-
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathatlas.go
127 lines (108 loc) · 4.45 KB
/
atlas.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package glitch
import (
"image"
"github.com/unitoftime/flow/glm"
)
// RBG: msdf-atlas-gen -type mtsdf -emrange 0.2 -dimensions 255 255 -font ~/Library/Fonts/FiraSans-Regular.otf -imageout assets/FiraSans-Regular.png -json assets/FiraSans-Regular.json
// ./msdf-atlas-gen/build/bin/msdf-atlas-gen -font ./Lato-Black.ttf -imageout atlas.png -json atlas.json -pots -size 32 -yorigin top -emrange 0.2 -type mtsdf
// MSDF
// ../msdf-atlas-gen/build/bin/msdf-atlas-gen -font ./Lato-Black.ttf -imageout atlas.png -json atlas.json -pots -size 32 -yorigin top -pxrange 10
// SDF
// ./msdf-atlas-gen/build/bin/msdf-atlas-gen -font ./Lato-Black.ttf -imageout atlas.png -json atlas.json -pots -size 32 -yorigin top -pxrange 10
// PlaneBounds: https://github.com/Chlumsky/msdf-atlas-gen/issues/2
type SdfAtlasPreamble struct {
Type string
DistanceRange float64
DistanceRangeMiddle int
Size int
Width int
Height int
YOrigin string
}
type SdfMetrics struct {
EmSize int
LineHeight float64
Ascender float64
Descender float64
UnderlineY float64
UnderlineThickness float64
}
type AtlasRect struct {
Left, Bottom, Right, Top float64
}
type GlyphData struct {
Unicode int
Advance float64
PlaneBounds AtlasRect
AtlasBounds AtlasRect
}
type SdfAtlas struct {
Atlas SdfAtlasPreamble
Metrics SdfMetrics
Glyphs []GlyphData
}
// Multiply by font size to get in pixels, then divide by texture size
func sdfUnitToFloat(sdfUnit float64, fontSize, texSize int) float64 {
return (sdfUnit * float64(fontSize)) / float64(texSize)
}
func AtlasFromSdf(sdf SdfAtlas, sdfImg image.Image, kerning float64) (*Atlas, error) {
texture := NewTexture(sdfImg, true) // TODO: Smoothing for sdf?
// height := sdfUnitToFloat(sdf.Metrics.LineHeight, sdf.Atlas.Size, sdf.Atlas.Width)
height := sdf.Metrics.LineHeight * float64(sdf.Atlas.Size)
ascent := sdf.Metrics.Ascender * float64(sdf.Atlas.Size)
descent := sdf.Metrics.Descender * float64(sdf.Atlas.Size)
// height := sdfUnitToFloat(sdf.Metrics.LineHeight, sdf.Atlas.Size, sdf.Atlas.Width)
// ascent := sdfUnitToFloat(-sdf.Metrics.Ascender, sdf.Atlas.Size, sdf.Atlas.Width)
// descent := sdfUnitToFloat(sdf.Metrics.Descender, sdf.Atlas.Size, sdf.Atlas.Width)
atlas := &Atlas{
mapping: make(map[rune]Glyph),
// ascent: floatToFixed(ascent),//floatToFixed(sdf.Metrics.Ascender),
// descent: floatToFixed(descent), //floatToFixed(sdf.Metrics.Descender),
// height: floatToFixed(height),
ascent: -ascent, //floatToFixed(sdf.Metrics.Ascender),
descent: descent, //floatToFixed(sdf.Metrics.Descender),
height: height,
// ascent: descent,
// descent: ascent,
// height: height,
texture: texture,
// pixelPerfect: true,
defaultKerning: kerning,
defaultMaterial: DefaultMsdfMaterial(texture),
}
for _, g := range sdf.Glyphs {
// pb := R(
// sdfUnitToFloat(g.PlaneBounds.Left, sdf.Atlas.Size, sdf.Atlas.Width),
// sdfUnitToFloat(g.PlaneBounds.Bottom, sdf.Atlas.Size, sdf.Atlas.Height),
// sdfUnitToFloat(g.PlaneBounds.Right, sdf.Atlas.Size, sdf.Atlas.Width),
// sdfUnitToFloat(g.PlaneBounds.Top, sdf.Atlas.Size, sdf.Atlas.Height),
// )
// ww := pb.W() * float64(sdf.Atlas.Width)
// if ww != g.AtlasBounds.Right - g.AtlasBounds.Left {
// fmt.Println("Failed:", rune(g.Unicode), ww, g.AtlasBounds.Right - g.AtlasBounds.Left)
// panic("aslkfdjsalfd")
// }
// bearingRect := image.Rect(
// int(g.PlaneBounds.Left),
// )
// bearingX := float64((bearingRect.Min.X * 1000000).Floor()) / (1000000 * fSize)
// bearingY := float64((-bearingRect.Max.Y * 1000000).Floor()) / (1000000 * fSize)
bearingX := sdfUnitToFloat(g.PlaneBounds.Left, sdf.Atlas.Size, sdf.Atlas.Width)
bearingY := sdfUnitToFloat(-g.PlaneBounds.Bottom, sdf.Atlas.Size, sdf.Atlas.Height)
// h := -g.PlaneBounds.Top + g.PlaneBounds.Bottom
// bearingY := sdfUnitToFloat(h - g.PlaneBounds.Bottom, sdf.Atlas.Size, sdf.Atlas.Height)
glyph := Glyph{
// Advance: (g.Advance * float64(sdf.Atlas.Size)) / float64(sdf.Atlas.Width),
Advance: sdfUnitToFloat(g.Advance, sdf.Atlas.Size, sdf.Atlas.Width),
Bearing: Vec2{bearingX, bearingY},
BoundsUV: glm.R(
g.AtlasBounds.Left/float64(sdf.Atlas.Width),
g.AtlasBounds.Top/float64(sdf.Atlas.Height),
g.AtlasBounds.Right/float64(sdf.Atlas.Width),
g.AtlasBounds.Bottom/float64(sdf.Atlas.Height),
).Norm(),
}
atlas.mapping[rune(g.Unicode)] = glyph
}
return atlas, nil
}