示例#1
0
def transformationAtCenter(matrix, centerPoint):
    """Helper function for rotate(), scale() and skew() to apply a
    transformation with a specified center point.

        >>> transformationAtCenter((2, 0, 0, 2, 0, 0), (0, 0))
        (2, 0, 0, 2, 0, 0)
        >>> transformationAtCenter((2, 0, 0, 2, 0, 0), (100, 200))
        (2, 0, 0, 2, -100, -200)
        >>> transformationAtCenter((-2, 0, 0, 2, 0, 0), (100, 200))
        (-2, 0, 0, 2, 300, -200)
        >>> t = Transform(*transformationAtCenter((0, 1, 1, 0, 0, 0), (100, 200)))
        >>> t.transformPoint((100, 200))
        (100, 200)
        >>> t.transformPoint((0, 0))
        (-100, 100)
    """
    if centerPoint == (0, 0):
        return matrix

    t = Transform()
    cx, cy = centerPoint
    t = t.translate(cx, cy)
    t = t.transform(matrix)
    t = t.translate(-cx, -cy)
    return tuple(t)
示例#2
0
 def test_reverseTransform(self):
     t = Transform(2, 0, 0, 3, 1, 6)
     reverse_t = t.reverseTransform((4, 3, 2, 1, 5, 6))
     assert reverse_t == Transform(8, 6, 6, 3, 21, 15)
     t = Transform(4, 3, 2, 1, 5, 6)
     reverse_t = t.transform((2, 0, 0, 3, 1, 6))
     assert reverse_t == Transform(8, 6, 6, 3, 21, 15)
示例#3
0
 def test_reverseTransform(self):
     t = Transform(2, 0, 0, 3, 1, 6)
     reverse_t = t.reverseTransform((4, 3, 2, 1, 5, 6))
     assert reverse_t == Transform(8, 6, 6, 3, 21, 15)
     t = Transform(4, 3, 2, 1, 5, 6)
     reverse_t = t.transform((2, 0, 0, 3, 1, 6))
     assert reverse_t == Transform(8, 6, 6, 3, 21, 15)
示例#4
0
 def transform(self, transform, center=(0, 0)):
     cx, cy = center
     t = Transform()
     t = t.translate(cx, cy)
     t = t.transform(transform)
     t = t.translate(-cx, -cy)
     matrix = skia.Matrix()
     matrix.setAffine(t)
     self.path.transform(matrix)
示例#5
0
def _flattenComponent(glyphSet, component):
    """Returns a list of tuples (baseGlyph, transform) of nested component."""

    glyph = glyphSet[component.baseGlyph]
    # Any contour will cause components to be decomposed
    if not glyph.components or len(glyph) > 0:
        transformation = Transform(*component.transformation)
        return [(component.baseGlyph, transformation)]

    all_flattened_components = []
    for nested in glyph.components:
        flattened_components = _flattenComponent(glyphSet, nested)
        for i, (name, tr) in enumerate(flattened_components):
            flat_tr = Transform(*component.transformation)
            flat_tr = flat_tr.translate(tr.dx, tr.dy)
            flat_tr = flat_tr.transform((tr.xx, tr.xy, tr.yx, tr.yy, 0, 0))
            flattened_components[i] = (name, flat_tr)
        all_flattened_components.extend(flattened_components)
    return all_flattened_components
示例#6
0
def propagate_anchors(ufo):
    """Copy anchors from parent glyphs' components to the parent."""

    from fontTools.misc.transform import Transform

    def get_anchor(glyph, name):
        return next((a for a in glyph.anchors if a.name == name), None)

    for parent in ufo:
        added_here = {}

        # don't propagate anchors for mark glyphs
        if any(a.name.startswith('_') for a in parent.anchors):
            continue

        # try to get anchors from base (first) components
        glyph = parent
        transformation = Transform()
        while glyph.components:
            component = glyph.components[0]
            glyph = ufo[component.baseGlyph]
            transformation = transformation.transform(component.transformation)
            for anchor in glyph.anchors:
                if get_anchor(parent, anchor.name) is None:
                    added_here[anchor.name] = transformation.transformPoint(
                        (anchor.x, anchor.y))

        # adjust anchors to which a mark has been attached
        for component in parent.components[1:]:
            glyph = ufo[component.baseGlyph]
            transformation = Transform(*component.transformation)
            for anchor in glyph.anchors:
                if (anchor.name in added_here
                        and get_anchor(glyph, '_' + anchor.name) is not None):
                    added_here[anchor.name] = transformation.transformPoint(
                        (anchor.x, anchor.y))

        for name, (x, y) in added_here.items():
            anchor_dict = {'name': name, 'x': x, 'y': y}
            parent.appendAnchor(glyph.anchorClass(anchorDict=anchor_dict))
示例#7
0
def propagate_anchors(ufo):
    """Copy anchors from parent glyphs' components to the parent."""

    from fontTools.misc.transform import Transform

    def get_anchor(glyph, name):
        return next((a for a in glyph.anchors if a.name == name), None)

    for parent in ufo:
        added_here = {}

        # don't propagate anchors for mark glyphs
        if any(a.name.startswith('_') for a in parent.anchors):
            continue

        # try to get anchors from base (first) components
        glyph = parent
        transformation = Transform()
        while glyph.components:
            component = glyph.components[0]
            glyph = ufo[component.baseGlyph]
            transformation = transformation.transform(component.transformation)
            for anchor in glyph.anchors:
                if get_anchor(parent, anchor.name) is None:
                    added_here[anchor.name] = transformation.transformPoint(
                        (anchor.x, anchor.y))

        # adjust anchors to which a mark has been attached
        for component in parent.components[1:]:
            glyph = ufo[component.baseGlyph]
            transformation = Transform(*component.transformation)
            for anchor in glyph.anchors:
                if (anchor.name in added_here and
                    get_anchor(glyph, '_' + anchor.name) is not None):
                    added_here[anchor.name] = transformation.transformPoint(
                        (anchor.x, anchor.y))

        for name, (x, y) in added_here.items():
            anchor_dict = {'name': name, 'x': x, 'y': y}
            parent.appendAnchor(glyph.anchorClass(anchorDict=anchor_dict))
def transformationAtCenter(matrix, centerPoint):
    """Helper function for rotate(), scale() and skew() to apply a transformation
    with a specified center point.

        >>> transformationAtCenter((2, 0, 0, 2, 0, 0), (0, 0))
        (2, 0, 0, 2, 0, 0)
        >>> transformationAtCenter((2, 0, 0, 2, 0, 0), (100, 200))
        (2, 0, 0, 2, -100, -200)
        >>> transformationAtCenter((-2, 0, 0, 2, 0, 0), (100, 200))
        (-2, 0, 0, 2, 300, -200)
        >>> t = Transform(*transformationAtCenter((0, 1, 1, 0, 0, 0), (100, 200)))
        >>> t.transformPoint((100, 200))
        (100, 200)
        >>> t.transformPoint((0, 0))
        (-100, 100)
    """
    if centerPoint == (0, 0):
        return matrix
    t = Transform()
    cx, cy = centerPoint
    t = t.translate(cx, cy)
    t = t.transform(matrix)
    t = t.translate(-cx, -cy)
    return tuple(t)
示例#9
0
def parsePositions(baseGlyph, markGlyph, font, markTransformMap, advanceWidth,
                   advanceHeight):
    xx, xy, yx, yy, x, y = 1, 0, 0, 1, advanceWidth, advanceHeight

    baseGlyphX = baseGlyphY = baseGlyph
    markFixedX = markFixedY = False

    flipX = flipY = False

    if positionSplit in markGlyph:
        markGlyph, position = markGlyph.split(positionSplit)

        if positionXYSplit in position:
            positions = position.split(positionXYSplit)
            if len(positions) == 6:
                xx, xy, yx, yy, positionX, positionY = positions
                xx = float(xx)
                xy = float(xy)
                yx = float(yx)
                yy = float(yy)
            elif len(positions) == 2:
                positionX, positionY = positions
            else:
                raise GlyphBuilderError(
                    "mark positions should have 6 or 2 options")
        else:
            positionX = positionY = position

        if positionBaseSplit in positionX:
            baseGlyphX, positionX = positionX.split(positionBaseSplit)

        if positionBaseSplit in positionY:
            baseGlyphY, positionY = positionY.split(positionBaseSplit)

        if flipMarkGlyphSplit in positionX:
            flipX = True
            positionX = positionX.replace(flipMarkGlyphSplit, "")

        if flipMarkGlyphSplit in positionY:
            flipY = True
            positionY = positionY.replace(flipMarkGlyphSplit, "")

        if positionX and positionY:
            baseX = baseY = 0
            markX = markY = 0

            if markGlyph not in font:
                if glyphSuffixSplit in markGlyph:
                    markGlyph = markGlyph.split(glyphSuffixSplit)[0]

            markPoint1, markAngle1, markFixedX = parsePosition(markGlyph,
                                                               font,
                                                               positionX,
                                                               direction="x",
                                                               prefix="_")
            markPoint2, markAngle2, markFixedY = parsePosition(markGlyph,
                                                               font,
                                                               positionY,
                                                               direction="y",
                                                               prefix="_")
            intersection = _intersectAngles(markPoint1, markAngle1, markPoint2,
                                            markAngle2)
            if intersection is not None:
                markX, markY = intersection

            if baseGlyphX in font and baseGlyphY in font:
                basePoint1, baseAngle1, _ = parsePosition(baseGlyphX,
                                                          font,
                                                          positionX,
                                                          direction="x",
                                                          isBase=True)
                basePoint2, baseAngle2, _ = parsePosition(baseGlyphY,
                                                          font,
                                                          positionY,
                                                          direction="y",
                                                          isBase=True)
                intersection = _intersectAngles(basePoint1, baseAngle1,
                                                basePoint2, baseAngle2)
                if intersection is not None:
                    baseX, baseY = intersection

            # calculate the offset
            if not markFixedX:
                x += baseX - markX
            else:
                x += markX

            if not markFixedY:
                y += baseY - markY
            else:
                y += markY

        if not markFixedX:
            baseTransform = markTransformMap.get(baseGlyphX)
            if baseTransform:
                x += baseTransform[4] - advanceWidth

        if not markFixedY:
            baseTransform = markTransformMap.get(baseGlyphY)
            if baseTransform:
                y += baseTransform[5] - advanceHeight

    transformMatrix = (xx, xy, yx, yy, x, y)

    if flipX:
        bounds = font[markGlyph].bounds
        if bounds:
            minx, miny, maxx, maxy = bounds
            bt = Transform(*transformMatrix)
            minx, miny = bt.transformPoint((minx, miny))
            maxx, maxy = bt.transformPoint((maxx, maxy))
            t = Transform()
            t = t.translate(0, miny)
            t = t.scale(1, -1)
            t = t.translate(0, -maxy)
            t = t.transform(bt)
            transformMatrix = t[:]

    if flipY:
        bounds = font[markGlyph].bounds
        if bounds:
            minx, miny, maxx, maxy = bounds
            bt = Transform(*transformMatrix)
            minx, miny = bt.transformPoint((minx, miny))
            maxx, maxy = bt.transformPoint((maxx, maxy))
            t = Transform()
            t = t.translate(minx, 0)
            t = t.scale(-1, 1)
            t = t.translate(-maxx, 0)
            t = t.transform(bt)
            transformMatrix = t[:]
    return markGlyph, transformMatrix
示例#10
0
 def test_transform(self):
     t = Transform(2, 0, 0, 3, 1, 6)
     assert t.transform((4, 3, 2, 1, 5, 6)) == Transform(8, 9, 4, 3, 11, 24)
def parsePositions(baseGlyph, markGlyph, font, markTransformMap, advanceWidth, advanceHeight):
    xx, xy, yx, yy, x, y = 1, 0, 0, 1, advanceWidth, advanceHeight

    baseGlyphX = baseGlyphY = baseGlyph
    markFixedX = markFixedY = False

    flipX = flipY = False

    if positionSplit in markGlyph:
        markGlyph, position = markGlyph.split(positionSplit)

        if positionXYSplit in position:
            positions = position.split(positionXYSplit)
            if len(positions) == 6:
                xx, xy, yx, yy, positionX, positionY = positions
                xx = float(xx)
                xy = float(xy)
                yx = float(yx)
                yy = float(yy)
            elif len(positions) == 2:
                positionX, positionY = positions
            else:
                raise GlyphBuilderError("mark positions should have 6 or 2 options")
        else:
            positionX = positionY = position

        if positionBaseSplit in positionX:
            baseGlyphX, positionX = positionX.split(positionBaseSplit)

        if positionBaseSplit in positionY:
            baseGlyphY, positionY = positionY.split(positionBaseSplit)

        if flipMarkGlyphSplit in positionX:
            flipY = True
            positionX = positionX.replace(flipMarkGlyphSplit, "")

        if flipMarkGlyphSplit in positionY:
            flipX = True
            positionY = positionY.replace(flipMarkGlyphSplit, "")

        if positionX and positionY:
            baseX = baseY = 0
            markX = markY = 0

            if markGlyph not in font:
                if glyphSuffixSplit in markGlyph:
                    markGlyph = markGlyph.split(glyphSuffixSplit)[0]

            markPoint1, markAngle1, markFixedX = parsePosition(markGlyph, font, positionX, direction="x", prefix="_")
            markPoint2, markAngle2, markFixedY = parsePosition(markGlyph, font, positionY, direction="y", prefix="_")
            intersection = _intersectAngles(markPoint1, markAngle1, markPoint2, markAngle2)
            if intersection is not None:
                markX, markY = intersection

            if baseGlyphX in font and baseGlyphY in font:
                basePoint1, baseAngle1, _ = parsePosition(baseGlyphX, font, positionX, direction="x", isBase=True)
                basePoint2, baseAngle2, _ = parsePosition(baseGlyphY, font, positionY, direction="y", isBase=True)
                intersection = _intersectAngles(basePoint1, baseAngle1, basePoint2, baseAngle2)
                if intersection is not None:
                    baseX, baseY = intersection

            # calculate the offset
            if not markFixedX:
                x += baseX - markX
            else:
                x += markX

            if not markFixedY:
                y += baseY - markY
            else:
                y += markY

        if not markFixedX:
            baseTransform = markTransformMap.get(baseGlyphX)
            if baseTransform:
                x += baseTransform[4] - advanceWidth

        if not markFixedY:
            baseTransform = markTransformMap.get(baseGlyphY)
            if baseTransform:
                y += baseTransform[5] - advanceHeight

    transformMatrix = (xx, xy, yx, yy, x, y)

    if flipX:
        bounds = font[markGlyph].bounds
        if bounds:
            minx, miny, maxx, maxy = bounds
            bt = Transform(*transformMatrix)
            minx, miny = bt.transformPoint((minx, miny))
            maxx, maxy = bt.transformPoint((maxx, maxy))
            t = Transform()
            t = t.translate(0, miny)
            t = t.scale(1, -1)
            t = t.translate(0, -maxy)
            t = t.transform(bt)
            transformMatrix = t[:]

    if flipY:
        bounds = font[markGlyph].bounds
        if bounds:
            minx, miny, maxx, maxy = bounds
            bt = Transform(*transformMatrix)
            minx, miny = bt.transformPoint((minx, miny))
            maxx, maxy = bt.transformPoint((maxx, maxy))
            t = Transform()
            t = t.translate(minx, 0)
            t = t.scale(-1, 1)
            t = t.translate(-maxx, 0)
            t = t.transform(bt)
            transformMatrix = t[:]
    return markGlyph, transformMatrix
示例#12
0
 def test_transform(self):
     t = Transform(2, 0, 0, 3, 1, 6)
     assert t.transform((4, 3, 2, 1, 5, 6)) == Transform(8, 9, 4, 3, 11, 24)