def _getIndicGlyphs(self): cmap = self.makeUnicodeToGlyphNameMapping() unicodeIsIndic = partial(unicodeInScripts, scripts=self.indicScripts) if any(unicodeIsIndic for uv in cmap): # If there are any characters from Indic scripts in the cmap, we # compile a temporary GSUB table to resolve substitutions and get # the set of all the "Indic" glyphs, including alternate glyphs. gsub = self.compileGSUB() glyphGroups = classifyGlyphs(unicodeIsIndic, cmap, gsub) # the 'glyphGroups' dict is keyed by the return value of the # classifying include, so here 'True' means all the Indic glyphs return glyphGroups.get(True, set()) else: return set()
def _makeKerningLookups(self): cmap = self.makeUnicodeToGlyphNameMapping() if any(unicodeScriptDirection(uv) == "RTL" for uv in cmap): # If there are any characters from globally RTL scripts in the # cmap, we compile a temporary GSUB table to resolve substitutions # and group glyphs by script horizontal direction and bidirectional # type. We then mark each kerning pair with these properties when # any of the glyphs involved in a pair intersects these groups. gsub = self.compileGSUB() dirGlyphs = classifyGlyphs(unicodeScriptDirection, cmap, gsub) directions = self._intersectPairs("directions", dirGlyphs) shouldSplit = "RTL" in directions if shouldSplit: bidiGlyphs = classifyGlyphs(unicodeBidiType, cmap, gsub) self._intersectPairs("bidiTypes", bidiGlyphs) else: shouldSplit = False marks = self.context.gdefClasses.mark lookups = {} if shouldSplit: # make one DFLT lookup with script-agnostic characters, and two # LTR/RTL lookups excluding pairs from the opposite group. # We drop kerning pairs with ambiguous direction: i.e. those containing # glyphs from scripts with different overall horizontal direction, or # glyphs with incompatible bidirectional type (e.g. arabic letters vs # arabic numerals). pairs = [] for pair in self.context.kerning.pairs: if ("RTL" in pair.directions and "LTR" in pair.directions) or ( "R" in pair.bidiTypes and "L" in pair.bidiTypes): self.log.warning( "skipped kern pair with ambiguous direction: %r", pair) continue pairs.append(pair) if not pairs: return lookups if self.options.ignoreMarks: # If there are pairs with a mix of mark/base then the IgnoreMarks # flag is unnecessary and should not be set basePairs, markPairs = self._splitBaseAndMarkPairs( pairs, marks) self._makeSplitDirectionKernLookups(lookups, basePairs) if markPairs: self._makeSplitDirectionKernLookups(lookups, markPairs, ignoreMarks=False, suffix="_marks") else: self._makeSplitDirectionKernLookups(lookups, pairs) else: # only make a single (implicitly LTR) lookup including all base/base pairs # and a single lookup including all base/mark pairs (if any) pairs = self.context.kerning.pairs if self.options.ignoreMarks: basePairs, markPairs = self._splitBaseAndMarkPairs( pairs, marks) lookups["LTR"] = [ self._makeKerningLookup("kern_ltr", basePairs) ] if markPairs: lookups["LTR"].append( self._makeKerningLookup("kern_ltr_marks", markPairs, ignoreMarks=False)) else: lookups["LTR"] = [self._makeKerningLookup("kern_ltr", pairs)] return lookups
def _makeKerningLookups(self): cmap = self.makeUnicodeToGlyphNameMapping() if any(unicodeScriptDirection(uv) == "RTL" for uv in cmap): # If there are any characters from globally RTL scripts in the # cmap, we compile a temporary GSUB table to resolve substitutions # and group glyphs by script horizontal direction and bidirectional # type. We then mark each kerning pair with these properties when # any of the glyphs involved in a pair intersects these groups. gsub = self.compileGSUB() dirGlyphs = classifyGlyphs(unicodeScriptDirection, cmap, gsub) directions = self._intersectPairs("directions", dirGlyphs) shouldSplit = "RTL" in directions if shouldSplit: bidiGlyphs = classifyGlyphs(unicodeBidiType, cmap, gsub) self._intersectPairs("bidiTypes", bidiGlyphs) else: shouldSplit = False lookups = {} if shouldSplit: # make one DFLT lookup with script-agnostic characters, and two # LTR/RTL lookups excluding pairs from the opposite group. # We drop kerning pairs with ambiguous direction. pairs = [] for pair in self.context.kerning.pairs: if "RTL" in pair.directions and "LTR" in pair.directions: self.log.warning( "skipped kern pair with ambiguous direction: %r", pair) continue pairs.append(pair) if not pairs: return lookups dfltKern = self._makeKerningLookup( "kern_dflt", pairs, exclude=( lambda pair: {"LTR", "RTL"}.intersection(pair.directions)), rtl=False, ) if dfltKern: lookups["DFLT"] = dfltKern ltrKern = self._makeKerningLookup( "kern_ltr", pairs, exclude=(lambda pair: not pair.directions or "RTL" in pair. directions), rtl=False, ) if ltrKern: lookups["LTR"] = ltrKern rtlKern = self._makeKerningLookup( "kern_rtl", pairs, exclude=(lambda pair: not pair.directions or "LTR" in pair. directions), rtl=True, ) if rtlKern: lookups["RTL"] = rtlKern else: # only make a single (implicitly LTR) lookup including all pairs lookups["LTR"] = self._makeKerningLookup( "kern_ltr", self.context.kerning.pairs) return lookups