-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild_color_v1.py
98 lines (81 loc) · 2.85 KB
/
build_color_v1.py
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
import logging
import sys
from io import BytesIO
import uharfbuzz as hb
from fontTools import ttLib
from fontTools.colorLib import builder
from fontTools.ttLib.tables import otTables as ot
log = logging.getLogger(__name__)
with open(sys.argv[1], "rb") as f:
fontData = f.read()
font = ttLib.TTFont(BytesIO(fontData))
hbFont = hb.Font(hb.Face(fontData, 0))
colr0 = font["COLR"]
cpal = font["CPAL"]
cpal.numPaletteEntries = len(cpal.palettes[0])
colrv1_map = {}
clipBoxes = {}
def getGlyphBounds(font, glyphName):
gid = font.getGlyphID(glyphName)
assert gid is not None, glyphName
x, y, w, h = hbFont.get_glyph_extents(gid)
# convert from HB's x/y_bearing + extents to xMin, yMin, xMax, yMax
y += h
h = -h
w += x
h += y
# Since the shadow extends beyond width and height, increase them by a factor.
# Make the box slightly bigger by reducing xMin, yMin toog
return x - 50, y - 50, w * 1.5, h * 1.5
for glyph_name, layers in colr0.ColorLayers.items():
# Remove udatta and anudatta from color font. They skew the clibbox a lot
if glyph_name in ["uni952", "uni951"]:
continue
v1_layers = []
colrv1_map[glyph_name] = (ot.PaintFormat.PaintColrLayers, v1_layers)
for layer in layers:
# Match COLRv0 fill
if cpal.numPaletteEntries == 2:
v1_layers.append(
{
"Format": ot.PaintFormat.PaintGlyph,
"Paint": {
"Format": ot.PaintFormat.PaintSolid,
"PaletteIndex": layer.colorID,
"Alpha": 1,
},
"Glyph": layer.name,
}
)
else:
if layer.colorID == 0: # Shadow
c1 = 0
c2 = 2
if layer.colorID == 1: # Main
c1 = 2
c2 = 1
v1_layers.append(
{
"Format": ot.PaintFormat.PaintGlyph,
"Paint": {
"Format": ot.PaintFormat.PaintLinearGradient,
"ColorLine": {"ColorStop": [(0.0, c1), (1.0, c2)], "Extend": "reflect"},
"x0": 0,
"y0": 0,
"x1": 0,
"y1": 400,
"x2": 100,
"y2": 0,
},
"Glyph": layer.name,
}
)
if glyph_name not in clipBoxes:
clipBoxes[glyph_name] = getGlyphBounds(font, glyph_name)
# If there is only one layer, simplify
if len(v1_layers) == 1:
colrv1_map[glyph_name] = v1_layers[0]
# pprint.PrettyPrinter(indent=2).pprint(colrv1_map)
font["COLR"] = builder.buildCOLR(colrv1_map, clipBoxes=clipBoxes)
font.save(sys.argv[2])
log.info(f"Colrv1 saved at {sys.argv[2]}")