-
Notifications
You must be signed in to change notification settings - Fork 0
/
scaled.go
102 lines (87 loc) · 2.15 KB
/
scaled.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package font
import (
"image"
"image/color"
"golang.org/x/image/font"
"golang.org/x/image/math/fixed"
)
type scaledImage struct {
image image.Image
scale int
}
func (s *scaledImage) ColorModel() color.Model {
return s.image.ColorModel()
}
func (s *scaledImage) Bounds() image.Rectangle {
b := s.image.Bounds()
b.Min = b.Min.Mul(s.scale)
b.Max = b.Max.Mul(s.scale)
return b
}
func euclidianDiv(x, y int) int {
if x < 0 {
x -= y - 1
}
return x / y
}
func (s *scaledImage) At(x, y int) color.Color {
x = euclidianDiv(x, s.scale)
y = euclidianDiv(y, s.scale)
return s.image.At(x, y)
}
func scaleFont(f font.Face, scale int) font.Face {
if scale == 1 {
return f
}
return &scaled{f, scale}
}
type scaled struct {
font font.Face
scale int
}
func (s *scaled) Close() error {
return s.font.Close()
}
func (s *scaled) Glyph(dot fixed.Point26_6, r rune) (dr image.Rectangle, mask image.Image, maskp image.Point, advance fixed.Int26_6, ok bool) {
dr, mask, maskp, advance, ok = s.font.Glyph(dot, r)
if !ok {
return
}
d := image.Pt(dot.X.Floor(), dot.Y.Floor())
dr.Min = dr.Min.Sub(d).Mul(s.scale).Add(d)
dr.Max = dr.Max.Sub(d).Mul(s.scale).Add(d)
maskp = maskp.Mul(s.scale)
advance *= fixed.Int26_6(s.scale)
return dr, &scaledImage{mask, s.scale}, maskp, advance, ok
}
func (s *scaled) GlyphBounds(r rune) (bounds fixed.Rectangle26_6, advance fixed.Int26_6, ok bool) {
bounds, advance, ok = s.font.GlyphBounds(r)
if !ok {
return
}
bounds.Min.X *= fixed.Int26_6(s.scale)
bounds.Min.Y *= fixed.Int26_6(s.scale)
bounds.Max.X *= fixed.Int26_6(s.scale)
bounds.Max.Y *= fixed.Int26_6(s.scale)
advance *= fixed.Int26_6(s.scale)
return
}
func (s *scaled) GlyphAdvance(r rune) (advance fixed.Int26_6, ok bool) {
advance, ok = s.font.GlyphAdvance(r)
if !ok {
return
}
advance *= fixed.Int26_6(s.scale)
return
}
func (s *scaled) Kern(r0, r1 rune) fixed.Int26_6 {
return s.font.Kern(r0, r1) * fixed.Int26_6(s.scale)
}
func (s *scaled) Metrics() font.Metrics {
m := s.font.Metrics()
return font.Metrics{
Height: m.Height * fixed.Int26_6(s.scale),
Ascent: m.Ascent * fixed.Int26_6(s.scale),
Descent: m.Descent * fixed.Int26_6(s.scale),
}
}