Last active
March 7, 2023 22:45
-
-
Save colinmford/561756fcc7f51ca9210bce08f111377b to your computer and use it in GitHub Desktop.
This file contains 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 fontTools.misc.fixedTools import otRound | |
def findIntersection(p0, p1, p2, p3): | |
""" | |
Find the intersection of two segments given two selected points. | |
""" | |
# get the coordinates of the points | |
x0, y0 = p0.x, p0.y | |
x1, y1 = p1.x, p1.y | |
x2, y2 = p2.x, p2.y | |
x3, y3 = p3.x, p3.y | |
# calculate the denominator | |
denominator = (x0 - x1) * (y2 - y3) - (y0 - y1) * (x2 - x3) | |
# if the denominator is zero, the segments are parallel | |
if denominator == 0: | |
return None | |
# calculate the intersection | |
x = ((x0 * y1 - y0 * x1) * (x2 - x3) - (x0 - x1) * (x2 * y3 - y2 * x3)) / denominator | |
y = ((x0 * y1 - y0 * x1) * (y2 - y3) - (y0 - y1) * (x2 * y3 - y2 * x3)) / denominator | |
# return the intersection | |
return (otRound(x), otRound(y)) | |
def main(): | |
g = CurrentGlyph() | |
# set an undo point | |
with g.undo("Sharpen Corner"): | |
# hold change notifications while we're working | |
with g.holdChanges(): | |
# loop through contours | |
for c in g.contours: | |
removePoints = [] | |
# break c.selectedPoints list into pairs of two | |
for p1, p2 in zip(c.selectedPoints[::2], c.selectedPoints[1::2]): | |
# get the points before and after the selected points | |
p0 = c.points[(p1.index - 1) % len(c.points)] | |
p3 = c.points[(p2.index + 1) % len(c.points)] | |
# find the intersection of the segments | |
intersection = findIntersection(p0, p1, p2, p3) | |
if intersection: | |
# if intersection, move the selected points to the intersection and add point indexes between p1 and p2 to a list for removal | |
p1.x, p1.y = intersection | |
p2.x, p2.y = intersection | |
p1.smooth = False | |
p2.smooth = False | |
p1.selected = False | |
p2.selected = False | |
for i in range(p1.index, p2.index): | |
removePoints.append(i) | |
for p in sorted(removePoints, reverse=True): | |
# remove the points between the selected points | |
c.removePoint(p) | |
g.changed() | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment