Skip to content

Instantly share code, notes, and snippets.

@connordavenport
Created March 5, 2021 15:50
Show Gist options
  • Save connordavenport/c80442d4c4eeac238b485872c474ac03 to your computer and use it in GitHub Desktop.
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.
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