Skip to content

Commit 9932805

Browse files
authored
Merge pull request #1114 from googlefonts/more-predicates
[tokens] Support a few more glyph predicates
2 parents bb17c74 + a5b99ad commit 9932805

File tree

4 files changed

+347
-29
lines changed

4 files changed

+347
-29
lines changed

Lib/glyphsLib/builder/tokens.py

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,12 @@ def parse_glyph_predicate(self, token):
124124
"hasTrueTypeHints",
125125
"isAligned",
126126
"isAppleColorGlyph",
127-
"isColorGlyph",
127+
"isAnyColorGlyph",
128+
"isFullColorGlyph",
128129
"isCornerGlyph",
129130
"isHangulKeyGlyph",
130131
"isSVGColorGlyph",
132+
"isColorPaletteGlyph",
131133
"isSmartGlyph",
132134
"justLocked",
133135
"locked",
@@ -294,19 +296,13 @@ def _get_value_for_layer(self, layer, value):
294296
"Unknown glyph property '%s' at position %i" % (value, self.position)
295297
) from e
296298

297-
gsglyph_attr_getters = {
298-
"colorIndex": lambda g: g.color,
299-
"countOfUnicodes": lambda g: len(g.unicodes),
300-
"countOfLayers": lambda g: len(g.layers),
301-
}
302-
303299
def _get_value_for_glyph(self, g, value):
304-
getter = self.gsglyph_attr_getters.get(value, None)
305-
if getter:
306-
return getter(g)
307-
308300
try:
309-
return getattr(g, value)
301+
attrib = getattr(g, value)
302+
if callable(attrib):
303+
return attrib()
304+
else:
305+
return attrib
310306
except AttributeError as exc:
311307
raise ValueError(
312308
"Glyphs attribute %s used in predicate '%s'"

Lib/glyphsLib/classes.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4345,6 +4345,53 @@ def vertWidthMetricsKey(self):
43454345
def vertWidthMetricsKey(self, value):
43464346
self.metricVertWidth = value
43474347

4348+
# The following methods are their mainly to support there use in predicate
4349+
# tokens.
4350+
4351+
def colorIndex(self):
4352+
return self.color
4353+
4354+
def countOfUnicodes(self):
4355+
return len(self.unicodes)
4356+
4357+
def countOfLayers(self):
4358+
return len(self.layers)
4359+
4360+
def hasAnnotations(self):
4361+
return any(bool(layer.annotations) for layer in self.layers)
4362+
4363+
def hasComponents(self):
4364+
return any(bool(layer.components) for layer in self.layers)
4365+
4366+
def hasCorners(self):
4367+
return any(
4368+
any(hint.type.upper() == "CORNER" for hint in layer.hints)
4369+
for layer in self.layers
4370+
)
4371+
4372+
def hasSpecialLayers(self):
4373+
return any(bool(layer.attributes) for layer in self.layers)
4374+
4375+
def isAnyColorGlyph(self):
4376+
return (
4377+
self.isFullColorGlyph()
4378+
or self.isColorPaletteGlyph()
4379+
or self.isSVGColorGlyph()
4380+
or self.isAppleColorGlyph()
4381+
)
4382+
4383+
def isFullColorGlyph(self):
4384+
return any("color" in layer.attributes for layer in self.layers)
4385+
4386+
def isColorPaletteGlyph(self):
4387+
return any("colorPalette" in layer.attributes for layer in self.layers)
4388+
4389+
def isSVGColorGlyph(self):
4390+
return any("svg" in layer.attributes for layer in self.layers)
4391+
4392+
def isAppleColorGlyph(self):
4393+
return any("sbixSize" in layer.attributes for layer in self.layers)
4394+
43484395

43494396
GSGlyph._add_parsers(
43504397
[

tests/data/TokenTest.glyphs

Lines changed: 267 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
{
2-
.appVersion = "3225";
2+
.appVersion = "3436";
33
.formatVersion = 3;
4+
axes = (
5+
{
6+
name = Weight;
7+
tag = wght;
8+
}
9+
);
410
classes = (
511
{
612
code = "$[name endswith \".sc\"]";
@@ -27,6 +33,9 @@ tag = dist;
2733
);
2834
fontMaster = (
2935
{
36+
axesValues = (
37+
400
38+
);
3039
id = m01;
3140
metricValues = (
3241
{
@@ -55,6 +64,9 @@ numberValues = (
5564
);
5665
},
5766
{
67+
axesValues = (
68+
700
69+
);
5870
iconName = Bold;
5971
id = "11119B89-ADF6-486B-9172-E51437C3592A";
6072
metricValues = (
@@ -127,6 +139,225 @@ script = latin;
127139
unicode = 65;
128140
},
129141
{
142+
glyphname = C;
143+
lastChange = "2025-11-06 15:49:59 +0000";
144+
layers = (
145+
{
146+
layerId = m01;
147+
width = 600;
148+
},
149+
{
150+
layerId = "11119B89-ADF6-486B-9172-E51437C3592A";
151+
width = 600;
152+
},
153+
{
154+
associatedMasterId = m01;
155+
attr = {
156+
color = 1;
157+
};
158+
layerId = "475D76E4-D816-4569-B7B3-C1A3B15E838A";
159+
name = "6 Nov 25 at 17:36";
160+
shapes = (
161+
{
162+
ref = A;
163+
}
164+
);
165+
width = 600;
166+
}
167+
);
168+
script = latin;
169+
unicode = 67;
170+
},
171+
{
172+
glyphname = D;
173+
lastChange = "2025-11-06 15:37:07 +0000";
174+
layers = (
175+
{
176+
layerId = m01;
177+
width = 600;
178+
},
179+
{
180+
layerId = "11119B89-ADF6-486B-9172-E51437C3592A";
181+
width = 600;
182+
},
183+
{
184+
associatedMasterId = "11119B89-ADF6-486B-9172-E51437C3592A";
185+
attr = {
186+
colorPalette = 0;
187+
};
188+
layerId = "5B23FE24-A600-42DA-9CF8-BDACB2E0781E";
189+
name = "6 Nov 25 at 17:37";
190+
width = 600;
191+
}
192+
);
193+
unicode = 68;
194+
},
195+
{
196+
glyphname = E;
197+
lastChange = "2025-11-06 15:37:33 +0000";
198+
layers = (
199+
{
200+
layerId = m01;
201+
width = 600;
202+
},
203+
{
204+
layerId = "11119B89-ADF6-486B-9172-E51437C3592A";
205+
width = 600;
206+
},
207+
{
208+
associatedMasterId = m01;
209+
attr = {
210+
sbixSize = 128;
211+
};
212+
layerId = "7B946257-9F2E-4482-9E99-2575245FB482";
213+
name = "6 Nov 25 at 17:37";
214+
width = 600;
215+
}
216+
);
217+
unicode = 69;
218+
},
219+
{
220+
glyphname = F;
221+
lastChange = "2025-11-06 15:37:39 +0000";
222+
layers = (
223+
{
224+
layerId = m01;
225+
width = 600;
226+
},
227+
{
228+
layerId = "11119B89-ADF6-486B-9172-E51437C3592A";
229+
width = 600;
230+
},
231+
{
232+
associatedMasterId = m01;
233+
attr = {
234+
svg = 1;
235+
};
236+
layerId = "99565BA2-48F5-429D-8BC5-54F7C691D673";
237+
name = "6 Nov 25 at 17:37";
238+
width = 600;
239+
}
240+
);
241+
unicode = 70;
242+
},
243+
{
244+
glyphname = G;
245+
lastChange = "2025-11-06 15:47:03 +0000";
246+
layers = (
247+
{
248+
layerId = m01;
249+
width = 600;
250+
},
251+
{
252+
layerId = "11119B89-ADF6-486B-9172-E51437C3592A";
253+
width = 600;
254+
},
255+
{
256+
associatedMasterId = m01;
257+
attr = {
258+
coordinates = (
259+
500
260+
);
261+
};
262+
layerId = "F07FD996-C306-4284-9FEC-E6771183EC6F";
263+
name = "6 Nov 25 at 17:46";
264+
width = 600;
265+
}
266+
);
267+
unicode = 71;
268+
},
269+
{
270+
glyphname = H;
271+
lastChange = "2025-11-06 15:47:19 +0000";
272+
layers = (
273+
{
274+
layerId = m01;
275+
width = 600;
276+
},
277+
{
278+
layerId = "11119B89-ADF6-486B-9172-E51437C3592A";
279+
width = 600;
280+
},
281+
{
282+
associatedMasterId = m01;
283+
attr = {
284+
axisRules = (
285+
{
286+
max = 600;
287+
min = 500;
288+
}
289+
);
290+
};
291+
layerId = "8DABC084-BB3D-4052-A648-45B03317531A";
292+
name = "6 Nov 25 at 17:47";
293+
width = 600;
294+
}
295+
);
296+
unicode = 72;
297+
},
298+
{
299+
glyphname = I;
300+
lastChange = "2025-11-06 15:54:25 +0000";
301+
layers = (
302+
{
303+
annotations = (
304+
{
305+
pos = (453,788);
306+
text = Test;
307+
type = Text;
308+
}
309+
);
310+
hints = (
311+
{
312+
name = _corner.test;
313+
options = 1;
314+
origin = (0,2);
315+
scale = (-1,1);
316+
type = Corner;
317+
}
318+
);
319+
layerId = m01;
320+
shapes = (
321+
{
322+
closed = 1;
323+
nodes = (
324+
(384,0,l),
325+
(384,500,l),
326+
(255,500,l),
327+
(255,0,l)
328+
);
329+
}
330+
);
331+
width = 600;
332+
},
333+
{
334+
hints = (
335+
{
336+
name = _corner.test;
337+
options = 1;
338+
origin = (0,2);
339+
scale = (-1,1);
340+
type = Corner;
341+
}
342+
);
343+
layerId = "11119B89-ADF6-486B-9172-E51437C3592A";
344+
shapes = (
345+
{
346+
closed = 1;
347+
nodes = (
348+
(384,0,l),
349+
(384,500,l),
350+
(255,500,l),
351+
(255,0,l)
352+
);
353+
}
354+
);
355+
width = 600;
356+
}
357+
);
358+
unicode = 73;
359+
},
360+
{
130361
export = 0;
131362
glyphname = B;
132363
lastChange = "2023-11-20 21:52:14 +0000";
@@ -195,6 +426,41 @@ width = 600;
195426
);
196427
subCategory = Arrow;
197428
unicode = 346;
429+
},
430+
{
431+
export = 0;
432+
glyphname = _corner.test;
433+
lastChange = "2025-11-06 15:53:37 +0000";
434+
layers = (
435+
{
436+
layerId = m01;
437+
shapes = (
438+
{
439+
closed = 0;
440+
nodes = (
441+
(0,0,l),
442+
(200,181,l),
443+
(200,0,l)
444+
);
445+
}
446+
);
447+
width = 200;
448+
},
449+
{
450+
layerId = "11119B89-ADF6-486B-9172-E51437C3592A";
451+
shapes = (
452+
{
453+
closed = 0;
454+
nodes = (
455+
(200,0,l),
456+
(200,181,l),
457+
(0,0,l)
458+
);
459+
}
460+
);
461+
width = 200;
462+
}
463+
);
198464
}
199465
);
200466
metrics = (

0 commit comments

Comments
 (0)