Hi! I’m using python, deepcopy, and glyphsLib. The purpose to duplicate is to then scale all of these layers as a post-process step for new masters.I’m struggling to duplicate the masters with my intermediate masters in my output before fontmake. Here is my python. What am i missing to duplicate the intermediate masters?
import math
from copy import deepcopy
from tqdm import tqdm
from glyphsLib.classes import GSLayer
SCALE_LC = 1.12
SCALE_UC_NUM = 1.08
def iround(x): return int(math.floor(x + 0.5))
def get_scale_for_glyph(glyph):
if glyph.category == "Number": return SCALE_UC_NUM
if glyph.category == "Letter" and glyph.subCategory == "Uppercase": return SCALE_UC_NUM
return SCALE_LC
def scale_layer_content(layer, scale):
for shape in layer.shapes:
if hasattr(shape, 'nodes'):
for node in shape.nodes:
node.position.x = iround(node.position.x * scale)
node.position.y = iround(node.position.y * scale)
if hasattr(shape, 'position') and not hasattr(shape, 'nodes'):
shape.position.x = iround(shape.position.x * scale)
shape.position.y = iround(shape.position.y * scale)
for anchor in layer.anchors:
anchor.position.x = iround(anchor.position.x * scale)
anchor.position.y = iround(anchor.position.y * scale)
def adjust_spacing(layer, amount):
for shape in layer.shapes:
if hasattr(shape, 'nodes'):
for node in shape.nodes:
node.position.x += amount
for anchor in layer.anchors:
anchor.position.x += amount
layer.width += (amount * 2)
def recalculate_component_widths(font, master_id):
for glyph in font.glyphs:
layer = glyph.layers[master_id]
if len(layer.components) > 0 and len(layer.paths) == 0:
base_comp = layer.components[0]
if base_comp.componentName in font.glyphs:
base_layer = font.glyphs[base_comp.componentName].layers[master_id]
layer.width = base_layer.width
def generate_and_scale_8pt(font, opsz_axis_index=0):
base_masters = [m for m in font.masters if m.axes[opsz_axis_index] == 18]
if not base_masters:
return
for master in base_masters:
print(f"\n--- Genning and scaling 8pt Micro from {master.name} ---")
new_m = deepcopy(master)
new_m.name = master.name.replace("Head", "Micro").replace("Dek", "Micro")
new_m.axes[opsz_axis_index] = 8
new_m.stems = [deepcopy(s) for s in master.stems]
font.masters.append(new_m)
for glyph in tqdm(font.glyphs, desc=f"Scaling {new_m.name}"):
scale = get_scale_for_glyph(glyph)
source_layers = [l for l in glyph.layers if l.associatedMasterId == master.id]
for src_layer in source_layers:
is_brace = "coordinates" in src_layer.attributes or getattr(src_layer, "isBraceLayer", False)
dest_layer = deepcopy(src_layer)
dest_layer.associatedMasterId = new_m.id
if not is_brace:
dest_layer.layerId = new_m.id
dest_layer.name = new_m.name
else:
if "coordinates" in dest_layer.attributes:
coords = list(dest_layer.attributes["coordinates"])
while len(coords) < 4: coords.append(0)
coords[0] = 8
dest_layer.attributes["coordinates"] = coords
dest_layer.name = "{" + ", ".join(map(str, coords)) + "}"
scale_layer_content(dest_layer, scale)
dest_layer.width = iround(src_layer.width * scale)
glyph.layers.append(dest_layer)
for glyph in font.glyphs:
target_layers = [l for l in glyph.layers if l.associatedMasterId == master.id]
for layer in target_layers: adjust_spacing(layer, -10)
for glyph in font.glyphs:
target_layers = [l for l in glyph.layers if l.associatedMasterId == new_m.id]
for layer in target_layers: adjust_spacing(layer, 10)
recalculate_component_widths(font, master.id)
recalculate_component_widths(font, new_m.id)
CalSansUI.glyphs (506.3 KB)