Beispiel #1
0
    def test_Slant(self, font, origin):
        filter_ = TransformationsFilter(Slant=45, Origin=origin)
        assert filter_(font)

        origin_height = filter_.get_origin_height(font, origin)

        a = font["a"]
        assert isclose(a[0][0].x, -origin_height)
        assert a[0][0].y == 0
Beispiel #2
0
    def test_ScaleY(self, font, origin):
        percent = 50
        filter_ = TransformationsFilter(ScaleY=percent, Origin=origin)
        assert filter_(font)

        factor = percent/100
        origin_height = filter_.get_origin_height(font, origin)
        bottom = origin_height * factor
        top = bottom + 300 * factor

        a = font["a"]
        # only y coords change
        assert (a[0][0].x, a[0][0].y) == (0, bottom)
        assert (a[0][2].x, a[0][2].y) == (300, top)
    def test_composite_glyphs(self, font):
        filter_ = TransformationsFilter(OffsetX=-10,
                                        OffsetY=51,
                                        ScaleX=50,
                                        ScaleY=50,
                                        exclude={"c"})
        assert filter_(font)

        b = font["b"]
        # component 'a' #1 was not transformed, because the base glyph was already
        # transformed, and the component's own transformation is identity
        assert b.components[0].transformation == (1, 0, 0, 1, 0, 0)
        # component 'c' was transformed, because base glyph was not included
        assert b.components[1].transformation == (0.5, 0, 0, 0.5, -10, 51)
        # component 'a' #2 was partly transformed: the base glyph was transformed, but
        # the component's original transformation was not identity; thus
        # it was modified to compensate for the transformation already applied to
        # the base glyph (scale stays same, offsets are scaled)
        assert b.components[2].transformation == (1, 0, 0, 1, 5, -5)

        d = font["d"]
        # component 'b' was transformed as well as its base glyph, because
        # its original transform had a scale, so it was necessary to
        # compensate for the transformation applied on the base glyph
        assert d.components[0].transformation == (1, 0, 0, -1, 0, 102)
Beispiel #4
0
    def test_ScaleX(self, font, origin):
        # different Origin heights should not affect horizontal scale
        filter_ = TransformationsFilter(ScaleX=50, Origin=origin)
        assert filter_(font)

        a = font["a"]
        assert (a[0][0].x, a[0][0].y) == (0, 0)
        assert (a[0][2].x, a[0][2].y) == (150, 300)
Beispiel #5
0
    def test_OffsetXY(self, font):
        filter_ = TransformationsFilter(OffsetX=-10, OffsetY=51)
        assert filter_(font)

        a = font["a"]
        assert (a[0][0].x, a[0][0].y) == (-10, 51)
        assert (a.anchors[1].x, a.anchors[1].y) == (90, -149)

        assert font["b"].components[0].transformation[-2:] == (0, 0)
Beispiel #6
0
    def test_OffsetX(self, font):
        filter_ = TransformationsFilter(OffsetX=-10)
        assert filter_(font)

        a = font["a"]
        assert (a[0][0].x, a[0][0].y) == (-10, 0)
        assert (a.anchors[1].x, a.anchors[1].y) == (90, -200)

        # base glyph was already transformed, component didn't change
        assert font["b"].components[0].transformation[-2:] == (0, 0)
Beispiel #7
0
    def test_composite_glyphs(self, font):
        filter_ = TransformationsFilter(
            OffsetX=-10, OffsetY=51, ScaleX=50, ScaleY=50, exclude={'c'})
        assert filter_(font)

        b = font["b"]
        # component 'a' was not transformed, because it doesn't have a scale
        # or skew and the base glyph was already included
        assert b.components[0].transformation == (1, 0, 0, 1, 0, 0)
        # component 'c' was transformed, because base glyph was not included
        assert b.components[1].transformation == (.5, 0, 0, .5, -10, 51)

        d = font["d"]
        # component 'b' was transformed as well as its base glyph, because
        # its original transform had a scale, so it was necessary to
        # compensate for the transformation applied on the base glyph
        assert d.components[0].transformation == (1, 0, 0, -1, 0, 102)
Beispiel #8
0
 def test_Identity(self, font):
     filter_ = TransformationsFilter()
     assert not filter_(font)
Beispiel #9
0
 def test_empty_glyph(self, font):
     filter_ = TransformationsFilter(OffsetY=51, include={'space'})
     assert not filter_(font)
Beispiel #10
0
 def test_invalid_origin_value(self):
     with pytest.raises(ValueError) as excinfo:
         TransformationsFilter(Origin=5)
     excinfo.match("is not a valid Origin")
Beispiel #11
0
def makeSlanted(options):
    font = makeDesktop(options, False)

    exclude = [f"u{i:X}" for i in range(0x1EE00, 0x1EEFF + 1)]
    exclude += [
        "exclam",
        "period",
        "guillemotleft",
        "guillemotright",
        "braceleft",
        "bar",
        "braceright",
        "bracketleft",
        "bracketright",
        "parenleft",
        "parenright",
        "slash",
        "backslash",
        "brokenbar",
        "uni061F",
        "dot.1",
        "dot.2",
    ]

    skew = TransformationsFilter(Slant=-options.slant, exclude=exclude)
    skew(font)

    # fix metadata
    info = font.info
    info.italicAngle = options.slant
    info.postscriptFullName += " Slanted"
    if info.postscriptWeightName == "Bold":
        info.postscriptFontName = info.postscriptFontName.replace(
            "Bold", "BoldSlanted")
        info.styleName = "Bold Slanted"
        info.styleMapFamilyName = info.familyName
        info.styleMapStyleName = "bold italic"
    else:
        info.postscriptFontName = info.postscriptFontName.replace(
            "Regular", "Slanted")
        info.styleName = "Slanted"
        info.styleMapFamilyName = info.familyName
        info.styleMapStyleName = "italic"

    matrix = skew.context.matrix
    mergeLatin(font)
    fea = font.features.text
    for block in fea.statements:
        if isinstance(block, (ast.LookupBlock, ast.FeatureBlock)):
            for st in block.statements:
                if isinstance(
                        st,
                    (ast.MarkMarkPosStatement, ast.MarkBasePosStatement)):
                    st.marks = [(transformAnchor(a, matrix), m)
                                for a, m in st.marks]
                elif isinstance(st, ast.MarkClassDefinition):
                    st.anchor = transformAnchor(st.anchor, matrix)
                elif isinstance(st, ast.CursivePosStatement):
                    st.entryAnchor = transformAnchor(st.entryAnchor, matrix)
                    st.exitAnchor = transformAnchor(st.exitAnchor, matrix)

    otf = generateFont(options, font)
    otf.save(options.output)