From 3b1fffade1473f20f2558733fbd218f4580fc7c3 Mon Sep 17 00:00:00 2001 From: Rasmus Andersson Date: Tue, 22 Aug 2017 00:05:20 -0700 Subject: Initial public commit --- misc/rf-scripts/AdjustWidth.py | 53 +++++ misc/rf-scripts/ChangeUPM.py | 107 ++++++++++ misc/rf-scripts/GridAdjust.py | 83 ++++++++ misc/rf-scripts/RemoveLocalGuides.py | 15 ++ misc/rf-scripts/StripGlyphs.py | 384 +++++++++++++++++++++++++++++++++++ misc/rf-scripts/ZeroWidth.py | 26 +++ 6 files changed, 668 insertions(+) create mode 100644 misc/rf-scripts/AdjustWidth.py create mode 100644 misc/rf-scripts/ChangeUPM.py create mode 100644 misc/rf-scripts/GridAdjust.py create mode 100644 misc/rf-scripts/RemoveLocalGuides.py create mode 100644 misc/rf-scripts/StripGlyphs.py create mode 100644 misc/rf-scripts/ZeroWidth.py (limited to 'misc/rf-scripts') diff --git a/misc/rf-scripts/AdjustWidth.py b/misc/rf-scripts/AdjustWidth.py new file mode 100644 index 000000000..c3d381f68 --- /dev/null +++ b/misc/rf-scripts/AdjustWidth.py @@ -0,0 +1,53 @@ +# +# This script changes the width of all glyphs by applying a multiplier. +# It keeps the contours centered as glyphs get wider or tighter. +# +from mojo.roboFont import version +from math import ceil, floor + +if __name__ == "__main__": + font = CurrentFont() + print "Resizing glyph margins for %r" % font + + # how much to add or remove from each glyph's margin + A = -16 + + if font is not None: + for g in font: + # skip glyphs + if g.name in ('c', 'e', 'o', 'r', 'j'): + continue + + if g.width < 2: + print '"%s": ["ignore", "zero-width"],' % (g.name) + continue + + if g.box is None: + print '"%s": ["ignore", "empty"],' % (g.name) + continue + + if g.width % 16 != 0: + print '"%s": ["ignore", "misaligned"],' % (g.name) + continue + + if g.leftMargin <= 0 or g.rightMargin <= 0: + print '"%s": ["ignore", "zero-or-negative"],' % (g.name) + continue + + leftMargin = int(max(0, g.leftMargin + A)) + rightMargin = int(max(0, g.rightMargin + A)) + + #print '"%s": ["update", %g, %g],' % (g.name, leftMargin, rightMargin) + if 'interface.spaceadjust' in g.lib: + g.lib['interface.width-adjustments'].append(A) + else: + g.lib['interface.width-adjustments'] = [A] + # order of assignment is probably important + g.rightMargin = int(rightMargin) + g.leftMargin = int(leftMargin) + + font.update() + else: + print "No fonts open" + + print "Done" diff --git a/misc/rf-scripts/ChangeUPM.py b/misc/rf-scripts/ChangeUPM.py new file mode 100644 index 000000000..f7617353a --- /dev/null +++ b/misc/rf-scripts/ChangeUPM.py @@ -0,0 +1,107 @@ +# Change upm +# Jens Kutilek 2013-01-02 + +from mojo.roboFont import version + +def scalePoints(glyph, factor): + if version == "1.4": + # stupid workaround for bug in RoboFont 1.4 + for contour in glyph: + for point in contour.points: + point.x *= factor + point.y *= factor + glyph.width *= factor + else: + glyph *= factor + +def scaleGlyph(glyph, factor, scaleWidth=True, roundCoordinates=True): + if not(scaleWidth): + oldWidth = glyph.width + if len(glyph.components) == 0: + scalePoints(glyph, factor) + if roundCoordinates: + glyph.round() + else: + # save components + # this may be a tad too convoluted ... + components = [] + for i in range(len(glyph.components)): + components.append(glyph.components[i]) + for c in components: + glyph.removeComponent(c) + scalePoints(glyph, factor) + if roundCoordinates: + glyph.round() + # restore components + for i in range(len(components)): + newOffset = (int(round(components[i].offset[0] * factor)), + int(round(components[i].offset[1] * factor))) + glyph.appendComponent(components[i].baseGlyph, newOffset, components[i].scale) + if not(scaleWidth): + # restore width + glyph.width = oldWidth + + +def changeUPM(font, factor, roundCoordinates=True): + + # Glyphs + for g in font: + scaleGlyph(g, factor) + for guide in g.guides: + # another thing that doesn't work in RoboFont 1.4 - 1.5.1 + guide.x *= factor + guide.y *= factor + + # Glyph layers + mainLayer = "foreground" + for layerName in font.layerOrder: + if layerName != mainLayer: + for g in font: + g.flipLayers(mainLayer, layerName) + scaleGlyph(g, factor, scaleWidth=False) + g.flipLayers(layerName, mainLayer) + + # Kerning + if font.kerning: + font.kerning.scale(factor) + if roundCoordinates: + if not version in ["1.4", "1.5", "1.5.1"]: + font.kerning.round(1) + else: + print "WARNING: kerning values cannot be rounded to integer in this RoboFont version" + + # TODO: Change positioning feature code? + + # Vertical dimensions + font.info.descender = int(round(font.info.descender * factor)) + font.info.xHeight = int(round(font.info.xHeight * factor)) + font.info.capHeight = int(round(font.info.capHeight * factor)) + font.info.ascender = int(round(font.info.ascender * factor)) + + # Finally set new UPM + font.info.unitsPerEm = newUpm + + font.update() + +if __name__ == "__main__": + from robofab.interface.all.dialogs import AskString + + print "Change Units Per Em" + + if CurrentFont() is not None: + oldUpm = CurrentFont().info.unitsPerEm + newUpm = CurrentFont().info.unitsPerEm + try: + newUpm = int(AskString("New units per em size?", oldUpm)) + except: + pass + if newUpm == oldUpm: + print " Not changing upm size." + else: + factor = float(newUpm) / oldUpm + print " Scaling all font measurements by", factor + changeUPM(CurrentFont(), factor) + else: + print " Open a font first to change upm, please." + + print " Done." diff --git a/misc/rf-scripts/GridAdjust.py b/misc/rf-scripts/GridAdjust.py new file mode 100644 index 000000000..f14550b4a --- /dev/null +++ b/misc/rf-scripts/GridAdjust.py @@ -0,0 +1,83 @@ +# +# This script changes the width of any glyph which width is not an even multiple of 256. +# For glyphs that are updated, the shape(s) inside the glyph are centered as well. +# +from mojo.roboFont import version +from math import ceil, floor + +if __name__ == "__main__": + font = CurrentFont() + print "Fitting glyphs to EM grid at 256 %r" % font + + # Strategy to use for centering a glyph when resizing its EM: + # "center" Ignore existing margins and center in EM at on integer units. + # "adjust-margins" Attempt to retain existing margins w/o centering inside EM. + centeringStrategy = 'center' + + if font is not None: + for g in font: + # only consider adjusting the listed glyphs + # if g.unicode not in (0x212B, 0x005A, 0x0387): + # continue + + if g.width < 2: + # ignore zero width glyph + # print 'ignoring %r -- zero width' % g + continue + + if g.width % 256 == 0: + # ignore already aligned glyph + # print 'ignoring %r -- already aligned' % g + continue + + width = g.width + if g.rightMargin < 128: + width = ceil(width / 256) * 256 + else: + width = round(width / 256) * 256 + + # center glyph in EM + leftMargin = g.leftMargin + rightMargin = g.rightMargin + + if centeringStrategy == 'adjust-margins': + # Adjust margins to place the glyph in the center while retaining original + # left/right margins. + widthDelta = width - g.width + leftMargin = g.leftMargin + int(floor(widthDelta / 2)) + rightMargin = g.rightMargin + int(ceil(widthDelta / 2)) + elif centeringStrategy == 'center': + # Read g.box (effective bounds of the glyph) and truly center the + # glyph, but we could run the risk of losing some intentionally-left or right + # aligned glyph, e.g. "|x |" -> "| x |" + if g.box is not None: + xMin, yMin, xMax, yMax = g.box + graphicWidth = xMax - xMin + leftMargin = round((width - graphicWidth) / 2) + else: + print 'Unexpected centeringStrategy value' + break + + # log message + uniname = '' + if g.unicode is not None: + uniname = ' U+%04X' % g.unicode + print 'Adjusting "%s"%s from %g to %g' % (g.name, uniname, g.width, width) + + # write changes to glyph + g.lib['interface.gridadjust.original'] = repr({ + "rightMargin": g.rightMargin, + "leftMargin": g.leftMargin, + "width": g.width, + }) + + # order of assignment is probably important + g.rightMargin = int(rightMargin) + g.leftMargin = int(leftMargin) + g.width = int(width) + + font.update() + else: + print "No fonts open" + + print "Done" diff --git a/misc/rf-scripts/RemoveLocalGuides.py b/misc/rf-scripts/RemoveLocalGuides.py new file mode 100644 index 000000000..05e1a05b7 --- /dev/null +++ b/misc/rf-scripts/RemoveLocalGuides.py @@ -0,0 +1,15 @@ +# +# Removes local guides from all glyphs +# +if __name__ == "__main__": + font = CurrentFont() + print "Removing local guides from all glyphs of %r" % font + if font is not None: + for g in font: + if 'com.typemytype.robofont.guides' in g.lib: + del(g.lib['com.typemytype.robofont.guides']) + font.update() + else: + print "No fonts open" + + print "Done" diff --git a/misc/rf-scripts/StripGlyphs.py b/misc/rf-scripts/StripGlyphs.py new file mode 100644 index 000000000..12bc2ab88 --- /dev/null +++ b/misc/rf-scripts/StripGlyphs.py @@ -0,0 +1,384 @@ +# +# Removes unused glyphs +# +from mojo.roboFont import version + +SC_ROMAN = [ + "A.smcp", + "B.smcp", + "C.smcp", + "D.smcp", + "E.smcp", + "F.smcp", + "G.smcp", + "H.smcp", + "I.smcp", + "J.smcp", + "K.smcp", + "L.smcp", + "M.smcp", + "N.smcp", + "O.smcp", + "P.smcp", + "Q.smcp", + "R.smcp", + "S.smcp", + "T.smcp", + "U.smcp", + "V.smcp", + "W.smcp", + "X.smcp", + "Y.smcp", + "Z.smcp", + "AE.smcp", + "AEacute.smcp", + "Aacute.smcp", + "Abreve.smcp", + "Acircumflex.smcp", + "Adieresis.smcp", + "Agrave.smcp", + "Alpha.smcp", + "Alphatonos.smcp", + "Amacron.smcp", + "Aogonek.smcp", + "Aogonek.smcp.NAV", + "Aring.smcp", + "Aringacute.smcp", + "Atilde.smcp", + "Beta.smcp", + "Cacute.smcp", + "Ccaron.smcp", + "Ccedilla.smcp", + "Ccircumflex.smcp", + "Chi.smcp", + "Dcaron.smcp", + "Dcroat.smcp", + "Delta.smcp", + "Eacute.smcp", + "Ebreve.smcp", + "Ecaron.smcp", + "Ecircumflex.smcp", + "Edieresis.smcp", + "Edotaccent.smcp", + "Egrave.smcp", + "Emacron.smcp", + "Eng.smcp", + "Eogonek.smcp", + "Eogonek.smcp.NAV", + "Epsilon.smcp", + "Epsilontonos.smcp", + "Eta.smcp", + "Etatonos.smcp", + "Eth.smcp", + "Gamma.smcp", + "Gbreve.smcp", + "Gcircumflex.smcp", + "Gcommaaccent.smcp", + "Germandbls.smcp", + "Hbar.smcp", + "Hcircumflex.smcp", + "IJ.smcp", + "Iacute.smcp", + "Ibreve.smcp", + "Icircumflex.smcp", + "Idieresis.smcp", + "Igrave.smcp", + "Imacron.smcp", + "Iogonek.smcp", + "Iota.smcp", + "Iotadieresis.smcp", + "Iotatonos.smcp", + "Itilde.smcp", + "Jcircumflex.smcp", + "Kappa.smcp", + "Kcommaaccent.smcp", + "Lacute.smcp", + "Lambda.smcp", + "Lcaron.smcp", + "Lcommaaccent.smcp", + "Ldot.smcp", + "Lslash.smcp", + "Nacute.smcp", + "Ncaron.smcp", + "Ncommaaccent.smcp", + "Ntilde.smcp", + "Nu.smcp", + "OE.smcp", + "Oacute.smcp", + "Obreve.smcp", + "Ocircumflex.smcp", + "Odieresis.smcp", + "Ograve.smcp", + "Ohungarumlaut.smcp", + "Omacron.smcp", + "Omega.smcp", + "Omegatonos.smcp", + "Omicron.smcp", + "Omicrontonos.smcp", + "Oogonek.smcp", + "Oogonek.smcp.NAV", + "Oslash.smcp", + "Oslashacute.smcp", + "Otilde.smcp", + "Phi.smcp", + "Pi.smcp", + "Psi.smcp", + "Racute.smcp", + "Rcaron.smcp", + "Rcommaaccent.smcp", + "Rho.smcp", + "Sacute.smcp", + "Scaron.smcp", + "Scedilla.smcp", + "Scircumflex.smcp", + "Sigma.smcp", + "Tau.smcp", + "Tbar.smcp", + "Tcaron.smcp", + "Theta.smcp", + "Thorn.smcp", + "Uacute.smcp", + "Ubreve.smcp", + "Ucircumflex.smcp", + "Udieresis.smcp", + "Ugrave.smcp", + "Uhungarumlaut.smcp", + "Umacron.smcp", + "Uogonek.smcp", + "Upsilon.smcp", + "Upsilondieresis.smcp", + "Upsilontonos.smcp", + "Uring.smcp", + "Utilde.smcp", + "Wacute.smcp", + "Wcircumflex.smcp", + "Wdieresis.smcp", + "Wgrave.smcp", + "Xi.smcp", + "Yacute.smcp", + "Ycircumflex.smcp", + "Ydieresis.smcp", + "Ygrave.smcp", + "Zacute.smcp", + "Zcaron.smcp", + "Zdotaccent.smcp", + "Zeta.smcp", + "ampersand.smcp", + "uni010A.smcp", + "uni0120.smcp", + "uni0162.smcp", + "Scommaaccent.smcp", + "Tcommaaccent.smcp", + "uni037F.smcp" +] + + +SC_SET1 = [ + "zero.smcp", + "one.smcp", + "two.smcp", + "three.smcp", + "four.smcp", + "five.smcp", + "six.smcp", + "seven.smcp", + "eight.smcp", + "nine.smcp", + "Euro.smcp", + "Idotaccent.smcp", + "Mu.smcp", + "dollar.smcp", + "lira.smcp", + "sterling.smcp", + "uni0401.smcp", + "uni0402.smcp", + "uni0403.smcp", + "uni0404.smcp", + "uni0405.smcp", + "uni0406.smcp", + "uni0407.smcp", + "uni0408.smcp", + "uni0409.smcp", + "uni040A.smcp", + "uni040B.smcp", + "uni040C.smcp", + "uni040E.smcp", + "uni040F.smcp", + "uni0410.smcp", + "uni0411.smcp", + "uni0412.smcp", + "uni0413.smcp", + "uni0414.smcp", + "uni0415.smcp", + "uni0416.smcp", + "uni0417.smcp", + "uni0418.smcp", + "uni0419.smcp", + "uni041A.smcp", + "uni041B.smcp", + "uni041C.smcp", + "uni041D.smcp", + "uni041E.smcp", + "uni041F.smcp", + "uni0420.smcp", + "uni0421.smcp", + "uni0422.smcp", + "uni0423.smcp", + "uni0424.smcp", + "uni0425.smcp", + "uni0426.smcp", + "uni0427.smcp", + "uni0428.smcp", + "uni0429.smcp", + "uni042A.smcp", + "uni042B.smcp", + "uni042C.smcp", + "uni042D.smcp", + "uni042E.smcp", + "uni042F.smcp", + "uni0490.smcp", + "uni0492.smcp", + "uni0496.smcp", + "uni0498.smcp", + "uni049A.smcp", + "uni049C.smcp", + "uni04A0.smcp", + "uni04A2.smcp", + "uni04A8.smcp", + "uni04AA.smcp", + "uni04AE.smcp", + "uni04B0.smcp", + "uni04B2.smcp", + "uni04B4.smcp", + "uni04B8.smcp", + "uni04BA.smcp", + "uni04BC.smcp", + "uni04BE.smcp", + "uni04D8.smcp", + "uni04E0.smcp", + "uni04E2.smcp", + "uni04E8.smcp", + "uni04EE.smcp", + "uni20B4.smcp", + "uni20B8.smcp", + "uni20BD.smcp", + "uni2116.smcp", + "yen.smcp" +] + + +SC_SET2 = [ + "I.smcp", + "Sigma.smcp", + "Mu.smcp", + "uni0410.smcp", + "uni0411.smcp", + "uni0412.smcp", + "uni0413.smcp", + "uni0414.smcp", + "uni0415.smcp", + "uni0416.smcp", + "uni0417.smcp", + "uni0418.smcp", + "uni0419.smcp", + "uni041A.smcp", + "uni041B.smcp", + "uni041C.smcp", + "uni041D.smcp", + "uni041E.smcp", + "uni041F.smcp", + "uni0420.smcp", + "uni0421.smcp", + "uni0422.smcp", + "uni0423.smcp", + "uni0424.smcp", + "uni0425.smcp", + "uni0426.smcp", + "uni0427.smcp", + "uni0428.smcp", + "uni0429.smcp", + "uni042A.smcp", + "uni042B.smcp", + "uni042C.smcp", + "uni042D.smcp", + "uni042E.smcp", + "uni042F.smcp", + "uni0401.smcp", + "uni0402.smcp", + "uni0403.smcp", + "uni0404.smcp", + "uni0405.smcp", + "uni0406.smcp", + "uni0407.smcp", + "uni0408.smcp", + "uni0409.smcp", + "uni040A.smcp", + "uni040B.smcp", + "uni040C.smcp", + "uni040E.smcp", + "uni040F.smcp", + "uni0490.smcp", + "uni0492.smcp", + "uni0496.smcp", + "uni0498.smcp", + "uni049A.smcp", + "uni049C.smcp", + "uni04A0.smcp", + "uni04A2.smcp", + "uni04A8.smcp", + "uni04AA.smcp", + "uni04AE.smcp", + "uni04B0.smcp", + "uni04B2.smcp", + "uni04B4.smcp", + "uni04B8.smcp", + "uni04BA.smcp", + "uni04BC.smcp", + "uni04BE.smcp", + "uni04D8.smcp", + "uni04E0.smcp", + "uni04E2.smcp", + "uni04E8.smcp", + "uni04EE.smcp" +] + + +STRIP_NAME_SET = set(SC_ROMAN).union(SC_SET1).union(SC_SET2) + +STRIP_SUFFIXES = ( + '.smcp', + '.unic', + '.alt', + '.alt2', + '.ss06', + '.ss07', + '.onum', + '.pnum', + '.tnum' +) + +def hasStripSuffix(g): + name = g.name + for suffix in STRIP_SUFFIXES: + if str.endswith(name, suffix): + return True + return False + +if __name__ == "__main__": + font = CurrentFont() + if font is not None: + for g in font: + if g.name in STRIP_NAME_SET or hasStripSuffix(g): + + if g.unicode is not None: + # glyph maps to a codepoint -- keep it + continue + + print 'Removing "%s"' % g.name + + font.removeGlyph(g.name) + font.update() + else: + print "No fonts open" + + print "Done" diff --git a/misc/rf-scripts/ZeroWidth.py b/misc/rf-scripts/ZeroWidth.py new file mode 100644 index 000000000..a9277d09c --- /dev/null +++ b/misc/rf-scripts/ZeroWidth.py @@ -0,0 +1,26 @@ +# +# This script changes the width of all glyphs by applying a multiplier. +# It keeps the contours centered as glyphs get wider or tighter. +# +from mojo.roboFont import version +from math import ceil, floor + +if __name__ == "__main__": + font = CurrentFont() + print "Resizing glyph margins for %r" % font + + if font is not None: + for g in font: + leftMargin = g.leftMargin + rightMargin = g.rightMargin + + if leftMargin < 0 or rightMargin < 0: + g.rightMargin = int(max(0, rightMargin)) + g.leftMargin = int(max(0, leftMargin)) + print("adjust %s" % g.name) + + font.update() + else: + print "No fonts open" + + print "Done" -- cgit v1.2.3