@@ -38,7 +38,10 @@ type Face interface {
38
38
// glyph at the sub-pixel destination location dot, and that glyph's
39
39
// advance width.
40
40
//
41
- // It returns !ok if the face does not contain a glyph for r.
41
+ // It returns !ok if the face does not contain a glyph for r. This includes
42
+ // returning !ok for a fallback glyph (such as substituting a U+FFFD glyph
43
+ // or OpenType's .notdef glyph), in which case the other return values may
44
+ // still be non-zero.
42
45
//
43
46
// The contents of the mask image returned by one Glyph call may change
44
47
// after the next Glyph call. Callers that want to cache the mask must make
@@ -49,7 +52,10 @@ type Face interface {
49
52
// GlyphBounds returns the bounding box of r's glyph, drawn at a dot equal
50
53
// to the origin, and that glyph's advance width.
51
54
//
52
- // It returns !ok if the face does not contain a glyph for r.
55
+ // It returns !ok if the face does not contain a glyph for r. This includes
56
+ // returning !ok for a fallback glyph (such as substituting a U+FFFD glyph
57
+ // or OpenType's .notdef glyph), in which case the other return values may
58
+ // still be non-zero.
53
59
//
54
60
// The glyph's ascent and descent are equal to -bounds.Min.Y and
55
61
// +bounds.Max.Y. The glyph's left-side and right-side bearings are equal
@@ -60,7 +66,10 @@ type Face interface {
60
66
61
67
// GlyphAdvance returns the advance width of r's glyph.
62
68
//
63
- // It returns !ok if the face does not contain a glyph for r.
69
+ // It returns !ok if the face does not contain a glyph for r. This includes
70
+ // returning !ok for a fallback glyph (such as substituting a U+FFFD glyph
71
+ // or OpenType's .notdef glyph), in which case the other return values may
72
+ // still be non-zero.
64
73
GlyphAdvance (r rune ) (advance fixed.Int26_6 , ok bool )
65
74
66
75
// Kern returns the horizontal adjustment for the kerning pair (r0, r1). A
@@ -150,14 +159,10 @@ func (d *Drawer) DrawBytes(s []byte) {
150
159
if prevC >= 0 {
151
160
d .Dot .X += d .Face .Kern (prevC , c )
152
161
}
153
- dr , mask , maskp , advance , ok := d .Face .Glyph (d .Dot , c )
154
- if ! ok {
155
- // TODO: is falling back on the U+FFFD glyph the responsibility of
156
- // the Drawer or the Face?
157
- // TODO: set prevC = '\ufffd'?
158
- continue
162
+ dr , mask , maskp , advance , _ := d .Face .Glyph (d .Dot , c )
163
+ if ! dr .Empty () {
164
+ draw .DrawMask (d .Dst , dr , d .Src , image.Point {}, mask , maskp , draw .Over )
159
165
}
160
- draw .DrawMask (d .Dst , dr , d .Src , image.Point {}, mask , maskp , draw .Over )
161
166
d .Dot .X += advance
162
167
prevC = c
163
168
}
@@ -170,14 +175,10 @@ func (d *Drawer) DrawString(s string) {
170
175
if prevC >= 0 {
171
176
d .Dot .X += d .Face .Kern (prevC , c )
172
177
}
173
- dr , mask , maskp , advance , ok := d .Face .Glyph (d .Dot , c )
174
- if ! ok {
175
- // TODO: is falling back on the U+FFFD glyph the responsibility of
176
- // the Drawer or the Face?
177
- // TODO: set prevC = '\ufffd'?
178
- continue
178
+ dr , mask , maskp , advance , _ := d .Face .Glyph (d .Dot , c )
179
+ if ! dr .Empty () {
180
+ draw .DrawMask (d .Dst , dr , d .Src , image.Point {}, mask , maskp , draw .Over )
179
181
}
180
- draw .DrawMask (d .Dst , dr , d .Src , image.Point {}, mask , maskp , draw .Over )
181
182
d .Dot .X += advance
182
183
prevC = c
183
184
}
@@ -227,16 +228,12 @@ func BoundBytes(f Face, s []byte) (bounds fixed.Rectangle26_6, advance fixed.Int
227
228
if prevC >= 0 {
228
229
advance += f .Kern (prevC , c )
229
230
}
230
- b , a , ok := f .GlyphBounds (c )
231
- if ! ok {
232
- // TODO: is falling back on the U+FFFD glyph the responsibility of
233
- // the Drawer or the Face?
234
- // TODO: set prevC = '\ufffd'?
235
- continue
231
+ b , a , _ := f .GlyphBounds (c )
232
+ if ! b .Empty () {
233
+ b .Min .X += advance
234
+ b .Max .X += advance
235
+ bounds = bounds .Union (b )
236
236
}
237
- b .Min .X += advance
238
- b .Max .X += advance
239
- bounds = bounds .Union (b )
240
237
advance += a
241
238
prevC = c
242
239
}
@@ -251,16 +248,12 @@ func BoundString(f Face, s string) (bounds fixed.Rectangle26_6, advance fixed.In
251
248
if prevC >= 0 {
252
249
advance += f .Kern (prevC , c )
253
250
}
254
- b , a , ok := f .GlyphBounds (c )
255
- if ! ok {
256
- // TODO: is falling back on the U+FFFD glyph the responsibility of
257
- // the Drawer or the Face?
258
- // TODO: set prevC = '\ufffd'?
259
- continue
251
+ b , a , _ := f .GlyphBounds (c )
252
+ if ! b .Empty () {
253
+ b .Min .X += advance
254
+ b .Max .X += advance
255
+ bounds = bounds .Union (b )
260
256
}
261
- b .Min .X += advance
262
- b .Max .X += advance
263
- bounds = bounds .Union (b )
264
257
advance += a
265
258
prevC = c
266
259
}
@@ -278,13 +271,7 @@ func MeasureBytes(f Face, s []byte) (advance fixed.Int26_6) {
278
271
if prevC >= 0 {
279
272
advance += f .Kern (prevC , c )
280
273
}
281
- a , ok := f .GlyphAdvance (c )
282
- if ! ok {
283
- // TODO: is falling back on the U+FFFD glyph the responsibility of
284
- // the Drawer or the Face?
285
- // TODO: set prevC = '\ufffd'?
286
- continue
287
- }
274
+ a , _ := f .GlyphAdvance (c )
288
275
advance += a
289
276
prevC = c
290
277
}
@@ -298,13 +285,7 @@ func MeasureString(f Face, s string) (advance fixed.Int26_6) {
298
285
if prevC >= 0 {
299
286
advance += f .Kern (prevC , c )
300
287
}
301
- a , ok := f .GlyphAdvance (c )
302
- if ! ok {
303
- // TODO: is falling back on the U+FFFD glyph the responsibility of
304
- // the Drawer or the Face?
305
- // TODO: set prevC = '\ufffd'?
306
- continue
307
- }
288
+ a , _ := f .GlyphAdvance (c )
308
289
advance += a
309
290
prevC = c
310
291
}
0 commit comments