Example #1
0
    def __init__(self, ufo, ttFont=None, glyphSet=None, **kwargs):
        """
        Args:
          ufo: an object representing a UFO (defcon.Font or equivalent)
            containing the features source data.
          ttFont: a fontTools TTFont object where the generated OpenType
            tables are added. If None, an empty TTFont is used, with
            the same glyph order as the ufo object.
          glyphSet: a (optional) dict containing pre-processed copies of
            the UFO glyphs.
        """
        self.ufo = ufo

        if ttFont is None:
            from fontTools.ttLib import TTFont

            from ufo2ft.util import makeOfficialGlyphOrder

            ttFont = TTFont()
            ttFont.setGlyphOrder(makeOfficialGlyphOrder(ufo))
        self.ttFont = ttFont

        glyphOrder = ttFont.getGlyphOrder()
        if glyphSet is not None:
            assert set(glyphOrder) == set(glyphSet.keys())
        else:
            glyphSet = ufo
        self.glyphSet = OrderedDict((gn, glyphSet[gn]) for gn in glyphOrder)
Example #2
0
    def makeOfficialGlyphOrder(self, glyphOrder):
        """
        Make the final glyph order.

        **This should not be called externally.** Subclasses
        may override this method to handle the order creation
        in a different way if desired.
        """
        return makeOfficialGlyphOrder(self.allGlyphs, glyphOrder)
Example #3
0
    def subset_otf_from_ufo(self, otf_path, ufo):
        """Subset a font using export flags set by glyphsLib.

        There are two more settings that can change export behavior:
        "Export Glyphs" and "Remove Glyphs", which are currently not supported
        for complexity reasons. See
        https://github.com/googlei18n/glyphsLib/issues/295.
        """
        from fontTools import subset

        # ufo2ft always inserts a ".notdef" glyph as the first glyph
        ufo_order = makeOfficialGlyphOrder(ufo)
        if ".notdef" not in ufo_order:
            ufo_order.insert(0, ".notdef")
        ot_order = TTFont(otf_path).getGlyphOrder()
        assert ot_order[0] == ".notdef"
        assert len(ufo_order) == len(ot_order)

        for key in (KEEP_GLYPHS_NEW_KEY, KEEP_GLYPHS_OLD_KEY):
            keep_glyphs_list = ufo.lib.get(key)
            if keep_glyphs_list is not None:
                keep_glyphs = set(keep_glyphs_list)
                break
        else:
            keep_glyphs = None

        include = []
        for source_name, binary_name in zip(ufo_order, ot_order):
            if keep_glyphs and source_name not in keep_glyphs:
                continue

            if source_name in ufo:
                exported = ufo[source_name].lib.get(GLYPH_EXPORT_KEY, True)
                if not exported:
                    continue

            include.append(binary_name)

        # copied from nototools.subset
        opt = subset.Options()
        opt.name_IDs = ['*']
        opt.name_legacy = True
        opt.name_languages = ['*']
        opt.layout_features = ['*']
        opt.notdef_outline = True
        opt.recalc_bounds = True
        opt.recalc_timestamp = True
        opt.canonical_order = True

        opt.glyph_names = True

        font = subset.load_font(otf_path, opt, lazy=False)
        subsetter = subset.Subsetter(options=opt)
        subsetter.populate(glyphs=include)
        subsetter.subset(font)
        subset.save_font(font, otf_path, opt)
Example #4
0
    def set_context(self, font):
        ctx = super(MarkFeatureWriter, self).set_context(font)

        glyphOrder = makeOfficialGlyphOrder(font)
        ctx.glyphSet = OrderedDict(((gn, font[gn]) for gn in glyphOrder))

        ctx.accentGlyphNames = set()

        self.setupAnchorPairs()

        return ctx
Example #5
0
    def getOrderedGlyphSet(self):
        """Return OrderedDict[glyphName, glyph] sorted by glyphOrder.
        """
        compiler = self.context.compiler
        if compiler is not None:
            return compiler.glyphSet

        from ufo2ft.util import makeOfficialGlyphOrder

        glyphSet = self.context.font
        glyphOrder = makeOfficialGlyphOrder(self.context.font)
        return OrderedDict((gn, glyphSet[gn]) for gn in glyphOrder)
Example #6
0
    def _makeOrderedGlyphSet(font, compiler=None):
        """ Return glyph set as an OrderedDict sorted by glyphOrder to write
        mark/mkmk classes and rules in a deterministic order.
        """
        if compiler is not None:
            glyphSet = compiler.glyphSet
            glyphOrder = compiler.ttFont.getGlyphOrder()
        else:
            from ufo2ft.util import makeOfficialGlyphOrder

            glyphSet = font
            glyphOrder = makeOfficialGlyphOrder(font)
        return OrderedDict((gn, glyphSet[gn]) for gn in glyphOrder)
Example #7
0
    def _makeOrderedGlyphSet(font, compiler=None):
        """ Return glyph set as an OrderedDict sorted by glyphOrder to write
        mark/mkmk classes and rules in a deterministic order.
        """
        if compiler is not None:
            glyphSet = compiler.glyphSet
            glyphOrder = compiler.ttFont.getGlyphOrder()
        else:
            from ufo2ft.util import makeOfficialGlyphOrder

            glyphSet = font
            glyphOrder = makeOfficialGlyphOrder(font)
        return OrderedDict((gn, glyphSet[gn]) for gn in glyphOrder)
Example #8
0
    def getOrderedGlyphSet(self):
        """Return OrderedDict[glyphName, glyph] sorted by glyphOrder."""
        compiler = self.context.compiler
        if compiler is not None:
            return compiler.glyphSet

        from ufo2ft.util import _GlyphSet, makeOfficialGlyphOrder

        font = self.context.font
        # subset glyphSet by skipExportGlyphs if any
        glyphSet = _GlyphSet.from_layer(
            font,
            skipExportGlyphs=set(font.lib.get("public.skipExportGlyphs", [])),
        )
        glyphOrder = makeOfficialGlyphOrder(glyphSet, font.glyphOrder)
        return OrderedDict((gn, glyphSet[gn]) for gn in glyphOrder)
Example #9
0
    def subset_otf_from_ufo(self, otf_path, ufo):
        """Subset a font using "Keep Glyphs" custom parameter and export flags as set
        by glyphsLib.

        "Export Glyphs" and "Remove Glyphs" are currently not supported:
        https://github.com/googlei18n/glyphsLib/issues/295.
        """
        from fontTools import subset

        # we must exclude from the final UFO glyphOrder all the glyphs that were not
        # exported to OTF because included in 'public.skipExportGlyphs'
        skip_export_glyphs = set(ufo.lib.get("public.skipExportGlyphs", ()))
        exported_glyphs = dict.fromkeys(g for g in ufo.keys()
                                        if g not in skip_export_glyphs)
        ufo_order = makeOfficialGlyphOrder(exported_glyphs,
                                           glyphOrder=ufo.glyphOrder)
        # ufo2ft always inserts a ".notdef" glyph as the first glyph
        if ".notdef" not in exported_glyphs:
            ufo_order.insert(0, ".notdef")
        ot_order = TTFont(otf_path).getGlyphOrder()
        assert ot_order[0] == ".notdef"
        assert len(ufo_order) == len(ot_order)

        for key in (KEEP_GLYPHS_NEW_KEY, KEEP_GLYPHS_OLD_KEY):
            keep_glyphs_list = ufo.lib.get(key)
            if keep_glyphs_list is not None:
                keep_glyphs = set(keep_glyphs_list)
                break
        else:
            keep_glyphs = None

        include = []
        for source_name, binary_name in zip(ufo_order, ot_order):
            if keep_glyphs and source_name not in keep_glyphs:
                continue

            if source_name in ufo:
                exported = ufo[source_name].lib.get(GLYPH_EXPORT_KEY, True)
                if not exported:
                    continue

            include.append(binary_name)

        # copied from nototools.subset
        opt = subset.Options()
        opt.name_IDs = ["*"]
        opt.name_legacy = True
        opt.name_languages = ["*"]
        opt.layout_features = ["*"]
        opt.notdef_outline = True
        opt.recalc_bounds = True
        opt.recalc_timestamp = True
        opt.canonical_order = True

        opt.glyph_names = True

        font = subset.load_font(otf_path, opt, lazy=False)
        subsetter = subset.Subsetter(options=opt)
        subsetter.populate(glyphs=include)
        subsetter.subset(font)
        subset.save_font(font, otf_path, opt)