Skip to content

Commit cedaacd

Browse files
No width linking of brace layers (#985)
* Add test * No width linking of brace layers it was getting it form the master they are attached too and that is supposed to have a different width * Fix lint --------- Co-authored-by: Jany Belluz <[email protected]>
1 parent 5946df8 commit cedaacd

File tree

3 files changed

+299
-17
lines changed

3 files changed

+299
-17
lines changed

Lib/glyphsLib/builder/glyph.py

+14-16
Original file line numberDiff line numberDiff line change
@@ -250,22 +250,20 @@ def effective_width(layer, glyph):
250250
# The width may be taken from another master via the customParameters
251251
# 'Link Metrics With Master' or 'Link Metrics With First Master'.
252252
font = glyph.parent
253-
master = font.masters[layer.associatedMasterId or layer.layerId]
254-
metrics_source = master.metricsSource
255-
if metrics_source is None:
256-
width = layer.width
257-
else:
258-
metric_layer = font.glyphs[glyph.name].layers[metrics_source.id]
259-
if metric_layer:
260-
width = metric_layer.width
261-
if layer.width != width:
262-
logger.debug(
263-
f"{layer.parent.name}: Applying width from master "
264-
f"'{metrics_source.id}': {layer.width} -> {width}"
265-
)
266-
else:
267-
width = None
268-
return width
253+
master = font.masters[layer.layerId]
254+
if master:
255+
metrics_source = master.metricsSource
256+
if metrics_source:
257+
metric_layer = font.glyphs[glyph.name].layers[metrics_source.id]
258+
if metric_layer:
259+
width = metric_layer.width
260+
if layer.width != width:
261+
logger.debug(
262+
f"{layer.parent.name}: Applying width from master "
263+
f"'{metrics_source.id}': {layer.width} -> {width}"
264+
)
265+
return width
266+
return layer.width
269267

270268

271269
def to_ufo_glyph_color(self, ufo_glyph, layer, glyph, do_color_layers=True):
+241
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
{
2+
.appVersion = "3259";
3+
.formatVersion = 3;
4+
DisplayStrings = (
5+
a
6+
);
7+
axes = (
8+
{
9+
name = Weight;
10+
tag = wght;
11+
},
12+
{
13+
name = ROUND;
14+
tag = ROND;
15+
}
16+
);
17+
date = "2024-04-22 16:44:09 +0000";
18+
familyName = "New Font";
19+
fontMaster = (
20+
{
21+
axesValues = (
22+
400,
23+
0
24+
);
25+
id = "m-400-0";
26+
metricValues = (
27+
{
28+
over = 16;
29+
pos = 800;
30+
},
31+
{
32+
over = -16;
33+
},
34+
{
35+
over = -16;
36+
pos = -200;
37+
},
38+
{
39+
over = 16;
40+
pos = 700;
41+
},
42+
{
43+
over = 16;
44+
pos = 500;
45+
},
46+
{
47+
}
48+
);
49+
name = Regular;
50+
},
51+
{
52+
axesValues = (
53+
700,
54+
0
55+
);
56+
iconName = SemiBold;
57+
id = "m-700-0";
58+
metricValues = (
59+
{
60+
over = 16;
61+
pos = 800;
62+
},
63+
{
64+
over = -16;
65+
},
66+
{
67+
over = -16;
68+
pos = -200;
69+
},
70+
{
71+
over = 16;
72+
pos = 700;
73+
},
74+
{
75+
over = 16;
76+
pos = 500;
77+
},
78+
{
79+
}
80+
);
81+
name = Bold;
82+
},
83+
{
84+
axesValues = (
85+
400,
86+
1
87+
);
88+
customParameters = (
89+
{
90+
name = "Link Metrics With Master";
91+
value = "m-400-0";
92+
}
93+
);
94+
id = "m-400-1";
95+
metricValues = (
96+
{
97+
over = 16;
98+
pos = 800;
99+
},
100+
{
101+
over = -16;
102+
},
103+
{
104+
over = -16;
105+
pos = -200;
106+
},
107+
{
108+
over = 16;
109+
pos = 700;
110+
},
111+
{
112+
over = 16;
113+
pos = 500;
114+
},
115+
{
116+
}
117+
);
118+
name = "Regular ROUND";
119+
},
120+
{
121+
axesValues = (
122+
700,
123+
1
124+
);
125+
customParameters = (
126+
{
127+
name = "Link Metrics With Master";
128+
value = "m-700-0";
129+
}
130+
);
131+
iconName = SemiBold;
132+
id = "m-700-1";
133+
metricValues = (
134+
{
135+
over = 16;
136+
pos = 800;
137+
},
138+
{
139+
over = -16;
140+
},
141+
{
142+
over = -16;
143+
pos = -200;
144+
},
145+
{
146+
over = 16;
147+
pos = 700;
148+
},
149+
{
150+
over = 16;
151+
pos = 500;
152+
},
153+
{
154+
}
155+
);
156+
name = "Bold ROUND";
157+
}
158+
);
159+
glyphs = (
160+
{
161+
glyphname = a;
162+
lastChange = "2024-04-23 07:38:25 +0000";
163+
layers = (
164+
{
165+
layerId = "m-400-1";
166+
width = 100;
167+
},
168+
{
169+
layerId = "m-400-0";
170+
width = 100;
171+
},
172+
{
173+
layerId = "m-700-1";
174+
width = 300;
175+
},
176+
{
177+
associatedMasterId = "m-400-0";
178+
attr = {
179+
coordinates = (
180+
500,
181+
0
182+
);
183+
};
184+
layerId = "m-500-0";
185+
name = "Intermediate 500 0";
186+
width = 200;
187+
},
188+
{
189+
layerId = "m-700-0";
190+
width = 300;
191+
},
192+
{
193+
associatedMasterId = "m-400-1";
194+
attr = {
195+
coordinates = (
196+
500,
197+
1
198+
);
199+
};
200+
layerId = "m-500-1";
201+
name = "Intermediate 500 1";
202+
width = 200;
203+
}
204+
);
205+
unicode = 97;
206+
},
207+
{
208+
glyphname = space;
209+
layers = (
210+
{
211+
layerId = "m-400-1";
212+
width = 200;
213+
}
214+
);
215+
unicode = 32;
216+
}
217+
);
218+
metrics = (
219+
{
220+
type = ascender;
221+
},
222+
{
223+
type = baseline;
224+
},
225+
{
226+
type = descender;
227+
},
228+
{
229+
type = "cap height";
230+
},
231+
{
232+
type = "x-height";
233+
},
234+
{
235+
type = "italic angle";
236+
}
237+
);
238+
unitsPerEm = 1000;
239+
versionMajor = 1;
240+
versionMinor = 0;
241+
}

tests/special_layer_width_test.py

+44-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import os
1818

19-
from glyphsLib import load_to_ufos
19+
from glyphsLib import load_to_ufos, GSFont, to_designspace
2020

2121

2222
def glyphs_file_path():
@@ -42,3 +42,46 @@ def test_substitution_layer_width():
4242
assert masters[1]["B"].width == 600
4343
assert masters[0]["B.BRACKET.varAlt01"].width == 510
4444
assert masters[1]["B.BRACKET.varAlt01"].width == 610
45+
46+
47+
def test_intermediate_layer_width_with_metrics_source_on_parent():
48+
"""This checks that "intermediate layers", a.k.a. "brace layers", do not
49+
incorrectly inherit an irrelevant width from their parent layer.
50+
51+
Scenario in the test file:
52+
53+
- Glyph /a
54+
- Regular (400, 0): advance width = 100
55+
- Intermediate layer {500, 0}: advance width = 200
56+
- Bold (700, 0): advance width = 300
57+
- Regular ROUND (400, 1); advance width = 100
58+
* This master layer has a "metricsSource" pointing to Regular (400, 0)
59+
to ensure the widths are consistent.
60+
- Intermediate layer {500, 1}: advance width = 200
61+
* This intermediate layer is under consideration for the test.
62+
- Bold ROUND (700, 1): advance width = 300
63+
64+
Previously, the advance width of the intermediate layer `{500, 1}` would be
65+
forcibly taken from the `metricsSource` of the master layer `Regular ROUND
66+
(400, 1)` to which the intermediate layer `{500, 1}` was attached, and so it
67+
would get 100 instead of 200.
68+
69+
With this patch, the advance width of the layer `{500, 1}` will not be
70+
changed, because the the layer `{500, 1}` does not define itself a
71+
`metricsSource`.
72+
73+
See https://github.com/googlefonts/glyphsLib/pull/985
74+
"""
75+
test_path = os.path.join(
76+
os.path.dirname(__file__), "data", "IntermediateLayerWidth.glyphs"
77+
)
78+
font = GSFont(test_path)
79+
doc = to_designspace(font)
80+
for intermediate_round in doc.sources:
81+
if intermediate_round.getFullDesignLocation(doc) == {"Weight": 500, "ROUND": 1}:
82+
break
83+
else:
84+
raise AssertionError("Can't find intermediate layer in the desigspace")
85+
assert (
86+
intermediate_round.font.layers[intermediate_round.layerName]["a"].width == 200
87+
)

0 commit comments

Comments
 (0)