예제 #1
0
 def test_roundTrip1(self):
     spen = _TestSegmentPen()
     pen = SegmentToPointPen(PointToSegmentPen(spen))
     pen.moveTo((10, 10))
     pen.lineTo((10, 20))
     pen.lineTo((20, 20))
     pen.closePath()
     self.assertEqual("10 10 moveto 10 20 lineto 20 20 lineto closepath", repr(spen))
예제 #2
0
 def test_roundTrip2(self):
     spen = _TestSegmentPen()
     pen = SegmentToPointPen(PointToSegmentPen(spen))
     pen.qCurveTo((10, 20), (20, 20), (20, 10), (10, 10), None)
     pen.closePath()
     pen.addComponent('base', [1, 0, 0, 1, 0, 0])
     self.assertEqual(
         "10 20 20 20 20 10 10 10 None qcurveto closepath "
         "'base' [1, 0, 0, 1, 0, 0] addcomponent", repr(spen))
예제 #3
0
 def test_cubic(self):
     tpen = _TestPointPen()
     pen = SegmentToPointPen(tpen)
     pen.moveTo((10, 10))
     pen.curveTo((10, 20), (20, 20), (20, 10))
     pen.closePath()
     self.assertEqual("beginPath() addPoint((10, 10), segmentType='line') "
                      "addPoint((10, 20)) addPoint((20, 20)) addPoint((20, 10), "
                      "segmentType='curve') endPath()", repr(tpen))
예제 #4
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))
예제 #5
0
 def test_move(self):
     tpen = _TestPointPen()
     pen = SegmentToPointPen(tpen)
     pen.moveTo((10, 10))
     pen.endPath()
     self.assertEqual("beginPath() addPoint((10, 10), segmentType='move') endPath()",
                      repr(tpen))
예제 #6
0
 def test_quad2(self):
     tpen = _TestPointPen()
     pen = SegmentToPointPen(tpen)
     pen.qCurveTo((10, 20), (20, 20), (20, 10), (10, 10), None)
     pen.closePath()
     self.assertEqual(
         "beginPath() addPoint((10, 20)) addPoint((20, 20)) "
         "addPoint((20, 10)) addPoint((10, 10)) endPath()", repr(tpen))
예제 #7
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))
예제 #8
0
 def getReversePen(self):
     adapterPen = PointToSegmentPen(self.otherPen)
     reversePen = ReverseContourPointPen(adapterPen)
     return SegmentToPointPen(reversePen)
예제 #9
0
 def getPen(self) -> AbstractPen:
     """Returns a pen for others to draw into self."""
     pen = SegmentToPointPen(self.getPointPen())
     return pen
예제 #10
0
def test(glyphsets, glyphs=None, names=None):

    if names is None:
        names = glyphsets
    if glyphs is None:
        glyphs = glyphsets[0].keys()

    hist = []
    problems = OrderedDict()

    def add_problem(glyphname, problem):
        problems.setdefault(glyphname, []).append(problem)

    for glyph_name in glyphs:
        # print()
        # print(glyph_name)

        try:
            allVectors = []
            allNodeTypes = []
            allContourIsomorphisms = []
            for glyphset, name in zip(glyphsets, names):
                # print('.', end='')
                if glyph_name not in glyphset:
                    add_problem(glyph_name, {
                        "type": "missing",
                        "master": name
                    })
                    continue
                glyph = glyphset[glyph_name]

                perContourPen = PerContourOrComponentPen(RecordingPen,
                                                         glyphset=glyphset)
                try:
                    glyph.draw(perContourPen, outputImpliedClosingLine=True)
                except TypeError:
                    glyph.draw(perContourPen)
                contourPens = perContourPen.value
                del perContourPen

                contourVectors = []
                contourIsomorphisms = []
                nodeTypes = []
                allNodeTypes.append(nodeTypes)
                allVectors.append(contourVectors)
                allContourIsomorphisms.append(contourIsomorphisms)
                for ix, contour in enumerate(contourPens):

                    nodeVecs = tuple(instruction[0]
                                     for instruction in contour.value)
                    nodeTypes.append(nodeVecs)

                    stats = StatisticsPen(glyphset=glyphset)
                    try:
                        contour.replay(stats)
                    except OpenContourError as e:
                        add_problem(
                            glyph_name,
                            {
                                "master": name,
                                "contour": ix,
                                "type": "open_path"
                            },
                        )
                        continue
                    size = abs(stats.area)**0.5 * 0.5
                    vector = (
                        int(size),
                        int(stats.meanX),
                        int(stats.meanY),
                        int(stats.stddevX * 2),
                        int(stats.stddevY * 2),
                        int(stats.correlation * size),
                    )
                    contourVectors.append(vector)
                    # print(vector)

                    # Check starting point
                    if nodeVecs[0] == 'addComponent':
                        continue
                    assert nodeVecs[0] == 'moveTo'
                    assert nodeVecs[-1] in ('closePath', 'endPath')
                    points = RecordingPointPen()
                    converter = SegmentToPointPen(points, False)
                    contour.replay(converter)
                    # points.value is a list of pt,bool where bool is true if on-curve and false if off-curve;
                    # now check all rotations and mirror-rotations of the contour and build list of isomorphic
                    # possible starting points.
                    bits = 0
                    for pt, b in points.value:
                        bits = (bits << 1) | b
                    n = len(points.value)
                    mask = (1 << n) - 1
                    isomorphisms = []
                    contourIsomorphisms.append(isomorphisms)
                    for i in range(n):
                        b = ((bits << i) & mask) | ((bits >> (n - i)))
                        if b == bits:
                            isomorphisms.append(
                                _rot_list(
                                    [complex(*pt) for pt, bl in points.value],
                                    i))
                    # Add mirrored rotations
                    mirrored = list(reversed(points.value))
                    reversed_bits = 0
                    for pt, b in mirrored:
                        reversed_bits = (reversed_bits << 1) | b
                    for i in range(n):
                        b = ((reversed_bits << i) & mask) | ((reversed_bits >>
                                                              (n - i)))
                        if b == bits:
                            isomorphisms.append(
                                _rot_list(
                                    [complex(*pt) for pt, bl in mirrored], i))

            # Check each master against the next one in the list.
            for i, (m0,
                    m1) in enumerate(zip(allNodeTypes[:-1], allNodeTypes[1:])):
                if len(m0) != len(m1):
                    add_problem(
                        glyph_name,
                        {
                            "type": "path_count",
                            "master_1": names[i],
                            "master_2": names[i + 1],
                            "value_1": len(m0),
                            "value_2": len(m1),
                        },
                    )
                if m0 == m1:
                    continue
                for pathIx, (nodes1, nodes2) in enumerate(zip(m0, m1)):
                    if nodes1 == nodes2:
                        continue
                    if len(nodes1) != len(nodes2):
                        add_problem(
                            glyph_name,
                            {
                                "type": "node_count",
                                "path": pathIx,
                                "master_1": names[i],
                                "master_2": names[i + 1],
                                "value_1": len(nodes1),
                                "value_2": len(nodes2),
                            },
                        )
                        continue
                    for nodeIx, (n1, n2) in enumerate(zip(nodes1, nodes2)):
                        if n1 != n2:
                            add_problem(
                                glyph_name,
                                {
                                    "type": "node_incompatibility",
                                    "path": pathIx,
                                    "node": nodeIx,
                                    "master_1": names[i],
                                    "master_2": names[i + 1],
                                    "value_1": n1,
                                    "value_2": n2,
                                },
                            )
                            continue

            for i, (m0, m1) in enumerate(zip(allVectors[:-1], allVectors[1:])):
                if len(m0) != len(m1):
                    # We already reported this
                    continue
                if not m0:
                    continue
                costs = [[_vlen(_vdiff(v0, v1)) for v1 in m1] for v0 in m0]
                matching, matching_cost = min_cost_perfect_bipartite_matching(
                    costs)
                identity_matching = list(range(len(m0)))
                identity_cost = sum(costs[i][i] for i in range(len(m0)))
                if matching != identity_matching and matching_cost < identity_cost * .95:
                    add_problem(
                        glyph_name,
                        {
                            "type": "contour_order",
                            "master_1": names[i],
                            "master_2": names[i + 1],
                            "value_1": list(range(len(m0))),
                            "value_2": matching,
                        },
                    )
                    break

            for i, (m0, m1) in enumerate(
                    zip(allContourIsomorphisms[:-1],
                        allContourIsomorphisms[1:])):
                if len(m0) != len(m1):
                    # We already reported this
                    continue
                if not m0:
                    continue
                for contour0, contour1 in zip(m0, m1):
                    c0 = contour0[0]
                    costs = [
                        v for v in (_complex_vlen(_vdiff(c0, c1))
                                    for c1 in contour1)
                    ]
                    min_cost = min(costs)
                    first_cost = costs[0]
                    if min_cost < first_cost * .95:
                        add_problem(
                            glyph_name,
                            {
                                "type": "wrong_start_point",
                                "master_1": names[i],
                                "master_2": names[i + 1],
                            },
                        )

        except ValueError as e:
            add_problem(
                glyph_name,
                {
                    "type": "math_error",
                    "master": name,
                    "error": e
                },
            )
    return problems
예제 #11
0
 def drawPoints(pointPen):
     pen = SegmentToPointPen(pointPen)
     outline.draw(pen)
예제 #12
0
 def drawToPointPen(self, pen):
     self.drawToPen(SegmentToPointPen(pen))
예제 #13
0
 def getPen(self):
     pen = SegmentToPointPen(self.getPointPen())
     return pen
예제 #14
0
파일: glyph.py 프로젝트: bghryct/babelfont
 def getPen(self):
     from fontTools.pens.pointPen import SegmentToPointPen
     return SegmentToPointPen(self.getPointPen())
예제 #15
0
파일: utils.py 프로젝트: verbosus/fonttools
 def drawPoints(self, pointPen):
     """Use another PointPen to replay the glyph's outline commands,
     indirectly through an adapter.
     """
     pen = SegmentToPointPen(pointPen)
     self.draw(pen)
예제 #16
0
 def getPen(self):
     return SegmentToPointPen(self.getPointPen())
예제 #17
0
파일: utils.py 프로젝트: verbosus/fonttools
 def getPen(self):
     """Return a SegmentPen adapter that can 'draw' on this glyph."""
     return SegmentToPointPen(self._pen)
예제 #18
0
 def getPen(self):
     return SegmentToPointPen(self.outline)