1212# See the License for the specific language governing permissions and
1313# limitations under the License.
1414
15+ import re
16+
1517from .constants import GLYPHS_PREFIX
1618
1719LAYER_ID_KEY = GLYPHS_PREFIX + "layerId"
1820LAYER_ORDER_PREFIX = GLYPHS_PREFIX + "layerOrderInGlyph."
1921LAYER_ORDER_TEMP_USER_DATA_KEY = "__layerOrder"
22+ LAYER_ORIGINAL_NAME_KEY = GLYPHS_PREFIX + "layerOriginalName"
23+ FOREGROUND_LAYER_ID_KEY = GLYPHS_PREFIX + "foregroundLayerId"
2024
2125
2226def 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
4986def 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