Created
May 10, 2022 13:53
-
-
Save mathieureguer/ca8d7eba03a9ce281e8476e48eb650ea to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Run in Robofont. | |
Tries to add anchors to selected glyphs, based on the position of components in relevant glyphs. | |
This script is not smart enough to distinguish top and bottom anchors (sorry), it must be run again for each target_anchor_name. | |
Here is a typical process: | |
- add "_top" to the circumflex glyph (we need at least an anchor as a starting point) | |
- set target_anchor_name to "top" | |
- select the base glyphs you want anchored (both base letters and diacritic glyphs) | |
- run | |
- add "_bottom" to the cedilla glyph | |
- set target_anchor_name to "bottom" | |
- select the base glyphs you want anchored (both base letters and diacritic glyphs) | |
- run again | |
- ... | |
""" | |
target_anchor_name = "top" | |
prefered_reference = ["circumflexcmb", "circumflex", "circumflex.cap", "cedillacmb" "cedilla", ] | |
# ---------------------------------------- | |
def get_matching_anchor_name(anchor_name): | |
if anchor_name.startswith("_"): | |
return anchor_name[1:] | |
else: | |
return "_" + anchor_name | |
def is_anchored(self, glyph): | |
if len(glyph.anchors) > 0: | |
return True | |
else: | |
return True | |
def has_anchor(glyph, anchor_name): | |
return anchor_name in (a.name for a in glyph.anchors) | |
def get_anchor_by_name(glyph, anchor_name): | |
for a in glyph.anchors: | |
if a.name == anchor_name: | |
return a | |
def has_priority_components(glyph): | |
has_targets = [comp.baseGlyph in prefered_reference for comp in glyph.components] | |
return sum(has_targets) | |
def sort_glyph_according_to_priority_components(glyph_list): | |
return sorted(references, key=lambda x: has_priority_components(x), reverse=True) | |
# ---------------------------------------- | |
f = CurrentFont() | |
sel = f.selectedGlyphNames | |
reverse_comp_map = {} | |
for g in f: | |
for c in g.components: | |
reverse_comp_map.setdefault(c.baseGlyph, []).append(g) | |
for target in sel: | |
target_glyph = f[target] | |
print(f"Checking {target}") | |
references = reverse_comp_map.get(target, []) | |
for reference in sort_glyph_according_to_priority_components(references): | |
# only look at glyph with 2 components | |
# other cases create too many special cases | |
if len(reference.components) == 2: | |
# print(f"reference found {reference}") | |
target_comp = [comp for comp in reference.components if comp.baseGlyph == target] | |
if len(target_comp) > 0: | |
target_comp = target_comp[0] | |
else: | |
continue | |
other_comp = [comp for comp in reference.components if comp.baseGlyph != target] | |
if len(other_comp) > 0: | |
other_comp = other_comp[0] | |
else: | |
continue | |
other_glyph = f[other_comp.baseGlyph] | |
other_anchor_name = get_matching_anchor_name(target_anchor_name) | |
# print(target_anchor_name, other_anchor_name) | |
# print(target_glyph, other_glyph) | |
if has_anchor(other_glyph, other_anchor_name) and not has_anchor(target_glyph, target_anchor_name): | |
other_anchor = get_anchor_by_name(other_glyph, other_anchor_name) | |
pos_x = int(other_comp.offset[0] - target_comp.offset[0] + other_anchor.position[0]) | |
pos_y = int(other_comp.offset[1] - target_comp.offset[1] + other_anchor.position[1]) | |
print(f"{target_glyph.name}: added anchor {target_anchor_name} <{pos_x} {pos_y}> using {reference.name} as reference") | |
target_glyph.appendAnchor(name=target_anchor_name, position=(pos_x, pos_y)) | |
# elif has_anchor(other_glyph, target_anchor_name) and not has_anchor(target_glyph, other_anchor_name): | |
# target_anchor = get_anchor_by_name(other_glyph, target_anchor_name) | |
# pos_x = int(target_anchor.position[0] - target_comp.offset[0]) | |
# pos_y = int(target_anchor.position[1] - target_comp.offset[1]) | |
# print(f"{target_glyph.name}: added anchor {other_anchor_name} <{pos_x} {pos_y}> using {reference.name} as reference") | |
# target_glyph.appendAnchor(name=other_anchor_name, position=(pos_x, pos_y)) | |
# |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment