Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding SplittedPen #44

Open
typemytype opened this issue Mar 26, 2024 · 0 comments
Open

adding SplittedPen #44

typemytype opened this issue Mar 26, 2024 · 0 comments
Assignees

Comments

@typemytype
Copy link
Member

similar to FlattenPen but splits the curve segment into small curves

from fontTools.misc.bezierTools import calcCubicArcLength, splitCubicAtT
from fontTools.pens.basePen import BasePen

from fontPens.penTools import distance, interpolatePoint


class SplittedPen(BasePen):
    
    def __init__(self, otherPen, approximateSegmentLength=5):
        self.approximateSegmentLength = approximateSegmentLength
        super().__init__({})
        self.otherPen = otherPen
    
    def _moveTo(self, pt):
        self.otherPen.moveTo(pt)
        self.currentPt = pt
        self.firstPt = pt
    
    def _lineTo(self, pt):                
        d = distance(self.currentPt, pt)
        maxSteps = int(round(d / self.approximateSegmentLength))
        if maxSteps < 1:
            self.otherPen.lineTo(pt)
            self.currentPt = pt
            return
        step = 1.0 / maxSteps
        for factor in range(1, maxSteps + 1):
            self.otherPen.lineTo(interpolatePoint(self.currentPt, pt, factor * step))
        self.currentPt = pt
        
    def _curveToOne(self, pt1, pt2, pt3):
        falseCurve = (pt1 == self.currentPt) and (pt2 == pt3)
        if falseCurve:
            self._lineTo(pt3)
            return
        
        maxSteps = int(round(calcCubicArcLength(self.currentPt, pt1, pt2, pt3) / self.approximateSegmentLength))
        if maxSteps < 1:
            self.otherPen.lineTo(pt3)
            self.currentPt = pt3
            return
        
        tValues = [i / maxSteps for i in range(1, maxSteps)]
        for curve in splitCubicAtT(self.currentPt, pt1, pt2, pt3, *tValues):
            self.otherPen.curveTo(*curve[1:])

        self.currentPt = pt3
    
    def _closePath(self):
        self.lineTo(self.firstPt)
        self.otherPen.closePath()

    def _endPath(self):
        self.otherPen.endPath()

    def addComponent(self, glyphName, transformation):
        self.otherPen.addComponent(glyphName, transformation) 
@typemytype typemytype self-assigned this Mar 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant