Skip to content

Commit

Permalink
Refactor MarkFeatureWriter._makeContextualAttachments
Browse files Browse the repository at this point in the history
Make attachments for mark2base and mark2liga in the same pass
Coerce numberless liga anchors to mark2base
  • Loading branch information
RickyDaMa committed Nov 21, 2024
1 parent d05c7f3 commit 03d831f
Showing 1 changed file with 23 additions and 19 deletions.
42 changes: 23 additions & 19 deletions Lib/ufo2ft/featureWriters/markFeatureWriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import re
from collections import OrderedDict, defaultdict
from functools import partial
from typing import Dict, Set, Tuple

from ufo2ft.constants import INDIC_SCRIPTS, OBJECT_LIBS_KEY, USE_SCRIPTS
from ufo2ft.featureWriters import BaseFeatureWriter, ast
Expand Down Expand Up @@ -725,25 +726,31 @@ def _makeMarkToLigaAttachments(self):
result.append(MarkToLigaPos(glyphName, ligatureMarks))
return result

def _makeContextualAttachments(self, glyphClass, liga=False):
ctx = self.context
result = defaultdict(list)
markGlyphNames = ctx.markGlyphNames
for glyphName, anchors in sorted(ctx.anchorLists.items()):
if glyphName in markGlyphNames:
def _makeContextualAttachments(
self, baseClass: Set[str], ligatureClass: Set[str]
) -> Tuple[Dict[str, Tuple[str, NamedAnchor]], Dict[str, Tuple[str, NamedAnchor]]]:
baseResult = defaultdict(list)
ligatureResult = defaultdict(list)

for glyphName, anchors in sorted(self.context.anchorLists.items()):
if glyphName in self.context.markGlyphNames:
continue
if glyphClass and glyphName not in glyphClass:
if glyphName not in baseClass and glyphName not in ligatureClass:
# TODO: should this be a warning everything should be one group or another?
continue
for anchor in anchors:
# Skip non-contextual anchors
if not anchor.isContextual:
continue
# If we are building the mark2liga lookup, skip anchors without a number
if liga and anchor.number is None:
continue
# If we are building the mark2base lookup, skip anchors with a number
if not liga and anchor.number is not None:
if glyphName in ligatureClass and anchor.number:
dest = ligatureResult
elif glyphName in baseClass and anchor.number:
# Skip mark2base where anchor has a number
continue
else:
# Note: this catch-all treats ligas without anchor numbers
# as mark2base
dest = baseResult
anchor_context = anchor.libData.get("GPOS_Context", "").strip()
if not anchor_context:
self.log.warning(
Expand All @@ -752,8 +759,8 @@ def _makeContextualAttachments(self, glyphClass, liga=False):
glyphName,
)
continue
result[anchor_context].append((glyphName, anchor))
return result
dest[anchor_context].append((glyphName, anchor))
return baseResult, ligatureResult

@staticmethod
def _iterAttachments(attachments, include=None, marksFilter=None):
Expand Down Expand Up @@ -1031,12 +1038,9 @@ def _makeFeatures(self):
ctx.markToMarkAttachments = self._makeMarkToMarkAttachments()

baseClass = self.context.gdefClasses.base
ctx.contextualMarkToBaseAnchors = self._makeContextualAttachments(baseClass)

ligatureClass = self.context.gdefClasses.ligature
ctx.contextualMarkToLigaAnchors = self._makeContextualAttachments(
ligatureClass,
True,
ctx.contextualMarkToBaseAnchors, ctx.contextualMarkToLigaAnchors = (
self._makeContextualAttachments(baseClass, ligatureClass)
)

abvmGlyphs, notAbvmGlyphs = self._getAbvmGlyphs()
Expand Down

0 comments on commit 03d831f

Please sign in to comment.