forked from fonttools/fontbakery
-
Notifications
You must be signed in to change notification settings - Fork 2
/
fvar.py
293 lines (256 loc) · 10.3 KB
/
fvar.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
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
from fontbakery.callable import check
from fontbakery.checkrunner import FAIL, PASS, WARN
from fontbakery.message import Message
# used to inform get_module_profile whether and how to create a profile
from fontbakery.fonts_profile import profile_factory # NOQA pylint: disable=unused-import
profile_imports = [
('.shared_conditions', ('is_variable_font'
, 'regular_wght_coord', 'regular_wdth_coord', 'regular_slnt_coord'
, 'regular_ital_coord', 'regular_opsz_coord', 'bold_wght_coord'))
]
@check(
id = 'com.google.fonts/check/varfont/regular_wght_coord',
rationale = """
According to the Open-Type spec's registered
design-variation tag 'wght' available at
https://docs.microsoft.com/en-gb/typography/opentype/spec/dvaraxistag_wght
If a variable font has a 'wght' (Weight) axis, then the coordinate
of its 'Regular' instance is required to be 400.
""",
conditions = ['is_variable_font',
'regular_wght_coord'],
misc_metadata = {
'request': 'https://github.com/googlefonts/fontbakery/issues/1707'
}
)
def com_google_fonts_check_varfont_regular_wght_coord(ttFont, regular_wght_coord):
"""The variable font 'wght' (Weight) axis coordinate must be 400 on the
'Regular' instance."""
if regular_wght_coord == 400:
yield PASS, "Regular:wght is 400."
else:
yield FAIL,\
Message("not-400",
f'The "wght" axis coordinate of'
f' the "Regular" instance must be 400.'
f' Got {regular_wght_coord} instead.')
@check(
id = 'com.google.fonts/check/varfont/regular_wdth_coord',
rationale = """
According to the Open-Type spec's registered
design-variation tag 'wdth' available at
https://docs.microsoft.com/en-gb/typography/opentype/spec/dvaraxistag_wdth
If a variable font has a 'wdth' (Width) axis, then the coordinate
of its 'Regular' instance is required to be 100.
""",
conditions = ['is_variable_font',
'regular_wdth_coord'],
misc_metadata = {
'request': 'https://github.com/googlefonts/fontbakery/issues/1707'
}
)
def com_google_fonts_check_varfont_regular_wdth_coord(ttFont, regular_wdth_coord):
"""The variable font 'wdth' (Width) axis coordinate must be 100 on the
'Regular' instance."""
if regular_wdth_coord == 100:
yield PASS, "Regular:wdth is 100."
else:
yield FAIL,\
Message("not-100",
f'The "wdth" coordinate of'
f' the "Regular" instance must be 100.'
f' Got {regular_wdth_coord} as a default value instead.')
@check(
id = 'com.google.fonts/check/varfont/regular_slnt_coord',
rationale = """
According to the Open-Type spec's registered
design-variation tag 'slnt' available at
https://docs.microsoft.com/en-gb/typography/opentype/spec/dvaraxistag_slnt
If a variable font has a 'slnt' (Slant) axis, then the coordinate
of its 'Regular' instance is required to be zero.
""",
conditions = ['is_variable_font',
'regular_slnt_coord'],
misc_metadata = {
'request': 'https://github.com/googlefonts/fontbakery/issues/1707'
}
)
def com_google_fonts_check_varfont_regular_slnt_coord(ttFont, regular_slnt_coord):
"""The variable font 'slnt' (Slant) axis coordinate must be zero on the
'Regular' instance."""
if regular_slnt_coord == 0:
yield PASS, "Regular:slnt is zero."
else:
yield FAIL,\
Message("non-zero",
f'The "slnt" coordinate of'
f' the "Regular" instance must be zero.'
f' Got {regular_slnt_coord} as a default value instead.')
@check(
id = 'com.google.fonts/check/varfont/regular_ital_coord',
rationale = """
According to the Open-Type spec's registered
design-variation tag 'ital' available at
https://docs.microsoft.com/en-gb/typography/opentype/spec/dvaraxistag_ital
If a variable font has a 'ital' (Italic) axis, then the coordinate
of its 'Regular' instance is required to be zero.
""",
conditions = ['is_variable_font',
'regular_ital_coord'],
misc_metadata = {
'request': 'https://github.com/googlefonts/fontbakery/issues/1707'
}
)
def com_google_fonts_check_varfont_regular_ital_coord(ttFont, regular_ital_coord):
"""The variable font 'ital' (Italic) axis coordinate must be zero on the
'Regular' instance."""
if regular_ital_coord == 0:
yield PASS, "Regular:ital is zero."
else:
yield FAIL,\
Message("non-zero",
f'The "ital" coordinate of'
f' the "Regular" instance must be zero.'
f' Got {regular_ital_coord} as a default value instead.')
@check(
id = 'com.google.fonts/check/varfont/regular_opsz_coord',
rationale = """
According to the Open-Type spec's registered
design-variation tag 'opsz' available at
https://docs.microsoft.com/en-gb/typography/opentype/spec/dvaraxistag_opsz
If a variable font has a 'opsz' (Optical Size) axis, then the coordinate
of its 'Regular' instance is recommended to be a value in the range 9 to 13.
""",
conditions = ['is_variable_font',
'regular_opsz_coord'],
misc_metadata = {
'request': 'https://github.com/googlefonts/fontbakery/issues/1707'
}
)
def com_google_fonts_check_varfont_regular_opsz_coord(ttFont, regular_opsz_coord):
"""The variable font 'opsz' (Optical Size) axis coordinate should be between
9 and 13 on the 'Regular' instance."""
if regular_opsz_coord >= 9 and regular_opsz_coord <= 13:
yield PASS, ("Regular:opsz coordinate ({regular_opsz_coord}) looks good.")
else:
yield WARN,\
Message("out-of-range",
f'The "opsz" (Optical Size) coordinate'
f' on the "Regular" instance is recommended'
f' to be a value in the range 9 to 13.'
f' Got {regular_opsz_coord} instead.')
@check(
id = 'com.google.fonts/check/varfont/bold_wght_coord',
rationale = """
The Open-Type spec's registered
design-variation tag 'wght' available at
https://docs.microsoft.com/en-gb/typography/opentype/spec/dvaraxistag_wght
does not specify a required value for the 'Bold' instance of a variable font.
But Dave Crossland suggested that we should enforce a
required value of 700 in this case.
""",
conditions = ['is_variable_font',
'bold_wght_coord'],
misc_metadata = {
'request': 'https://github.com/googlefonts/fontbakery/issues/1707'
}
)
def com_google_fonts_check_varfont_bold_wght_coord(ttFont, bold_wght_coord):
"""The variable font 'wght' (Weight) axis coordinate must be 700 on the
'Bold' instance."""
if bold_wght_coord == 700:
yield PASS, "Bold:wght is 700."
else:
yield FAIL,\
Message("not-700",
f'The "wght" axis coordinate of'
f' the "Bold" instance must be 700.'
f' Got {bold_wght_coord} instead.')
@check(
id = 'com.google.fonts/check/wght_valid_range',
rationale = """
According to the Open-Type spec's registered
design-variation tag 'wght' available at
https://docs.microsoft.com/en-gb/typography/opentype/spec/dvaraxistag_wght
On the 'wght' (Weight) axis, the valid coordinate range is 1-1000.
""",
conditions = ['is_variable_font'],
misc_metadata = {
'request': 'https://github.com/googlefonts/fontbakery/issues/2264'
}
)
def com_google_fonts_check_wght_valid_range(ttFont):
"""The variable font 'wght' (Weight) axis coordinate
must be within spec range of 1 to 1000 on all instances."""
Failed = False
for instance in ttFont['fvar'].instances:
if 'wght' in instance.coordinates:
value = instance.coordinates['wght']
if value < 1 or value > 1000:
Failed = True
yield FAIL,\
Message("out-of-range",
f'Found a bad "wght" coordinate with value {value}'
f' outside of the valid range from 1 to 1000.')
break
if not Failed:
yield PASS, ("OK")
@check(
id = 'com.google.fonts/check/wdth_valid_range',
rationale = """
According to the Open-Type spec's registered
design-variation tag 'wdth' available at
https://docs.microsoft.com/en-gb/typography/opentype/spec/dvaraxistag_wdth
On the 'wdth' (Width) axis, the valid coordinate range is 1-1000
""",
conditions = ['is_variable_font'],
misc_metadata = {
}
)
def com_google_fonts_check_wdth_valid_range(ttFont):
"""The variable font 'wdth' (Weight) axis coordinate
must be within spec range of 1 to 1000 on all instances."""
Failed = False
for instance in ttFont['fvar'].instances:
if 'wdth' in instance.coordinates:
value = instance.coordinates['wdth']
if value < 1 or value > 1000:
Failed = True
yield FAIL,\
Message("out-of-range",
f'Found a bad "wdth" coordinate with value {value}'
f' outside of the valid range from 1 to 1000.')
break
if not Failed:
yield PASS, ("OK")
@check(
id = 'com.google.fonts/check/varfont/slnt_range',
rationale = """
The OpenType spec says at
https://docs.microsoft.com/en-us/typography/opentype/spec/dvaraxistag_slnt that:
[...] the scale for the Slant axis is interpreted as the angle of slant in
counter-clockwise degrees from upright. This means that a typical, right-leaning
oblique design will have a negative slant value. This matches the scale used for
the italicAngle field in the post table.
""",
conditions = ['is_variable_font',
'slnt_axis'],
misc_metadata = {
'request': 'https://github.com/googlefonts/fontbakery/issues/2572'
}
)
def com_google_fonts_check_varfont_slnt_range(ttFont, slnt_axis):
""" The variable font 'slnt' (Slant) axis coordinate
specifies positive values in its range? """
if slnt_axis.minValue < 0 and slnt_axis.maxValue >= 0:
yield PASS, "Looks good!"
else:
yield WARN,\
Message("unusual-range",
f'The range of values for the "slnt" axis in'
f' this font only allows positive coordinates'
f' (from {slnt_axis.minValue} to {slnt_axis.maxValue}),'
f' indicating that this may be a back slanted design,'
f' which is rare. If that\'s not the case, then'
f' the "slant" axis should be a range of'
f' negative values instead.')