Created
March 5, 2021 15:50
-
-
Save connordavenport/c80442d4c4eeac238b485872c474ac03 to your computer and use it in GitHub Desktop.
A startup script that adds interpolate() functions to RContour RSegment objects. There is also a faux RSegment.copy() function.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from fontParts.base.errors import FontPartsError | |
from fontPens.digestPointPen import DigestPointStructurePen | |
def isStrictCompatible(path1,path2): | |
# check interpolation compatibility | |
if type(path1).__name__.split(".")[-1] == "RSegment": | |
if path1.type == path2.type: | |
return True | |
else: | |
return False | |
else: | |
p1Pen = DigestPointStructurePen() | |
path1.drawPoints(p1Pen) | |
p1Data = p1Pen.getDigest() | |
p2Pen = DigestPointStructurePen() | |
path2.drawPoints(p2Pen) | |
p2Data = p2Pen.getDigest() | |
if p2Data == p1Data: | |
return True | |
else: | |
return False | |
def interpolatePoints(a,b,v): | |
# interpolate points | |
x = a[0] + v * (b[0] - a[0]) | |
y = a[1] + v * (b[1] - a[1]) | |
return (x,y) | |
def addLastPoint(segment): | |
# This adds the extra point to segment.points | |
segmentPoints = [] | |
allSegs = [seg for seg in segment.contour.segments] | |
segmentPoints.append(allSegs[segment.index-1][-1]) | |
for selPoint in segment.points: | |
segmentPoints.append(selPoint) | |
return segmentPoints | |
def copySegment(self): | |
# This adds a faux copy function to a segment | |
tempGlyph = RGlyph() | |
points = addLastPoint(self) | |
if len(points) == 4: | |
pen = tempGlyph.getPen() | |
pen.moveTo((points[0].x,points[0].y)) | |
if self.type == "line": | |
pen.lineTo((points[1].x,points[1].y)) | |
else: | |
pen.curveTo((points[1].x,points[1].y),(points[2].x,points[2].y),(points[3].x,points[3].y)) | |
pen.endPath() | |
return tempGlyph.contours[-1] | |
def interpolateConSeg(self,factor,otherConSeg): | |
# Interpolate a contour or segment | |
# Segment interpolation is very hacky | |
if type(self).__name__.split(".")[-1] == "RSegment": | |
objType = "RSeg" | |
else: | |
objType = "RCon" | |
glyph = self.glyph | |
glyph.prepareUndo() | |
if self.isCompatible(otherConSeg): | |
if isStrictCompatible(self,otherConSeg): | |
pointPen = glyph.getPointPen() | |
copied = self.copy() | |
if objType == "RSeg": | |
conPoints = addLastPoint(self) | |
otherConSegPs = addLastPoint(otherConSeg) | |
else: | |
conPoints = self.points | |
otherConSegPs = otherConSeg.points | |
for i, point in enumerate(conPoints): | |
ips = interpolatePoints((point.x,point.y),(otherConSegPs[i].x,otherConSegPs[i].y),factor) | |
copied.points[i].x = round(ips[0]) | |
copied.points[i].y = round(ips[1]) | |
copied.drawPoints(pointPen) | |
else: | |
raise FontPartsError | |
glyph.performUndo() | |
# ------------------------------------------------------------------ # | |
from mojo.roboFont import RContour | |
from lib.fontObjects.fontPartsWrappers import RSegment | |
RSegment.copy = copySegment | |
RContour.interpolate = interpolateConSeg | |
RSegment.interpolate = interpolateConSeg | |
# ------------------------------------------------------------------ # |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment