Esempio n. 1
0
    def expandSegment(self, cp, segment):
        """Expands the Segment instance. It may contain multiple quadratics.
        Split into cubics and lines."""

        if len(segment) == 1:
            # Straight line.
            p1 = segment.points[-1]
            self._cubic.append(('lineTo', (p1.x, p1.y)))
            cp = p1

        elif len(segment) == 2:
            # Converts quadratic curve to cubic.
            p1, p2 = segment.points
            self.expandQuadratic2Cubic(cp.x, cp.y, p1.x, p1.y, p2.x, p2.y)
            cp = p2

        else:
            # Handles implied on-curve points.
            for n in range(len(segment)-1):
                p0 = cp # Previous oncurve.
                p1 = segment.points[n] # next offcurve.
                p2 = segment.points[n+1] # offcurve or last point.

                if n < len(segment) - 2:
                    # Implied point.
                    m = APoint((p1.x + (p2.x - p1.x) / 2, p1.y + (p2.y - p1.y) / 2), True)
                else:
                    # Last (oncurve) point.
                    m = p2

                self.expandQuadratic2Cubic(cp.x, cp.y, p1.x, p1.y, m.x, m.y)
                cp = m

        return cp
Esempio n. 2
0
    def _get_perpendicularMiddleLine(self):
        # Calculate the average middle from the projections
        mx = my = 0
        projectionLines = self.projectionLines
        count = len(projectionLines) * 2  # Avoid double division of average
        for p, projectedP in projectionLines:
            mx += p.x + projectedP.x
            my += p.y + projectedP.y

        #FIXME: I'm not sure if APoint (from apoint.py) is the correct object to use here:
        m = APoint(mx / count, my / count)

        # Now project this window middle points on the two lines again.
        pp0 = self.point.getProjectedPoint(m)
        pp1 = self.parent.getProjectedPoint(m)
        return pp0, pp1
Esempio n. 3
0
 def projectedOnLine(self, p):
     u"""Answer the point context pc projects on the line of self."""
     xy = pointProjectedOnLine(self.p.p, self.p1.p, p.p)
     return APoint(xy)
Esempio n. 4
0
    def _initialize(self):
        """Initializes the cached data, such as points, contours, components,
        segments and bounding box. """
        self._points = []

        # Same as self.points property with added 4 spacing points in TTF
        # style.
        self._points4 = []
        self._contours = []
        self._segments = []
        self._cubic = []
        self._boundingBox = None

        components = self.components
        coordinates = self.coordinates

        if coordinates or components:
            minX = minY = XXXL # Store bounding box as we process the coordinate.
            maxX = maxY = -XXXL
        else:
            minX = minY = maxX = maxY = 0

        for component in components:
            componentName = component.baseGlyph
            if componentName in self.font.keys():
                componentGlyph = self.font[componentName]
                self._cubic.append(('component', ((component.x, component.y), componentGlyph)))

                # Expand bounding box.
                cMinX, cMinY, cMaxX, cMaxY = componentGlyph.boundingBox
                minX = min(cMinX+component.x, minX)
                minY = min(cMinY+component.y, minY)
                maxX = max(cMaxX+component.x, maxX)
                maxY = max(cMaxY+component.y, maxY)

        flags = self.flags
        openContour = False
        openSegment = None
        currentOnCurve = None
        endPtsOfContours = set(self.endPtsOfContours)
        p0 = None

        for index, (x, y) in enumerate(coordinates):
            # Expand bounding box.
            minX = min(x, minX)
            maxX = max(x, maxX)
            minY = min(y, minY)
            maxY = max(y, maxY)

            # Create APoint, to store weakref to self and index for altering
            # the coordinate and onCurve.
            p = APoint((x, y), flags[index], self, index)
            self._points.append(p)

            if not openContour:
                # Also store as cubic command.
                self._cubic.append(('moveTo', (x, y)))
                p0 = p
                currentOnCurve = p
                openContour = []
                self._contours.append(openContour)

            openContour.append(p)

            if not openSegment:
                openSegment = ASegment()
                self._segments.append(openSegment)

            openSegment.append(p)

            # If there is an open segment, it may contain multiple
            # quadratics. Split into cubics.
            if index in endPtsOfContours and openContour:
                # End of contour.
                if openSegment:
                    if not p.onCurve:
                        openSegment.append(p0)

                    currentOnCurve = self.expandSegment(currentOnCurve, openSegment)
                self._cubic.append(('closePath', None))
                openContour = None
                openSegment = None

            elif p.onCurve:
                # Inside contour.
                currentOnCurve = self.expandSegment(currentOnCurve, openSegment)
                openSegment = None

        # Add 4 spacing points, as default in TTF. No index, as they cannot be
        # written back. Instead, for writing, use self.leftMargin,
        # self.rightMargin and self.width.
        self._points4 = self._points[:] + [
            APoint((minX, 0), glyph=self),
            APoint((0, minY), glyph=self),
            APoint((maxX, 0), glyph=self),
            APoint((0, maxY), glyph=self)
        ]

        self._boundingBox = (minX, minY, maxX, maxY)
        self.dirty = False # All cleaned up.
Esempio n. 5
0
    def _initialize(self):
        u"""Initializes the cached data, such as self.points, self.contour,
        self.components and self.path, as side effect of drawing the path image.

        TODO: Separate path creation from initialize, so we no longer need self.context here.
        """

        self._points = []
        self._points4 = [
        ]  # Same as self.points property with added 4 spacing points in TTF style.
        self._contours = []
        self._segments = []
        self._boundingBox = None
        components = self.components

        coordinates = self.coordinates  # Get list from the font.
        flags = self.flags
        endPtsOfContours = set(self.endPtsOfContours)
        openContour = False
        openSegment = None
        currentOnCurve = None
        p0 = None

        minX = minY = sys.maxsize  # Store bounding box as we process the coordinate.
        maxX = maxY = -sys.maxsize

        if coordinates or components:
            self._path = self.context.newPath()

        for component in components:
            componentName = component.baseGlyph
            if componentName in self.font.keys():
                componentPath = self.font[componentName].path
                componentPath.transform((1, 0, 0, 1, component.x, component.y))
                self._path.appendPath(componentPath)
                componentPath.transform(
                    (1, 0, 0, 1, -component.x, -component.y))

        for index, (x, y) in enumerate(coordinates):
            minX = min(x, minX)
            maxX = max(x, maxX)
            minY = min(y, minY)
            maxY = max(y, maxY)

            # Create APoint, to store weakref to self and index for altering the coordinate and onCurve
            p = APoint((x, y), flags[index], self, index)
            self._points.append(p)

            if not openContour:
                assert self._path is not None
                self._path.moveTo((x, y))
                p0 = p
                currentOnCurve = p
                openContour = []
                self._contours.append(openContour)

            openContour.append(p)

            if not openSegment:
                openSegment = ASegment()
                self._segments.append(openSegment)

            openSegment.append(p)

            # If there is an open segment, it may contain multiple
            # quadratics. Split into cubics.

            if index in endPtsOfContours and openContour:
                # End of contour.
                if openSegment:
                    if not p.onCurve:
                        openSegment.append(p0)

                    currentOnCurve = self._drawSegment(currentOnCurve,
                                                       openSegment, self._path)

                self._path.closePath()
                openContour = None
                openSegment = None

            elif p.onCurve:
                # Inside contour.
                currentOnCurve = self._drawSegment(currentOnCurve, openSegment,
                                                   self._path)
                openSegment = None

        # Add 4 spacing points, as default in TTF. No index, as they cannot be written back.
        # Instead, for writing, use self.leftMargin, self.rightMargin and self.width.
        self._points4 = self._points[:] + [
            APoint((minX, 0), glyph=self),
            APoint((0, minY), glyph=self),
            APoint((maxX, 0), glyph=self),
            APoint((0, maxY), glyph=self)
        ]
        self._boundingBox = (minX, minY, maxX, maxY)
        self.dirty = False  # All cleaned up.