Skip to content

Commit 1492cc2

Browse files
committed
Store layerId and originalLayerName when necessary
1 parent d763522 commit 1492cc2

1 file changed

Lines changed: 99 additions & 26 deletions

File tree

Lib/glyphsLib/builder/layers.py

Lines changed: 99 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -12,62 +12,113 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15+
import re
16+
1517
from .constants import GLYPHS_PREFIX
1618

1719
LAYER_ID_KEY = GLYPHS_PREFIX + "layerId"
1820
LAYER_ORDER_PREFIX = GLYPHS_PREFIX + "layerOrderInGlyph."
1921
LAYER_ORDER_TEMP_USER_DATA_KEY = "__layerOrder"
22+
LAYER_ORIGINAL_NAME_KEY = GLYPHS_PREFIX + "layerOriginalName"
23+
FOREGROUND_LAYER_ID_KEY = GLYPHS_PREFIX + "foregroundLayerId"
2024

2125

2226
def to_ufo_layer(self, glyph, layer):
27+
layer_names_ids = {
28+
(l.name, l.layerId)
29+
for g in self.font.glyphs
30+
for l in glyph.layers
31+
if (l.associatedMasterId == layer.associatedMasterId)
32+
}
33+
layers_with_name = [name for name, _ in layer_names_ids if name == layer.name]
34+
glyphs_layers = self.font.glyphs[glyph.name].layers
2335
ufo_font = self._sources[layer.associatedMasterId or layer.layerId].font
36+
2437
if layer.associatedMasterId == layer.layerId:
2538
ufo_layer = ufo_font.layers.defaultLayer
2639
elif layer.name not in ufo_font.layers:
2740
ufo_layer = ufo_font.newLayer(layer.name)
28-
elif layer.name in ufo_font.layers and glyph.name in ufo_font.layers[layer.name]:
29-
self.logger.warning(
30-
f"{ufo_font.info.familyName} {ufo_font.info.styleName}: "
31-
f"Glyph {glyph.name}, layer {layer.name}: Duplicate glyph layer name",
41+
elif len(layers_with_name) > 1:
42+
# If there's already a layer with the same layerId, use it.
43+
# Otherwise make up a new layer with a new name.
44+
layer_name = next(
45+
(
46+
l.name
47+
for l in ufo_font.layers
48+
if l.lib.get(LAYER_ID_KEY) == layer.layerId
49+
),
50+
None,
3251
)
33-
n = 1
34-
new_layer_name = layer.name
35-
while new_layer_name in ufo_font.layers:
36-
new_layer_name = f"{layer.name} #{n!r}"
37-
n += 1
38-
ufo_layer = ufo_font.newLayer(new_layer_name)
52+
if layer_name is not None:
53+
ufo_layer = ufo_font.layers[layer_name]
54+
else:
55+
self.logger.warning(
56+
f"{ufo_font.info.familyName} {ufo_font.info.styleName}: "
57+
f"Glyph {glyph.name}, layer {layer.name}: Duplicate glyph layer name",
58+
)
59+
n = 1
60+
new_layer_name = layer.name
61+
while new_layer_name in ufo_font.layers:
62+
new_layer_name = f"{layer.name} #{n!r}"
63+
n += 1
64+
ufo_layer = ufo_font.newLayer(new_layer_name)
65+
ufo_layer.lib[LAYER_ORIGINAL_NAME_KEY] = layer.name
3966
else:
4067
ufo_layer = ufo_font.layers[layer.name]
41-
if self.minimize_glyphs_diffs:
68+
69+
# Store layerId when other layers have the same name or when minimizing
70+
# Glyphs diffs.
71+
if len(layers_with_name) > 1 or self.minimize_glyphs_diffs:
4272
ufo_layer.lib[LAYER_ID_KEY] = layer.layerId
73+
74+
# Store the layer order when color layers are present or when minimizing
75+
# Glyphs diffs.
76+
if (
77+
any([re.match(r"^Color \d+$", l.name) for l in glyphs_layers])
78+
or self.minimize_glyphs_diffs
79+
):
4380
ufo_layer.lib[LAYER_ORDER_PREFIX + glyph.name] = _layer_order_in_glyph(
4481
self, layer
4582
)
4683
return ufo_layer
4784

4885

4986
def to_ufo_background_layer(self, glyph, layer):
87+
layer_names_ids = {
88+
(l.name, l.layerId)
89+
for glyph in self.font.glyphs
90+
for l in glyph.layers
91+
if (l.associatedMasterId == layer.associatedMasterId)
92+
}
5093
ufo_font = self._sources[layer.associatedMasterId or layer.layerId].font
5194
if layer.associatedMasterId == layer.layerId:
5295
layer_name = "public.background"
5396
else:
5497
layer_name = f"{layer.name}.background"
5598

99+
layers_with_name = [name for name, _ in layer_names_ids if name == layer.name]
100+
if len(layers_with_name) > 1:
101+
# Find foreground layer and use the same name as a base for the
102+
# background layer name.
103+
foreground_name = next(
104+
(
105+
l.name
106+
for l in ufo_font.layers
107+
if l.lib.get(LAYER_ID_KEY) == layer.layerId
108+
),
109+
None,
110+
)
111+
assert foreground_name is not None
112+
layer_name = f"{foreground_name}.background"
113+
56114
if layer_name not in ufo_font.layers:
57115
background_layer = ufo_font.newLayer(layer_name)
58-
elif layer_name in ufo_font.layers and glyph.name in ufo_font.layers[layer_name]:
59-
self.logger.warning(
60-
f"{ufo_font.info.familyName} {ufo_font.info.styleName}: "
61-
f"Glyph {glyph.name}, layer {layer_name}: Duplicate glyph layer name",
62-
)
63-
n = 1
64-
new_layer_name = layer_name
65-
while new_layer_name in ufo_font.layers:
66-
new_layer_name = f"{layer.name} #{n!r}.background"
67-
n += 1
68-
background_layer = ufo_font.newLayer(new_layer_name)
69116
else:
70117
background_layer = ufo_font.layers[layer_name]
118+
119+
# Store foreground layerId when other foreground layers have the same name.
120+
if len(layers_with_name) > 1:
121+
background_layer.lib[FOREGROUND_LAYER_ID_KEY] = layer.layerId
71122
return background_layer
72123

73124

@@ -87,13 +138,32 @@ def to_glyphs_layer(self, ufo_layer, glyph, master):
87138
layer = master_layer.background
88139
elif ufo_layer.name.endswith(".background"):
89140
# Find or create the foreground layer
90-
# TODO: (jany) add lib attribute to find foreground by layer id
91-
foreground_name = ufo_layer.name[: -len(".background")]
141+
if FOREGROUND_LAYER_ID_KEY in ufo_layer.lib:
142+
foreground_layerId = ufo_layer.lib[FOREGROUND_LAYER_ID_KEY]
143+
foreground_layer = next(
144+
(
145+
l
146+
for l in self._sources[master.id].font.layers
147+
if (l.lib.get(LAYER_ID_KEY) == foreground_layerId)
148+
),
149+
None,
150+
)
151+
assert foreground_layer is not None
152+
foreground_name = foreground_layer.lib.get(LAYER_ORIGINAL_NAME_KEY)
153+
else:
154+
foreground_layerId = None
155+
foreground_name = None
156+
157+
if foreground_name is None:
158+
foreground_name = ufo_layer.name[: -len(".background")]
159+
92160
foreground = next(
93161
(
94162
l
95163
for l in glyph.layers
96-
if l.name == foreground_name and l.associatedMasterId == master.id
164+
if (foreground_layerId is None or foreground_layerId == l.layerId)
165+
and l.name == foreground_name
166+
and l.associatedMasterId == master.id
97167
),
98168
None,
99169
)
@@ -117,7 +187,10 @@ def to_glyphs_layer(self, ufo_layer, glyph, master):
117187
layer.associatedMasterId = master.id
118188
if LAYER_ID_KEY in ufo_layer.lib:
119189
layer.layerId = ufo_layer.lib[LAYER_ID_KEY]
120-
layer.name = ufo_layer.name
190+
if LAYER_ORIGINAL_NAME_KEY in ufo_layer.lib:
191+
layer.name = ufo_layer.lib[LAYER_ORIGINAL_NAME_KEY]
192+
else:
193+
layer.name = ufo_layer.name
121194
glyph.layers.append(layer)
122195
order_key = LAYER_ORDER_PREFIX + glyph.name
123196
if order_key in ufo_layer.lib:

0 commit comments

Comments
 (0)