Пример #1
0
def to_ufo_components_background_decompose(self, ufo_glyph, layer):
    """Draw decomposed .glyphs background components with a pen, adding them to
    the parent glyph."""

    layer_id = layer.foreground.layerId
    layer_master_id = layer.foreground.associatedMasterId

    if layer_id in self._glyph_sets:
        layers = self._glyph_sets[layer_id]
    else:
        if layer_id == layer_master_id:
            # Is a master layer.
            layers = self._glyph_sets[layer_id] = {
                g.name: l
                for g in layer.parent.parent.glyphs
                for l in g.layers
                if l.layerId == layer_id
            }
        else:
            # Is a non-master layer.
            layers_nonmaster = {
                g.name: l
                for g in layer.parent.parent.glyphs
                for l in g.layers
                if l.name == layer.name
            }
            layers_master = {
                g.name: l
                for g in layer.parent.parent.glyphs
                for l in g.layers
                if l.layerId == layer_master_id
            }
            layers = self._glyph_sets[layer_id] = {
                **layers_master,
                **layers_nonmaster,
            }

    rpen = DecomposingRecordingPen(glyphSet=layers)
    for component in layer.components:
        try:
            component.draw(rpen)
        except MissingComponentError as e:
            raise MissingComponentError(
                f"Glyph '{ufo_glyph.name}', background layer: component "
                f"'{component.name}' points to a non-existent glyph."
            ) from e
    rpen.replay(ufo_glyph.getPen())
Пример #2
0
def ttfont_glyph_to_skia_path(glyph_name: str, tt_font: ttFont.TTFont) -> pathops.Path:
    """
    Converts fontTools.ttLib.TTFont glyph to a pathops.Path object
    by glyph name.  During this conversion, all composite paths are
    decomposed.
    """
    glyf_table = tt_font["glyf"]
    glyph_set: ttFont._TTGlyphSet = tt_font.getGlyphSet()
    tt_glyph = glyf_table[glyph_name]
    skia_path = pathops.Path()
    skia_path_pen = skia_path.getPen()

    if tt_glyph.isComposite():
        decompose_pen = DecomposingRecordingPen(glyph_set)
        glyph_set[glyph_name].draw(decompose_pen)
        decompose_pen.replay(skia_path_pen)
        return skia_path
    else:
        glyph_set[glyph_name].draw(skia_path_pen)
        return skia_path
Пример #3
0
def to_ufo_components_background_decompose(self, ufo_glyph, layer):
    """Draw decomposed .glyphs background components with a pen, adding them to
    the parent glyph."""

    layer_id = layer.foreground.layerId
    layer_master_id = layer.foreground.associatedMasterId

    if layer_id in self._glyph_sets:
        layers = self._glyph_sets[layer_id]
    else:
        if layer_id == layer_master_id:
            # Is a master layer.
            layers = self._glyph_sets[layer_id] = {
                g.name: l
                for g in layer.parent.parent.glyphs
                for l in g.layers
                if l.layerId == layer_id
            }
        else:
            # Is a non-master layer.
            layers_nonmaster = {
                g.name: l
                for g in layer.parent.parent.glyphs
                for l in g.layers
                if l.name == layer.name
            }
            layers_master = {
                g.name: l
                for g in layer.parent.parent.glyphs
                for l in g.layers
                if l.layerId == layer_master_id
            }
            layers = self._glyph_sets[layer_id] = {
                **layers_master,
                **layers_nonmaster,
            }

    rpen = DecomposingRecordingPen(glyphSet=layers)
    for component in layer.components:
        component.draw(rpen)
    rpen.replay(ufo_glyph.getPen())
Пример #4
0
def decomposeAndRemoveOverlap(font, glyphName):

    glyfTable = font["glyf"]
    glyphSet = font.getGlyphSet()

    # record TTGlyph outlines without components
    dcPen = DecomposingRecordingPen(glyphSet)
    glyphSet[glyphName].draw(dcPen)

    # replay recording onto a skia-pathops Path
    path = pathops.Path()
    pathPen = path.getPen()
    dcPen.replay(pathPen)

    # remove overlaps
    path.simplify()

    # create new TTGlyph from Path
    ttPen = TTGlyphPen(None)
    path.draw(ttPen)
    glyfTable[glyphName] = ttPen.glyph()
def process_font(input_path, output_path=None, verbose=False):
    """
    De-componentize a single font at input_path, saving to output_path (or
    input_path if None)
    """
    font = TTFont(input_path)
    output_path = output_path or input_path
    gs = font.getGlyphSet()
    drpen = DecomposingRecordingPen(gs)
    ttgpen = TTGlyphPen(gs)

    count = 0
    for glyphname in font.glyphOrder:
        glyph = font["glyf"][glyphname]
        if not glyph.isComposite():
            continue

        if verbose:
            print(f"    decomposing '{glyphname}'")

        # reset the pens
        drpen.value = []
        ttgpen.init()

        # draw the composite glyph into the decomposing pen
        glyph.draw(drpen, font["glyf"])
        # replay the recorded decomposed glyph into the TTGlyphPen
        drpen.replay(ttgpen)
        # store the decomposed glyph in the 'glyf' table
        font["glyf"][glyphname] = ttgpen.glyph()

        count += 1

    font.save(output_path)

    return count
Пример #6
0
src = sys.argv[1]
dst = sys.argv[2]

with TTFont(src) as f:
    glyfTable = f["glyf"]
    glyphSet = f.getGlyphSet()

    for glyphName in glyphSet.keys():
        if not glyfTable[glyphName].isComposite():
            continue

        # record TTGlyph outlines without components
        dcPen = DecomposingRecordingPen(glyphSet)
        glyphSet[glyphName].draw(dcPen)

        # replay recording onto a skia-pathops Path
        path = pathops.Path()
        pathPen = path.getPen()
        dcPen.replay(pathPen)

        # remove overlaps
        path.simplify()

        # create new TTGlyph from Path
        ttPen = TTGlyphPen(None)
        path.draw(ttPen)
        glyfTable[glyphName] = ttPen.glyph()

    f.save(dst)