Beispiel #1
0
def draw(layer, instance, pen):
    pen = PointToSegmentPen(pen)

    for path in layer.paths:
        nodes = list(path.nodes)

        pen.beginPath()
        if nodes:
            if not path.closed:
                node = nodes.pop(0)
                assert node.type == "line", "Open path starts with off-curve points"
                pen.addPoint(tuple(node.position), segmentType="move")
            else:
                # In Glyphs.app, the starting node of a closed contour is always
                # stored at the end of the nodes list.
                nodes.insert(0, nodes.pop())
            for node in nodes:
                node_type = node.type
                if node_type not in ["line", "curve", "qcurve"]:
                    node_type = None
                pen.addPoint(tuple(node.position), segmentType=node_type, smooth=node.smooth)
        pen.endPath();

    for component in layer.components:
        componentLayer = getLayer(component.component, instance)
        transform = component.transform.value
        componentPen = pen.pen
        if transform != DEFAULT_TRANSFORM:
            componentPen = TransformPen(pen.pen, transform)
            xx, xy, yx, yy = transform[:4]
            if xx * yy - xy * yx < 0:
                componentPen = ReverseContourPen(componentPen)
        draw(componentLayer, instance, componentPen)

    return pen.pen
Beispiel #2
0
 def test_open(self):
     pen = _TestSegmentPen()
     ppen = PointToSegmentPen(pen)
     ppen.beginPath()
     ppen.addPoint((10, 10), "move")
     ppen.addPoint((10, 20), "line")
     ppen.endPath()
     self.assertEqual("10 10 moveto 10 20 lineto endpath", repr(pen))
Beispiel #3
0
 def test_quad_onlyOffCurvePoints(self):
     pen = _TestSegmentPen()
     ppen = PointToSegmentPen(pen)
     ppen.beginPath()
     ppen.addPoint((10, 10))
     ppen.addPoint((10, 40))
     ppen.addPoint((40, 40))
     ppen.endPath()
     self.assertEqual("10 10 10 40 40 40 None qcurveto closepath", repr(pen))
Beispiel #4
0
 def test_quad(self):
     pen = _TestSegmentPen()
     ppen = PointToSegmentPen(pen)
     ppen.beginPath(identifier='foo')
     ppen.addPoint((10, 10), "line")
     ppen.addPoint((10, 40))
     ppen.addPoint((40, 40))
     ppen.addPoint((10, 40), "qcurve")
     ppen.endPath()
     self.assertEqual("10 10 moveto 10 40 40 40 10 40 qcurveto closepath", repr(pen))
Beispiel #5
0
 def test_cubic(self):
     pen = _TestSegmentPen()
     ppen = PointToSegmentPen(pen)
     ppen.beginPath()
     ppen.addPoint((10, 10), "line")
     ppen.addPoint((10, 20))
     ppen.addPoint((20, 20))
     ppen.addPoint((20, 40), "curve")
     ppen.endPath()
     self.assertEqual("10 10 moveto 10 20 20 20 20 40 curveto closepath", repr(pen))
Beispiel #6
0
 def test_roundTrip1(self):
     tpen = _TestPointPen()
     ppen = PointToSegmentPen(SegmentToPointPen(tpen))
     ppen.beginPath()
     ppen.addPoint((10, 10), "line")
     ppen.addPoint((10, 20))
     ppen.addPoint((20, 20))
     ppen.addPoint((20, 40), "curve")
     ppen.endPath()
     self.assertEqual("beginPath() addPoint((10, 10), segmentType='line') addPoint((10, 20)) "
                      "addPoint((20, 20)) addPoint((20, 40), segmentType='curve') endPath()",
                      repr(tpen))
Beispiel #7
0
 def test_closed_outputImpliedClosingLine(self):
     tpen = _TestSegmentPen()
     ppen = PointToSegmentPen(tpen, outputImpliedClosingLine=True)
     ppen.beginPath()
     ppen.addPoint((10, 10), "line")
     ppen.addPoint((10, 20), "line")
     ppen.addPoint((20, 20), "line")
     ppen.endPath()
     self.assertEqual(
         "10 10 moveto "
         "10 20 lineto "
         "20 20 lineto "
         "10 10 lineto "  # explicit closing line
         "closepath",
         repr(tpen))
Beispiel #8
0
 def test_roundTrip2(self):
     tpen = _TestPointPen()
     ppen = PointToSegmentPen(SegmentToPointPen(tpen))
     ppen.beginPath()
     ppen.addPoint((0, 651), segmentType="line")
     ppen.addPoint((0, 101), segmentType="line")
     ppen.addPoint((0, 101), segmentType="line")
     ppen.addPoint((0, 651), segmentType="line")
     ppen.endPath()
     self.assertEqual(
         "beginPath() "
         "addPoint((0, 651), segmentType='line') "
         "addPoint((0, 101), segmentType='line') "
         "addPoint((0, 101), segmentType='line') "
         "addPoint((0, 651), segmentType='line') "
         "endPath()", repr(tpen))
Beispiel #9
0
 def draw(self, pen):
     ppen = PointToSegmentPen(pen)
     startIndex = 0
     points = self.getPoints()
     for endIndex in self.contours:
         lastTag = self.tags[endIndex]
         endIndex += 1
         contourTags = self.tags[startIndex:endIndex]
         contourPoints = points[startIndex:endIndex]
         ppen.beginPath()
         for tag, (x, y) in zip(contourTags, contourPoints):
             if tag == FT_CURVE_TAG_ON:
                 segmentType = segmentTypes[lastTag]
             else:
                 segmentType = None
             ppen.addPoint((x, y), segmentType=segmentType)
             lastTag = tag
         ppen.endPath()
         startIndex = endIndex
Beispiel #10
0
 def test_closed_line_overlapping_start_end_points(self):
     # Test case from https://github.com/googlefonts/fontmake/issues/572.
     tpen = _TestSegmentPen()
     ppen = PointToSegmentPen(tpen, outputImpliedClosingLine=False)
     # The last oncurve point on this closed contour is a "line" segment and has
     # same coordinates as the starting point.
     ppen.beginPath()
     ppen.addPoint((0, 651), segmentType="line")
     ppen.addPoint((0, 101), segmentType="line")
     ppen.addPoint((0, 101), segmentType="line")
     ppen.addPoint((0, 651), segmentType="line")
     ppen.endPath()
     # Check that we always output an explicit 'lineTo' segment at the end,
     # regardless of the value of 'outputImpliedClosingLine', to disambiguate
     # the duplicate point from the implied closing line.
     self.assertEqual(
         "0 651 moveto "
         "0 101 lineto "
         "0 101 lineto "
         "0 651 lineto "
         "0 651 lineto "
         "closepath", repr(tpen))