1
2
3
4
5
6 package truetype
7
8 import (
9 "image"
10 "math"
11
12 "github.com/golang/freetype/raster"
13 "golang.org/x/image/font"
14 "golang.org/x/image/math/fixed"
15 )
16
17 func powerOf2(i int) bool {
18 return i != 0 && (i&(i-1)) == 0
19 }
20
21
22 type Options struct {
23
24
25
26 Size float64
27
28
29
30
31 DPI float64
32
33
34
35
36 Hinting font.Hinting
37
38
39
40
41
42
43
44 GlyphCacheEntries int
45
46
47
48
49
50
51
52
53
54
55
56 SubPixelsX int
57
58
59
60
61
62
63
64
65
66
67
68 SubPixelsY int
69 }
70
71 func (o *Options) size() float64 {
72 if o != nil && o.Size > 0 {
73 return o.Size
74 }
75 return 12
76 }
77
78 func (o *Options) dpi() float64 {
79 if o != nil && o.DPI > 0 {
80 return o.DPI
81 }
82 return 72
83 }
84
85 func (o *Options) hinting() font.Hinting {
86 if o != nil {
87 switch o.Hinting {
88 case font.HintingVertical, font.HintingFull:
89
90 return font.HintingFull
91 }
92 }
93 return font.HintingNone
94 }
95
96 func (o *Options) glyphCacheEntries() int {
97 if o != nil && powerOf2(o.GlyphCacheEntries) {
98 return o.GlyphCacheEntries
99 }
100
101
102 return 512
103 }
104
105 func (o *Options) subPixelsX() (value uint32, halfQuantum, mask fixed.Int26_6) {
106 if o != nil {
107 switch o.SubPixelsX {
108 case 1, 2, 4, 8, 16, 32, 64:
109 return subPixels(o.SubPixelsX)
110 }
111 }
112
113
114
115 return subPixels(4)
116 }
117
118 func (o *Options) subPixelsY() (value uint32, halfQuantum, mask fixed.Int26_6) {
119 if o != nil {
120 switch o.SubPixelsX {
121 case 1, 2, 4, 8, 16, 32, 64:
122 return subPixels(o.SubPixelsX)
123 }
124 }
125
126
127
128
129 return subPixels(1)
130 }
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151 func subPixels(q int) (value uint32, bias, mask fixed.Int26_6) {
152 return uint32(q), 32 / fixed.Int26_6(q), -64 / fixed.Int26_6(q)
153 }
154
155
156 type glyphCacheEntry struct {
157 key glyphCacheKey
158 val glyphCacheVal
159 }
160
161 type glyphCacheKey struct {
162 index Index
163 fx, fy uint8
164 }
165
166 type glyphCacheVal struct {
167 advanceWidth fixed.Int26_6
168 offset image.Point
169 gw int
170 gh int
171 }
172
173 type indexCacheEntry struct {
174 rune rune
175 index Index
176 }
177
178
179 func NewFace(f *Font, opts *Options) font.Face {
180 a := &face{
181 f: f,
182 hinting: opts.hinting(),
183 scale: fixed.Int26_6(0.5 + (opts.size() * opts.dpi() * 64 / 72)),
184 glyphCache: make([]glyphCacheEntry, opts.glyphCacheEntries()),
185 }
186 a.subPixelX, a.subPixelBiasX, a.subPixelMaskX = opts.subPixelsX()
187 a.subPixelY, a.subPixelBiasY, a.subPixelMaskY = opts.subPixelsY()
188
189
190
191 for i := range a.glyphCache {
192 a.glyphCache[i].key.fy = 0xff
193 }
194 for i := range a.indexCache {
195 a.indexCache[i].rune = -1
196 }
197
198
199 b := f.Bounds(a.scale)
200 xmin := +int(b.Min.X) >> 6
201 ymin := -int(b.Max.Y) >> 6
202 xmax := +int(b.Max.X+63) >> 6
203 ymax := -int(b.Min.Y-63) >> 6
204 a.maxw = xmax - xmin
205 a.maxh = ymax - ymin
206 a.masks = image.NewAlpha(image.Rect(0, 0, a.maxw, a.maxh*len(a.glyphCache)))
207 a.r.SetBounds(a.maxw, a.maxh)
208 a.p = facePainter{a}
209
210 return a
211 }
212
213 type face struct {
214 f *Font
215 hinting font.Hinting
216 scale fixed.Int26_6
217 subPixelX uint32
218 subPixelBiasX fixed.Int26_6
219 subPixelMaskX fixed.Int26_6
220 subPixelY uint32
221 subPixelBiasY fixed.Int26_6
222 subPixelMaskY fixed.Int26_6
223 masks *image.Alpha
224 glyphCache []glyphCacheEntry
225 r raster.Rasterizer
226 p raster.Painter
227 paintOffset int
228 maxw int
229 maxh int
230 glyphBuf GlyphBuf
231 indexCache [indexCacheLen]indexCacheEntry
232
233
234 }
235
236 const indexCacheLen = 256
237
238 func (a *face) index(r rune) Index {
239 const mask = indexCacheLen - 1
240 c := &a.indexCache[r&mask]
241 if c.rune == r {
242 return c.index
243 }
244 i := a.f.Index(r)
245 c.rune = r
246 c.index = i
247 return i
248 }
249
250
251 func (a *face) Close() error { return nil }
252
253
254 func (a *face) Metrics() font.Metrics {
255 scale := float64(a.scale)
256 fupe := float64(a.f.FUnitsPerEm())
257 return font.Metrics{
258 Height: a.scale,
259 Ascent: fixed.Int26_6(math.Ceil(scale * float64(+a.f.ascent) / fupe)),
260 Descent: fixed.Int26_6(math.Ceil(scale * float64(-a.f.descent) / fupe)),
261 }
262 }
263
264
265 func (a *face) Kern(r0, r1 rune) fixed.Int26_6 {
266 i0 := a.index(r0)
267 i1 := a.index(r1)
268 kern := a.f.Kern(a.scale, i0, i1)
269 if a.hinting != font.HintingNone {
270 kern = (kern + 32) &^ 63
271 }
272 return kern
273 }
274
275
276 func (a *face) Glyph(dot fixed.Point26_6, r rune) (
277 dr image.Rectangle, mask image.Image, maskp image.Point, advance fixed.Int26_6, ok bool) {
278
279
280 dotX := (dot.X + a.subPixelBiasX) & a.subPixelMaskX
281 dotY := (dot.Y + a.subPixelBiasY) & a.subPixelMaskY
282
283
284 ix, fx := int(dotX>>6), dotX&0x3f
285 iy, fy := int(dotY>>6), dotY&0x3f
286
287 index := a.index(r)
288 cIndex := uint32(index)
289 cIndex = cIndex*a.subPixelX - uint32(fx/a.subPixelMaskX)
290 cIndex = cIndex*a.subPixelY - uint32(fy/a.subPixelMaskY)
291 cIndex &= uint32(len(a.glyphCache) - 1)
292 a.paintOffset = a.maxh * int(cIndex)
293 k := glyphCacheKey{
294 index: index,
295 fx: uint8(fx),
296 fy: uint8(fy),
297 }
298 var v glyphCacheVal
299 if a.glyphCache[cIndex].key != k {
300 var ok bool
301 v, ok = a.rasterize(index, fx, fy)
302 if !ok {
303 return image.Rectangle{}, nil, image.Point{}, 0, false
304 }
305 a.glyphCache[cIndex] = glyphCacheEntry{k, v}
306 } else {
307 v = a.glyphCache[cIndex].val
308 }
309
310 dr.Min = image.Point{
311 X: ix + v.offset.X,
312 Y: iy + v.offset.Y,
313 }
314 dr.Max = image.Point{
315 X: dr.Min.X + v.gw,
316 Y: dr.Min.Y + v.gh,
317 }
318 return dr, a.masks, image.Point{Y: a.paintOffset}, v.advanceWidth, true
319 }
320
321 func (a *face) GlyphBounds(r rune) (bounds fixed.Rectangle26_6, advance fixed.Int26_6, ok bool) {
322 if err := a.glyphBuf.Load(a.f, a.scale, a.index(r), a.hinting); err != nil {
323 return fixed.Rectangle26_6{}, 0, false
324 }
325 xmin := +a.glyphBuf.Bounds.Min.X
326 ymin := -a.glyphBuf.Bounds.Max.Y
327 xmax := +a.glyphBuf.Bounds.Max.X
328 ymax := -a.glyphBuf.Bounds.Min.Y
329 if xmin > xmax || ymin > ymax {
330 return fixed.Rectangle26_6{}, 0, false
331 }
332 return fixed.Rectangle26_6{
333 Min: fixed.Point26_6{
334 X: xmin,
335 Y: ymin,
336 },
337 Max: fixed.Point26_6{
338 X: xmax,
339 Y: ymax,
340 },
341 }, a.glyphBuf.AdvanceWidth, true
342 }
343
344 func (a *face) GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool) {
345 if err := a.glyphBuf.Load(a.f, a.scale, a.index(r), a.hinting); err != nil {
346 return 0, false
347 }
348 return a.glyphBuf.AdvanceWidth, true
349 }
350
351
352
353
354
355 func (a *face) rasterize(index Index, fx, fy fixed.Int26_6) (v glyphCacheVal, ok bool) {
356 if err := a.glyphBuf.Load(a.f, a.scale, index, a.hinting); err != nil {
357 return glyphCacheVal{}, false
358 }
359
360 xmin := int(fx+a.glyphBuf.Bounds.Min.X) >> 6
361 ymin := int(fy-a.glyphBuf.Bounds.Max.Y) >> 6
362 xmax := int(fx+a.glyphBuf.Bounds.Max.X+0x3f) >> 6
363 ymax := int(fy-a.glyphBuf.Bounds.Min.Y+0x3f) >> 6
364 if xmin > xmax || ymin > ymax {
365 return glyphCacheVal{}, false
366 }
367
368
369
370
371
372 fx -= fixed.Int26_6(xmin << 6)
373 fy -= fixed.Int26_6(ymin << 6)
374
375 a.r.Clear()
376 pixOffset := a.paintOffset * a.maxw
377 clear(a.masks.Pix[pixOffset : pixOffset+a.maxw*a.maxh])
378 e0 := 0
379 for _, e1 := range a.glyphBuf.Ends {
380 a.drawContour(a.glyphBuf.Points[e0:e1], fx, fy)
381 e0 = e1
382 }
383 a.r.Rasterize(a.p)
384 return glyphCacheVal{
385 a.glyphBuf.AdvanceWidth,
386 image.Point{xmin, ymin},
387 xmax - xmin,
388 ymax - ymin,
389 }, true
390 }
391
392 func clear(pix []byte) {
393 for i := range pix {
394 pix[i] = 0
395 }
396 }
397
398
399 func (a *face) drawContour(ps []Point, dx, dy fixed.Int26_6) {
400 if len(ps) == 0 {
401 return
402 }
403
404
405
406
407
408
409
410
411
412
413
414 start := fixed.Point26_6{
415 X: dx + ps[0].X,
416 Y: dy - ps[0].Y,
417 }
418 var others []Point
419 if ps[0].Flags&0x01 != 0 {
420 others = ps[1:]
421 } else {
422 last := fixed.Point26_6{
423 X: dx + ps[len(ps)-1].X,
424 Y: dy - ps[len(ps)-1].Y,
425 }
426 if ps[len(ps)-1].Flags&0x01 != 0 {
427 start = last
428 others = ps[:len(ps)-1]
429 } else {
430 start = fixed.Point26_6{
431 X: (start.X + last.X) / 2,
432 Y: (start.Y + last.Y) / 2,
433 }
434 others = ps
435 }
436 }
437 a.r.Start(start)
438 q0, on0 := start, true
439 for _, p := range others {
440 q := fixed.Point26_6{
441 X: dx + p.X,
442 Y: dy - p.Y,
443 }
444 on := p.Flags&0x01 != 0
445 if on {
446 if on0 {
447 a.r.Add1(q)
448 } else {
449 a.r.Add2(q0, q)
450 }
451 } else {
452 if on0 {
453
454 } else {
455 mid := fixed.Point26_6{
456 X: (q0.X + q.X) / 2,
457 Y: (q0.Y + q.Y) / 2,
458 }
459 a.r.Add2(q0, mid)
460 }
461 }
462 q0, on0 = q, on
463 }
464
465 if on0 {
466 a.r.Add1(start)
467 } else {
468 a.r.Add2(q0, start)
469 }
470 }
471
472
473
474 type facePainter struct {
475 a *face
476 }
477
478 func (p facePainter) Paint(ss []raster.Span, done bool) {
479 m := p.a.masks
480 b := m.Bounds()
481 b.Min.Y = p.a.paintOffset
482 b.Max.Y = p.a.paintOffset + p.a.maxh
483 for _, s := range ss {
484 s.Y += p.a.paintOffset
485 if s.Y < b.Min.Y {
486 continue
487 }
488 if s.Y >= b.Max.Y {
489 return
490 }
491 if s.X0 < b.Min.X {
492 s.X0 = b.Min.X
493 }
494 if s.X1 > b.Max.X {
495 s.X1 = b.Max.X
496 }
497 if s.X0 >= s.X1 {
498 continue
499 }
500 base := (s.Y-m.Rect.Min.Y)*m.Stride - m.Rect.Min.X
501 p := m.Pix[base+s.X0 : base+s.X1]
502 color := uint8(s.Alpha >> 8)
503 for i := range p {
504 p[i] = color
505 }
506 }
507 }
508
View as plain text