Exemple #1
0
 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()
Exemple #2
0
    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
Exemple #3
0
    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