Last active
November 3, 2021 22:48
-
-
Save okay-type/cffaf9bdc56d7b578be1d42d68af650a to your computer and use it in GitHub Desktop.
MM-quick-compare-kerning.py
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
import metricsMachine as mm | |
from vanilla import * | |
from mojo.events import addObserver, removeObserver, postEvent | |
from mojo.UI import GetFile | |
import merz | |
from fontTools.pens.basePen import BasePen | |
# this update lets you do basic edits to the current kern value | |
def _getMainWindowControllerForFont(font=None): | |
if font is None: | |
font = CurrentFont() | |
for other in AllFonts(): | |
if other != font: | |
continue | |
document = other.document() | |
for controller in document.windowControllers(): | |
window = controller.window() | |
if hasattr(window, "windowName") and window.windowName() == "MetricsMachineMainWindow": | |
delegate = window.delegate() | |
mmController = delegate.vanillaWrapper() | |
return mmController | |
raise MetricsMachineScriptingError("A MetricsMachine window is not open for %r." % font) | |
class DecompPen(BasePen): | |
def __init__(self, glyphSet, outPen): | |
super(DecompPen, self).__init__(glyphSet) | |
self._moveTo = outPen.moveTo | |
self._lineTo = outPen.lineTo | |
self._curveToOne = outPen.curveTo | |
self._closePath = outPen.closePath | |
self._endPath = outPen.endPath | |
class mmComparison(): | |
def __init__(self): | |
ufo = GetFile( | |
message=None, | |
title=None, | |
directory=None, | |
fileName=None, | |
allowsMultipleSelection=False, | |
fileTypes=None | |
) | |
self.compare = OpenFont(ufo, showUI=False) | |
self.w = Window( | |
(0, 0, 1000, 200), | |
'Compare Kerning', | |
fullSizeContentView=True, | |
titleVisible=False, | |
) | |
self.w.merzview = merz.MerzView( | |
(0, 0, -0, -0), | |
backgroundColor=(1, 1, 1, 1) | |
) | |
self.w.edit = EditText( | |
(-200, 0, 100, 22), | |
placeholder='0', | |
continuous=False, | |
callback=self.edit, | |
) | |
self.w.save = Button( | |
(-100, 0, 100, 22), | |
title='Save', | |
callback=self.save, | |
) | |
self.w.save.enable(False) | |
self.fillGlyph = (0, 0, 0, 1) | |
self.num = (0, 0, 0, .05) | |
self.numP = (0, .7, .6, 1) | |
self.numN = (1, 0, 0, 1) | |
addObserver(self, 'pairChanged', 'MetricsMachine.currentPairChanged') | |
self.w.bind('close', self.close) | |
self.w.open() | |
self.pairChanged(None) | |
def getMMGlyphs(self): | |
names = [] | |
pairView = _getMainWindowControllerForFont().editView.pairView | |
for g in pairView.getPairView().getGlyphs(): | |
names.append(g.name) | |
return names, pairView.getPointSize() | |
def close(self, sender): | |
self.compare.close() | |
removeObserver(self, 'MetricsMachine.currentPairChanged') | |
def edit(self, sender): | |
newKern = sender.get() | |
self.w.save.enable(True) | |
pairCurrent = left, right = list(mm.GetCurrentPair()) | |
currentKern = str(self.compare.kerning.find(pairCurrent)) | |
# update kerning here | |
# check if that should be a group instead of a glyph | |
matching = [s for s in self.compare.groups.findGlyph(left) if 'public.kern1' in s] | |
if len(matching) > 0: | |
left = matching[0] | |
# check if that should be a group instead of a glyph | |
matching = [s for s in self.compare.groups.findGlyph(right) if 'public.kern2' in s] | |
if len(matching) > 0: | |
right = matching[0] | |
if newKern == '0' or newKern == '' or newKern == 'None': | |
self.compare.kerning.remove((left, right)) | |
print('Removing ', left, right, 'kern from comparison ufo') | |
else: | |
self.compare.kerning[(left, right)] = int(newKern) | |
print('Adding ', left, right, newKern, 'kern to comparison ufo. Don\'t forget to save') | |
# update | |
self.pairChanged(None) | |
def save(self, sender): | |
self.w.save.enable(False) | |
self.compare.save() | |
print('Saved comparison ufo to', self.compare.path) | |
def pairChanged(self, notification): | |
pairCurrent = list(mm.GetCurrentPair()) | |
currentKern = str(self.compare.kerning.find(pairCurrent)) | |
if currentKern == 'None': | |
currentKern = '0' | |
self.w.edit.set(currentKern) | |
# self.pairCurrent = notification['pair'] | |
glyphs, size = self.getMMGlyphs() | |
x = shift = 0 | |
scale = size / 1000 | |
view = self.w.merzview | |
container = view.getMerzContainer() | |
container.clearSublayers() | |
container.setContainerScale(scale) | |
layerPreview = container.getSublayer('layerPreview') | |
if layerPreview is None: | |
layerPreview = container.appendBaseSublayer( | |
name='layerPreview', | |
position=(300, dict(point='center', offset=-100)), | |
size=(view.width(), view.height()), | |
) | |
with layerPreview.drawingTools() as bot: | |
for i, glyphName in enumerate(glyphs): | |
if glyphName in self.compare.glyphOrder: | |
if (x+self.compare[glyphName].width+400)*scale < view.width(): | |
if shift != 0 and i != 0: | |
if glyphName != 'space' and glyphs[i-1] != 'space': | |
c = self.num | |
if shift < 0: c = self.numN | |
if shift > 0: c = self.numP | |
textLineLayer = layerPreview.appendTextLineSublayer( | |
position=(x, -500), | |
size=(10, 10), | |
pointSize=9, | |
text=str(shift), | |
fillColor=(*c,), | |
horizontalAlignment='center' | |
) | |
bot.fill(*self.fillGlyph,) | |
rglyph, x = self.getGlyph(glyphName, x) | |
bot.drawGlyph(rglyph) | |
if i < len(glyphs)-1: | |
shift = self.compare.kerning.find((glyphName, glyphs[i+1])) | |
if shift == None: | |
shift = 0 | |
x += shift | |
def getGlyph(self, glyph, x, layer=None): | |
if glyph == 'space': | |
return self.compare[glyph], self.compare[glyph].width + x | |
else: | |
g = self.compare[glyph] | |
rglyph = RGlyph() | |
pen = DecompPen(self.compare, rglyph.getPen()) | |
g.draw(pen) | |
rglyph.moveBy((x, 0)) | |
x += g.width | |
return rglyph, x | |
mmComparison() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment