Created
September 23, 2015 00:11
-
-
Save davelab6/16197d07388a636eac75 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 mojo.roboFont import * | |
from mojo.events import EditingTool, installTool | |
from AppKit import * | |
# Original script by Christian Robertson www.betatype.com | |
# RoboFont version by Travis Kochel www.tktype.com | |
# Some chunks by Frederik Berlaen www.robofont.com | |
# Crudely hacked together by Jackson Cavanaugh www.okaytype.com | |
# Instead of complaining you should help fix this shitty code | |
# Ted-Nudget version 0.4 | |
def getContourRange(cID,c): | |
start = c.bPoints[cID] | |
if c.GetContoursNumber() > cID: | |
end = len(g)-1 | |
else: | |
end = c.GetContourBegin(cID+1)-1 | |
return start,end | |
def getNextNode(nID,c): | |
numPoints = len(c.bPoints) - 1 | |
if nID >= numPoints: | |
nID = 0 | |
else: nID = nID + 1 | |
return c.bPoints[nID] | |
def getPrevNode(nID,c): | |
numPoints = len(c.bPoints) - 1 | |
if nID <= 0: | |
nID = numPoints | |
else: | |
nID = nID - 1 | |
return c.bPoints[nID] | |
def interpolateNode(nindex,g,c,offset): | |
n = c.bPoints[nindex] | |
nn = getNextNode(nindex,c) | |
pn = getPrevNode(nindex,c) | |
#Get change in x,y next and prev nodes | |
xDiffNn = abs(n.anchor[0] - nn.anchor[0]) | |
yDiffNn = abs(n.anchor[1] - nn.anchor[1]) | |
xDiffPn = abs(n.anchor[0] - pn.anchor[0]) | |
yDiffPn = abs(n.anchor[1] - pn.anchor[1]) | |
#get Ratio of BCP to x,y change next/prev node | |
if xDiffNn != 0: | |
xRatioNout = float(n.bcpOut[0]) / float(xDiffNn) | |
xRatioNn = float(nn.bcpIn[0]) / float(xDiffNn) | |
else: | |
xRatioNout = 0 | |
xRatioNn = 0 | |
if yDiffNn != 0: | |
yRatioNout = float(n.bcpOut[1]) / float(yDiffNn) | |
yRatioNn = float(nn.bcpIn[1]) / float(yDiffNn) | |
else: | |
yRatioNout = 0 | |
yRatioNn = 0 | |
if xDiffPn != 0: | |
xRatioNin = float(n.bcpIn[0]) / float(xDiffPn) | |
xRatioPn = float(pn.bcpOut[0]) / float(xDiffPn) | |
else: | |
xRatioNin = 0 | |
xRatioPn = 0 | |
if yDiffPn != 0: | |
yRatioNin = float(n.bcpIn[1]) / float(yDiffPn) | |
yRatioPn = float(pn.bcpOut[1]) / float(yDiffPn) | |
else: | |
yRatioNin = 0 | |
yRatioPn = 0 | |
#move the selected anchor | |
n.move(offset) | |
#get new diff | |
xDiffNnNew = abs(n.anchor[0] - nn.anchor[0]) | |
yDiffNnNew = abs(n.anchor[1] - nn.anchor[1]) | |
xDiffPnNew = abs(n.anchor[0] - pn.anchor[0]) | |
yDiffPnNew = abs(n.anchor[1] - pn.anchor[1]) | |
# find coordinates of new bcps based on ratio | |
if xDiffNnNew == 0: | |
xNoutNew = xRatioNout | |
xNnNew = xRatioNn | |
else: | |
xNoutNew = xRatioNout * xDiffNnNew | |
xNnNew = xRatioNn * xDiffNnNew | |
if yDiffNnNew == 0: | |
yNoutNew = yRatioNout | |
yNnNew = yRatioNn | |
else: | |
yNoutNew = yRatioNout * yDiffNnNew | |
yNnNew = yRatioNn * yDiffNnNew | |
if xDiffPnNew == 0: | |
xNinNew = xRatioNin | |
xPnNew = xRatioPn | |
else: | |
xNinNew = xRatioNin * xDiffPnNew | |
xPnNew = xRatioPn * xDiffPnNew | |
if yDiffPnNew == 0: | |
yNinNew = yRatioNin | |
yPnNew = yRatioPn | |
else: | |
yNinNew = yRatioNin * yDiffPnNew | |
yPnNew = yRatioPn * yDiffPnNew | |
#assign new bcp coordinates | |
n.bcpIn = (xNinNew, yNinNew ) | |
n.bcpOut = (xNoutNew, yNoutNew ) | |
nn.bcpIn = (xNnNew, yNnNew ) | |
pn.bcpOut = (xPnNew, yPnNew ) | |
#undo double move of selected anchor | |
newoffset = list(offset) | |
newoffset[0] = newoffset[0]*-1 | |
newoffset[1] = newoffset[1]*-1 | |
n.move(newoffset) | |
def nudgeSelected(x): | |
f = CurrentFont() | |
g = CurrentGlyph() | |
for c in g.contours: | |
i = 0 | |
for p in c.bPoints: | |
n = c.bPoints[i] | |
if n.selected: | |
g.prepareUndo(undoTitle='InterpolatedNudge') | |
interpolateNode(i,g,c,x) | |
g.performUndo() | |
g.update() | |
i = i + 1 | |
def nudge(glyph, x, y): | |
nudgeSelected((x,y)) | |
## subclass the editing tool but only overwrite the | |
class NudgeTool(EditingTool): | |
## we only need the keydown event | |
def keyDown(self, event): | |
modifiers = self.getModifiers() | |
## do nothing when option (alt) is down | |
if modifiers["optionDown"]: | |
return | |
x = 0 | |
y = 0 | |
## check which arrow keys are pushed | |
characters = event.characters() | |
if NSUpArrowFunctionKey == characters: | |
y = 1 | |
elif NSDownArrowFunctionKey == characters: | |
y = -1 | |
elif NSLeftArrowFunctionKey == characters: | |
x = -1 | |
elif NSRightArrowFunctionKey == characters: | |
x = 1 | |
else: | |
return | |
## add shif and command | |
add = 1 | |
if modifiers["shiftDown"]: | |
add = 10 | |
if modifiers["commandDown"]: | |
add = 100 | |
x *= add | |
y *= add | |
glyph = self.getGlyph() | |
## set undo | |
glyph.prepareUndo("Ted Nudgeit") | |
nudge(glyph, x, y) | |
glyph.performUndo() | |
def getToolbarTip(self): | |
return "Ted Nudgeit" | |
def getToolbarIcon(self): | |
thisNudgeIcon = NSImage.alloc().initWithContentsOfFile_("ted-nudgeit.pdf") | |
if thisNudgeIcon : | |
return thisNudgeIcon | |
## install the tool | |
installTool(NudgeTool()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment