def test_out_of_range_transform_decomposed(self):
        componentName = "a"
        glyphSet = {}
        pen = TTGlyphPointPen(glyphSet)

        pen.beginPath()
        pen.addPoint((0, 0), "line")
        pen.addPoint((0, 1), "line")
        pen.addPoint((1, 0), "line")
        pen.endPath()
        glyphSet[componentName] = _TestGlyph(pen.glyph())

        pen.addComponent(componentName, (3, 0, 0, 2, 0, 0))
        pen.addComponent(componentName, (1, 0, 0, 1, -1, 2))
        pen.addComponent(componentName, (2, 0, 0, -3, 0, 0))
        compositeGlyph = pen.glyph()

        pen.beginPath()
        pen.addPoint((0, 0), "line")
        pen.addPoint((0, 2), "line")
        pen.addPoint((3, 0), "line")
        pen.endPath()
        pen.beginPath()
        pen.addPoint((-1, 2), "line")
        pen.addPoint((-1, 3), "line")
        pen.addPoint((0, 2), "line")
        pen.endPath()
        pen.beginPath()
        pen.addPoint((0, 0), "line")
        pen.addPoint((0, -3), "line")
        pen.addPoint((2, 0), "line")
        pen.endPath()
        expectedGlyph = pen.glyph()

        assert expectedGlyph == compositeGlyph
    def test_scaled_component_bounds(self):
        glyphSet = {}

        pen = TTGlyphPointPen(glyphSet)
        pen.beginPath()
        pen.addPoint((-231, 939), "line")
        pen.addPoint((-55, 939), "line")
        pen.addPoint((-55, 745), "line")
        pen.addPoint((-231, 745), "line")
        pen.endPath()
        glyphSet["gravecomb"] = pen.glyph()

        pen = TTGlyphPointPen(glyphSet)
        pen.beginPath()
        pen.addPoint((-278, 939), "line")
        pen.addPoint((8, 939), "line")
        pen.addPoint((8, 745), "line")
        pen.addPoint((-278, 745), "line")
        pen.endPath()
        glyphSet["circumflexcomb"] = pen.glyph()

        pen = TTGlyphPointPen(glyphSet)
        pen.addComponent("circumflexcomb", (1, 0, 0, 1, 0, 0))
        pen.addComponent("gravecomb", (0.9, 0, 0, 0.9, 198, 180))
        glyphSet["uni0302_uni0300"] = uni0302_uni0300 = pen.glyph()

        uni0302_uni0300.recalcBounds(glyphSet)
        self.assertGlyphBoundsEqual(uni0302_uni0300, (-278, 745, 148, 1025))
    def test_glyph_decomposes(self):
        componentName = "a"
        glyphSet = {}
        pen = TTGlyphPointPen(glyphSet)

        pen.beginPath()
        pen.addPoint((0, 0), "line")
        pen.addPoint((0, 1), "line")
        pen.addPoint((1, 0), "line")
        pen.endPath()
        glyphSet[componentName] = _TestGlyph(pen.glyph())

        pen.beginPath()
        pen.addPoint((0, 0), "line")
        pen.addPoint((0, 1), "line")
        pen.addPoint((1, 0), "line")
        pen.endPath()
        pen.addComponent(componentName, (1, 0, 0, 1, 2, 0))
        pen.addComponent("missing", (1, 0, 0, 1, 0, 0))  # skipped
        compositeGlyph = pen.glyph()

        pen.beginPath()
        pen.addPoint((0, 0), "line")
        pen.addPoint((0, 1), "line")
        pen.addPoint((1, 0), "line")
        pen.endPath()
        pen.beginPath()
        pen.addPoint((2, 0), "line")
        pen.addPoint((2, 1), "line")
        pen.addPoint((3, 0), "line")
        pen.endPath()
        plainGlyph = pen.glyph()

        assert plainGlyph == compositeGlyph
    def test_no_handle_overflowing_transform(self):
        componentName = "a"
        glyphSet = {}
        pen = TTGlyphPointPen(glyphSet, handleOverflowingTransforms=False)

        pen.beginPath()
        pen.addPoint((0, 0), "line")
        pen.addPoint((0, 1), "line")
        pen.addPoint((1, 0), "line")
        pen.endPath()
        baseGlyph = pen.glyph()
        glyphSet[componentName] = _TestGlyph(baseGlyph)

        pen.addComponent(componentName, (3, 0, 0, 1, 0, 0))
        compositeGlyph = pen.glyph()

        assert compositeGlyph.components[0].transform == ((3, 0), (0, 1))

        with pytest.raises(struct.error):
            compositeGlyph.compile({"a": baseGlyph})
    def test_round_float_coordinates_and_component_offsets(self):
        glyphSet = {}
        pen = TTGlyphPointPen(glyphSet)

        pen.beginPath()
        pen.addPoint((0, 0), "line")
        pen.addPoint((0, 1), "line")
        pen.addPoint((367.6, 0), "line")
        pen.endPath()
        simpleGlyph = pen.glyph()

        simpleGlyph.recalcBounds(glyphSet)
        self.assertGlyphBoundsEqual(simpleGlyph, (0, 0, 368, 1))

        componentName = "a"
        glyphSet[componentName] = simpleGlyph

        pen.addComponent(componentName, (1, 0, 0, 1, -86.4, 0))
        compositeGlyph = pen.glyph()

        compositeGlyph.recalcBounds(glyphSet)
        self.assertGlyphBoundsEqual(compositeGlyph, (-86, 0, 282, 1))
    def test_within_range_component_transform(self):
        componentName = "a"
        glyphSet = {}
        pen = TTGlyphPointPen(glyphSet)

        pen.beginPath()
        pen.addPoint((0, 0), "line")
        pen.addPoint((0, 1), "line")
        pen.addPoint((1, 0), "line")
        pen.endPath()
        glyphSet[componentName] = _TestGlyph(pen.glyph())

        pen.addComponent(componentName, (1.5, 0, 0, 1, 0, 0))
        pen.addComponent(componentName, (1, 0, 0, -1.5, 0, 0))
        compositeGlyph = pen.glyph()

        pen.addComponent(componentName, (1.5, 0, 0, 1, 0, 0))
        pen.addComponent(componentName, (1, 0, 0, -1.5, 0, 0))
        expectedGlyph = pen.glyph()

        assert expectedGlyph == compositeGlyph
    def test_clamp_to_almost_2_component_transform(self):
        componentName = "a"
        glyphSet = {}
        pen = TTGlyphPointPen(glyphSet)

        pen.beginPath()
        pen.addPoint((0, 0), "line")
        pen.addPoint((0, 1), "line")
        pen.addPoint((1, 0), "line")
        pen.endPath()
        glyphSet[componentName] = _TestGlyph(pen.glyph())

        pen.addComponent(componentName, (1.99999, 0, 0, 1, 0, 0))
        pen.addComponent(componentName, (1, 2, 0, 1, 0, 0))
        pen.addComponent(componentName, (1, 0, 2, 1, 0, 0))
        pen.addComponent(componentName, (1, 0, 0, 2, 0, 0))
        pen.addComponent(componentName, (-2, 0, 0, -2, 0, 0))
        compositeGlyph = pen.glyph()

        almost2 = MAX_F2DOT14  # 0b1.11111111111111
        pen.addComponent(componentName, (almost2, 0, 0, 1, 0, 0))
        pen.addComponent(componentName, (1, almost2, 0, 1, 0, 0))
        pen.addComponent(componentName, (1, 0, almost2, 1, 0, 0))
        pen.addComponent(componentName, (1, 0, 0, almost2, 0, 0))
        pen.addComponent(componentName, (-2, 0, 0, -2, 0, 0))
        expectedGlyph = pen.glyph()

        assert expectedGlyph == compositeGlyph