├── Clone Glyph.py
├── ExportSelectedGlyphsToFL.py
├── GetAllGlyphsMarkedLikeAsSelected.py
├── GetSelectedGlyphsAsArray.py
├── GetSelectedGlyphsAsString.py
├── Import Marks and Masks from Fontlab.py
├── Interpolation Tool
└── Interpolation Tool (beta).roboFontExt
│ ├── html
│ ├── index.html
│ ├── inttoolmain.jpg
│ └── inttoolshortview.jpg
│ ├── info.plist
│ └── lib
│ ├── InterpolationLib.py
│ ├── InterpolationTool.py
│ ├── ReportWindow.py
│ └── tempfont.ufo
│ ├── fontinfo.plist
│ ├── glyphs
│ ├── DDbracketleft_.glif
│ ├── DDbracketright_.glif
│ ├── DDeight_.glif
│ ├── DDfive_.glif
│ ├── DDfour_.glif
│ ├── DDminus_.glif
│ ├── DDnine_.glif
│ ├── DDone_.glif
│ ├── DDseven_.glif
│ ├── DDsix_.glif
│ ├── DDthree_.glif
│ ├── DDtwo_.glif
│ ├── DDzero_.glif
│ └── contents.plist
│ ├── lib.plist
│ └── metainfo.plist
├── LatCyrl-CharacterSet-RF.txt
├── README.md
├── Show all glyphs.py
├── TestInstallAdvanced.py
├── Version Control
├── README.md
├── VersionControl.roboFontExt
│ ├── html
│ │ └── index.html
│ ├── info.plist
│ └── lib
│ │ └── VersionControl.py
└── doc
│ └── VersionControl-RobofontExtension.pdf
├── checkOverlaping.py
├── drawReferenceGlyph.py
├── dump All-to-All to SpaceCenter.py
├── getInterpolationFactorByStems.py
├── makeGroupsFromFeature.py
├── makeTableAlltoAll.py
├── make_ALT_fea.py
├── polygon selection tool
├── polygon-select.png
└── polygonSelectionTool.py
├── removeAllGuides.py
├── renameGroupsOBSR.py
└── resortGlyphOrder.py
/Clone Glyph.py:
--------------------------------------------------------------------------------
1 | # RoboFont Script
2 | # Dublicate selected glyphs and rename them to NameGlyph.ver.XXX
3 | # XXX ( XXX - 001, 002 ... 999 )
4 | # Alexander Lubovenko
5 | # http://github.com/typedev
6 |
7 | from robofab.world import CurrentFont, CurrentGlyph
8 | from mojo.UI import *
9 | from time import asctime
10 |
11 | font = CurrentFont()
12 | glyphslist = font.selection
13 |
14 | def cloneGlyph(glyph,name=''):
15 | if name == '':
16 | oldname = glyph.name
17 | else:
18 | oldname = name
19 | for i in range(1,1000):
20 | oldname = oldname.replace('.ver','')
21 | newName = '%s.ver.%03d' % (oldname, i)
22 | if newName not in font.keys():
23 | font.insertGlyph(glyph,newName)
24 | font.update()
25 | font[newName].note = asctime()
26 | break
27 |
28 | for i in glyphslist:
29 | glyph = font[i]
30 | lname = glyph.name.split('.')
31 | if len(lname) == 1:
32 | cloneGlyph(glyph)
33 | else:
34 | gnumber = lname[-1]
35 | if gnumber.isdigit():
36 | lname.pop()
37 | sname='.'.join(lname)
38 | cloneGlyph(glyph,sname)
39 |
40 | font.update()
--------------------------------------------------------------------------------
/ExportSelectedGlyphsToFL.py:
--------------------------------------------------------------------------------
1 | import sys
2 |
3 | sys.path.append( '/Users/alexander/PycharmProjects/CustomControls' )
4 |
5 | import tdReport
6 | from robofab.world import CurrentFont, CurrentGlyph
7 | font = CurrentFont()
8 | gselected = CurrentGlyph()
9 |
10 | TOFL_MARK = (0.4, 1.0, 0.4, 1.0)
11 | EXPORTED = (0.4, 1.0, 0.4, 0.1)
12 | EXCEPT_MARK = (1.0, 0.8, 0.4, 1.0)
13 |
14 | file_ext = 'toFl'
15 | path_exp = font.path.replace('.ufo','')
16 | # filename = font.filename
17 | report = tdReport.Report(file = path_exp, ext = 'toFL', process= 'Export selected glyphs to FontLab' )
18 | print 'Selected glyph: ', gselected.name, 'marked as', gselected.mark
19 | names = []
20 | for gf in CurrentFont():
21 | if gf.mark == gselected.mark:
22 | names.append(gf.name)
23 | report.add(gf.name)
24 | print names
25 | print 'Glyph list saved as: ' + path_exp + '.' + file_ext
26 | report.save()
27 |
28 |
29 |
--------------------------------------------------------------------------------
/GetAllGlyphsMarkedLikeAsSelected.py:
--------------------------------------------------------------------------------
1 | gselected = CurrentGlyph()
2 |
3 | print 'Selected glyph: ', gselected.name, 'marked as', gselected.mark
4 | names = []
5 | for gf in CurrentFont():
6 | if gf.mark == gselected.mark:
7 | names.append(gf.name)
8 | print names
9 | namesstr = ''
10 | for n in names:
11 | namesstr = namesstr + n +' '
12 | print namesstr
13 |
--------------------------------------------------------------------------------
/GetSelectedGlyphsAsArray.py:
--------------------------------------------------------------------------------
1 | __author__ = 'alexander'
2 |
3 | stroke = '["'
4 | font = CurrentFont()
5 |
6 | for g in font.selection:
7 | stroke = stroke + g + '","'
8 | print stroke + '"]'
9 |
--------------------------------------------------------------------------------
/GetSelectedGlyphsAsString.py:
--------------------------------------------------------------------------------
1 | __author__ = 'alexander'
2 |
3 | stroke = ''
4 | font = CurrentFont()
5 |
6 | for g in font.selection:
7 | g = g.replace('\n','')
8 | stroke = stroke + g + ' '
9 | print stroke
10 |
--------------------------------------------------------------------------------
/Import Marks and Masks from Fontlab.py:
--------------------------------------------------------------------------------
1 |
import colorsys
f = CurrentFont()
MASK_LIB_KEY = "org.robofab.fontlab.maskData"
MARK_LIB_KEY = "org.robofab.fontlab.mark"
def portFLmark(glyph):
fontLabMarkColor = 0
fontLabMarkColor = glyph.lib.get("org.robofab.fontlab.mark")
if fontLabMarkColor != 0:
r, g, b = colorsys.hsv_to_rgb(fontLabMarkColor/256., 1., 1.)
glyph.mark = (r, g, b, .5)
def portFLmaskData(glyph):
#get pendata
# filter out any single point contours (anchors)
instructions = []
pointStack = []
lib = glyph.lib
if lib.has_key(MASK_LIB_KEY):
instructions = lib[MASK_LIB_KEY]
pen = glyph.getPointPen()
instructionsDrawPoints(instructions, pen)
# clear the mask data from the glyph lib
del lib[MASK_LIB_KEY]
glyph.update()
def instructionsDrawPoints(instructions, pointPen):
"""draw instructions created by InstructionPointPen"""
# filter out single point contours (anchors)
pointStack = []
for instruction in instructions:
pointStack.append(instruction)
meth = instruction["method"]
if meth == "endPath":
if len(pointStack) > 3:
_drawPointStack(pointStack, pointPen)
pointStack = []
def _drawPointStack(stack, pointPen):
for instruction in stack:
meth = instruction["method"]
if meth == "beginPath":
pointPen.beginPath()
elif meth == "endPath":
pointPen.endPath()
elif meth == "addPoint":
pt = instruction["pt"]
smooth = instruction.get("smooth")
segmentType = instruction.get("segmentType")
name = instruction.get("name")
pointPen.addPoint(pt, segmentType, smooth, name)
elif meth == "addComponent":
baseGlyphName = instruction["baseGlyphName"]
transformation = instruction["transformation"]
pointPen.addComponent(baseGlyphName, transformation)
else:
raise NotImplementedError, meth
for glyph in f:
#port the colour marks
portFLmark(glyph)
#create/get the layer for the mask data
glyph.getLayer("FontLab Mask")
#flip it so we draw on a clean layer
glyph.flipLayers("FontLab Mask", "foreground")
portFLmaskData(glyph)
#flip back we’re done
glyph.flipLayers("FontLab Mask", "foreground")
print "Done"
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/html/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | documentation-eng2
7 |
8 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
Interpolation Tool is an extension for Robofont which allows you to model interpolation and extrapolation of any number of instances between two masters. Two compatible fonts should be used as masters for interpolation. There are three methods for interpolation modeling: “Luc(as) de Groot” , “Pablo Impallari” and “Linear” method. However, each instance in the line can be adjusted with the Tuner.
27 |
28 |
29 | Interpolation Tool may also be useful for basic masters correction, as any changes in contours of basic glyphs are displayed in Interpolation line immediately.
30 |
31 |
32 |
User interface
33 |
34 |
35 |
36 | Main Window
37 |
38 |
39 |
40 |
41 | Choose Interpolation Method
42 | Increasing/ decreasing the number of instances between masters
43 | The first master
44 | The second master
45 | Add extrapolation –100
46 | Add extrapolation +500
47 | View window of Instance line
48 | Instance weight
49 | Tuner instance
50 | Button to display the preview of the selected glyph or open master`s glyph edit window
51 | Button to remove the selected instance
52 | Button to generate the selected instance (currently not working)
53 | Button to generate all instances (currently not working)
54 |
55 |
56 |
View mode
57 |
58 |
A. Full View Mode (by default) – all tools are visible
59 |
60 |
B. Short View Mode – a part of tools are visible.
61 | This mode can be useful for making adjustments to glyphs` masters.
62 |
63 |
C. Controlling Instance`s Line Preview Size
64 |
65 |
66 |
67 | Short View Mode
68 |
69 |
70 |
71 |
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/html/inttoolmain.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/typedev/RoboFont/d74e13781b1685a28b1e6fe59f24a42f75d74432/Interpolation Tool/Interpolation Tool (beta).roboFontExt/html/inttoolmain.jpg
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/html/inttoolshortview.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/typedev/RoboFont/d74e13781b1685a28b1e6fe59f24a42f75d74432/Interpolation Tool/Interpolation Tool (beta).roboFontExt/html/inttoolshortview.jpg
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | addToMenu
6 |
7 |
8 | path
9 | InterpolationTool.py
10 | preferredName
11 | InterpolationTool
12 | shortKey
13 |
14 |
15 |
16 | developer
17 | Alexander Lubovenko
18 | developerURL
19 | https://github.com/typedev
20 | html
21 |
22 | launchAtStartUp
23 | 0
24 | mainScript
25 |
26 | name
27 | Interpolation Tool (beta)
28 | requiresVersionMajor
29 | 1
30 | requiresVersionMinor
31 | 5
32 | timeStamp
33 | 1382679499.7877497
34 | version
35 | 0.8.72
36 | repository
37 | typedev/RoboFont
38 | extensionPath
39 | Interpolation Tool/Interpolation Tool (beta).roboFontExt
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/lib/InterpolationLib.py:
--------------------------------------------------------------------------------
1 | from mojo.roboFont import *
2 | from time import asctime
3 | from math import *
4 | # import ReportWindow
5 | # reload(ReportWindow)
6 |
7 | redMark = (1,0,0,1)
8 | greyMark = (.2, .2, .2, .5)
9 |
10 |
11 | from vanilla import *
12 |
13 | # InterpolationReport = ReportWindow.ReportWindow('Interpolation Report')
14 |
15 | def mathVM(minVM,maxVM,factor):
16 | delta = maxVM - minVM
17 | return int(round(minVM+factor*delta,0))
18 |
19 | class ProgressBarWindow(object):
20 |
21 | def __init__(self, Count = 0, nameOfProcess = ''):
22 | self.w = FloatingWindow((280, 65))
23 | self.w.label = TextBox((10, 12, -10, 24), nameOfProcess)
24 | self.w.bar = ProgressBar((10, 40, -10, 16),minValue=0, maxValue = Count)
25 | self.w.center()
26 | self.w.open()
27 |
28 | def increment(self):
29 | self.w.bar.increment()
30 |
31 | def closeProgress(self):
32 | self.w.close()
33 |
34 |
35 | def decomposeGlyph(glyph):
36 | if glyph.components != None:
37 | for c in glyph.components:
38 | c.decompose()
39 | return glyph
40 |
41 | def getListOfCompatibleGlyphs(bFont,dFont, mark = True):
42 | bGlyphCount = len(bFont)
43 | dGlyphCount = len(dFont)
44 | okGlyphs = []
45 | wrongGlyphs = []
46 | missingGlyphs = []
47 | Progress = ProgressBarWindow((bGlyphCount+dGlyphCount),'Checking glyphs...')
48 | copyBfont = bFont.copy()
49 | copyDfont = dFont.copy()
50 | for glyph in bFont:
51 | Progress.increment()
52 | if dFont.has_key( glyph.name ):
53 | # print "++++++++++++++++", glyph.name
54 | # aGlyph = bFont[glyph.name]
55 | # bGlyph = dFont[glyph.name]
56 | aGlyph = decomposeGlyph(copyBfont[glyph.name])
57 | bGlyph = decomposeGlyph(copyDfont[glyph.name])
58 | isComp = aGlyph.isCompatible (bGlyph, True)
59 | if isComp[0]:
60 | okGlyphs.append(glyph.name)
61 | else:
62 | a = ' '.join(isComp[1])
63 | a = a.replace('Fatal error: ','')
64 | wrongGlyphs.append([glyph.name, a])
65 | if mark:
66 | glyph.mark = redMark
67 | dFont[ glyph.name ].mark = redMark
68 | else:
69 | missingGlyphs.append([bFont.info.familyName, bFont.info.styleName, glyph.name])
70 | if mark:
71 | glyph.mark = greyMark
72 | for glyph in dFont:
73 | Progress.increment()
74 |
75 | if bFont.has_key( glyph.name ):
76 | pass
77 | else:
78 | missingGlyphs.append([dFont.info.familyName, dFont.info.styleName, glyph.name])
79 | if mark:
80 | glyph.mark = greyMark
81 | # bFont.update()
82 | # dFont.update()
83 | Progress.closeProgress()
84 | return okGlyphs, wrongGlyphs, missingGlyphs
85 |
86 | def getRightFontOrder(bFont,dFont):
87 | bGlyphCount = len(bFont)
88 | dGlyphCount = len(dFont)
89 | if bGlyphCount == dGlyphCount:
90 | return bFont, dFont
91 | else:
92 | if bGlyphCount > dGlyphCount:
93 | return bFont, dFont
94 | if bGlyphCount < dGlyphCount:
95 | return dFont, bFont
96 |
97 |
98 | def checkCompatibilityConsole(bFont,dFont, mark = True, report = True):
99 | # InterpolationReport.addToReport( "Interpolation Tool report" )
100 | # InterpolationReport.addToReport( "Checking glyphs... " + asctime() )
101 | print "Interpolation Tool report"
102 | print "Checking glyphs... ", asctime()
103 | okGlyphs = []
104 | wrongGlyphs = []
105 | missingGlyphs = []
106 |
107 |
108 | aFont, bFont = getRightFontOrder(bFont,dFont)
109 | okGlyphs, wrongGlyphs, missingGlyphs = getListOfCompatibleGlyphs( aFont, bFont, mark )
110 |
111 |
112 | if report:
113 | Progress = ProgressBarWindow(len(wrongGlyphs)+len(missingGlyphs),'Making report...')
114 | for glyph in wrongGlyphs:
115 | gname, gerror = glyph
116 | print "Incompatible:", glyph[0] ,"Reason:", gerror, "Marked RED label"
117 | Progress.increment()
118 |
119 | for glyph in missingGlyphs:
120 | print "Missing Glyph:", glyph[0], glyph[1], glyph[2], "Marked GREY label"
121 | Progress.increment()
122 | Progress.closeProgress()
123 |
124 | # for glyph in wrongGlyphs:
125 | # gname, gerror = glyph
126 | # InterpolationReport.addToReport( "Incompatible: " + glyph[0] + " Reason: " + gerror + " Marked RED label." )
127 | # Progress.increment()
128 |
129 | # for glyph in missingGlyphs:
130 | # InterpolationReport.addToReport( "Missing Glyph: " + glyph[0] +' '+ glyph[1] +' '+ glyph[2] + " Marked GREY label." )
131 | # Progress.increment()
132 | return okGlyphs
133 |
134 |
135 | def InterpolateFonts(minFont,maxFont,
136 | compatibleGlyphs = [],
137 | intrepolateScale = [],
138 | kerning = True,
139 | deletesmallpairs = True,
140 | lowpair = -5,
141 | highpair = 5):
142 | # InterpolationReport.addToReport( "Interpolate..." )
143 | print "Interpolate..."
144 |
145 | aFont, bFont = getRightFontOrder(minFont, maxFont)
146 |
147 |
148 |
149 | for factor in intrepolateScale:
150 |
151 | ffactor = int(factor * 1000)
152 | if (ffactor != 0) and (ffactor != 1000):
153 | fontNewWeightName = str(ffactor)
154 |
155 | # InterpolationReport.addToReport( "Generate instance: " + fontNewWeightName + ' -- ' + asctime() )
156 | print "Generate instance: ", fontNewWeightName, ' -- ', asctime()
157 |
158 | resultFont = NewFont(aFont.info.familyName, fontNewWeightName )
159 |
160 | print "Dimensions:"
161 |
162 |
163 | A = minFont.info.ascender
164 | B = maxFont.info.ascender
165 | resultFont.info.ascender = mathVM(A,B,factor)
166 |
167 | print '\tAscender:', resultFont.info.ascender
168 |
169 | A = minFont.info.capHeight
170 | B = maxFont.info.capHeight
171 | resultFont.info.capHeight = mathVM(A,B,factor)
172 |
173 | print '\tCap-height', resultFont.info.capHeight
174 |
175 | A = minFont.info.xHeight
176 | B = maxFont.info.xHeight
177 | resultFont.info.xHeight = mathVM(A,B,factor)
178 |
179 | print '\tx-height', resultFont.info.xHeight
180 |
181 | A = minFont.info.descender
182 | B = maxFont.info.descender
183 | resultFont.info.descender = mathVM(A,B,factor)
184 |
185 | print '\tDescender:', resultFont.info.descender
186 |
187 |
188 |
189 |
190 |
191 | # Copy groups
192 | Progress = ProgressBarWindow(len(aFont.groups.items()),'['+fontNewWeightName+'] Copying groups...')
193 | # InterpolationReport.addToReport('Groups: ' + str(len(aFont.groups.items())) )
194 | print 'Groups: ', str(len(aFont.groups.items()))
195 | for group, value in aFont.groups.items():
196 | resultFont.groups[group] = value
197 | Progress.increment()
198 | Progress.closeProgress()
199 |
200 | # Interpolate kerning
201 | if kerning:
202 | resultFont.kerning.interpolate(minFont.kerning, maxFont.kerning, factor )
203 | if deletesmallpairs:
204 | dic = {}
205 | totalPairs = len(resultFont.kerning.items())
206 | Progress = ProgressBarWindow( totalPairs ,'['+fontNewWeightName+'] Interpolate kerning...')
207 | # InterpolationReport.addToReport('Interpolate kerning: ')
208 | # InterpolationReport.addToReport('total pairs ' + str(totalPairs) )
209 | # InterpolationReport.addToReport('removing pairs between -5 and 5 ' )
210 | for i in resultFont.kerning.items():
211 | # InterpolationReport.addToReport(str(i[1]) +' '+ str(i[0]))
212 | Progress.increment()
213 | if i[1] != 0:
214 | if i[1] > highpair:
215 | dic[i[0]] = int(round(i[1]))
216 | else:
217 | if i[1] < lowpair:
218 | dic[i[0]] = int(round(i[1]))
219 |
220 | resultFont.kerning.clear()
221 | resultFont.kerning.update(dic)
222 | # InterpolationReport.addToReport('total pairs ' + str(len(resultFont.kerning.items())) )
223 | Progress.closeProgress()
224 |
225 | # Interpolate glyphs
226 | Progress = ProgressBarWindow(len(compatibleGlyphs),'['+fontNewWeightName+'] Interpolate glyphs...')
227 |
228 | for glyphname in compatibleGlyphs:
229 | newglyph = resultFont.newGlyph( glyphname )
230 | newglyph.interpolate (factor, minFont[ glyphname ], maxFont[ glyphname ])
231 | newglyph.unicode = aFont[ glyphname ].unicode
232 | newglyph.update()
233 | Progress.increment()
234 |
235 | resultFont.round()
236 |
237 | Progress.closeProgress()
238 |
239 |
240 | # resultFont.glyphOrder = aFont.glyphOrder
241 | # InterpolationReport.addToReport( "Instance: " + fontNewWeightName + " done" )
242 | print "Instance: ", fontNewWeightName, " done"
243 |
244 | minFont.update()
245 | maxFont.update()
246 | # InterpolationReport.addToReport( "All done. =)" )
247 | # InterpolationReport.showReport()
248 | print "All done. =)"
249 |
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/lib/InterpolationTool.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | RoboFont Script
4 | InterpolationTool.py
5 |
6 | Created by Alexander Lubovenko on 2013-08-26.
7 | http://github.com/typedev
8 | """
9 | #from __future__ import division
10 |
11 | import sys
12 | from math import *
13 | from vanilla import *
14 | from mojo.UI import *
15 | from mojo.glyphPreview import GlyphPreview
16 | from mojo.events import addObserver, removeObserver
17 | from mojo.roboFont import OpenWindow
18 | from defconAppKit.windows.baseWindow import BaseWindowController
19 | from defconAppKit.controls.glyphLineView import GlyphLineView
20 | from mojo import events
21 | from mojo.drawingTools import *
22 | from mojo.canvas import Canvas
23 | import InterpolationLib #import *
24 | #import mojo.extensions
25 | # from lib.settings import applicationPluginRootPath, applicationPluginPreferencesPath, appName
26 |
27 | # print applicationPluginRootPath
28 | # print sys.path[0]
29 | # print applicationPluginPreferencesPath
30 |
31 | #reload(InterpolationLib)
32 |
33 | minStem = 1
34 | maxStem = 10
35 |
36 | intLucas = 0
37 | intImpallari = 1
38 | intLinear = 2
39 | intManual = 3
40 |
41 | viewFull = 0
42 | viewShort = 1
43 |
44 | #===================================================================================
45 | redMark = (1, 0, 0, 1)
46 | greyMark = (.2, .2, .2, .5)
47 |
48 | previewOptions = {'Inverse': False, 'xHeight Cut': False, 'Show Kerning': True,
49 | 'Left to Right': True, 'Show Metrics': False, 'Show Space Matrix': True,
50 | 'Upside Down': False, 'Right to Left': False, 'Stroke': False, 'Beam': False,
51 | 'Water Fall': False, 'Multi Line': True, 'Single Line': False,
52 | 'Show Control glyphs': False, 'Fill': True}
53 |
54 | DDlist = {'DDzero': 0, 'DDone': 1,
55 | 'DDtwo': 2, 'DDthree': 3,
56 | 'DDfour': 4, 'DDfive': 5,
57 | 'DDsix': 6, 'DDseven': 7,
58 | 'DDeight': 8, 'DDnine': 9}
59 |
60 | DDfontPath = sys.path[0] + '/tempfont.ufo'
61 | listfonts = AllFonts()
62 |
63 | ListManualStems = '48=0 74 94 128 165 192 218=1'
64 |
65 |
66 | def getListOfOpenFonts ():
67 | lfonts = []
68 | for n in listfonts:
69 | fontFamilyName = ''
70 | fontStyleName = ''
71 | if n.info.familyName != None:
72 | fontFamilyName = n.info.familyName
73 | if n.info.styleName != None:
74 | fontStyleName = n.info.styleName
75 | lfonts.append(fontFamilyName + '/' + fontStyleName)
76 | lfonts.sort()
77 | return lfonts
78 |
79 |
80 | def getGlyphNameString (number):
81 | st = []
82 | if number[0] != '-':
83 | for a in number:
84 | for n, d in DDlist.items():
85 | if d == int(a):
86 | st.append(n)
87 | else:
88 | st.append('DDminus')
89 | for a in number[1:]:
90 | for n, d in DDlist.items():
91 | if d == int(a):
92 | st.append(n)
93 | return st
94 |
95 |
96 | def getLucasFactor (a, b, n):
97 | d = (log(b) - log(a)) / (n + 1)
98 | factor = []
99 | for i in range(n + 2):
100 | dd = exp(log(a) + i * d)
101 | factor = factor + [round((dd - a) / (b - a), 3)]
102 | return factor
103 |
104 |
105 | def getLinearFactor (a, b, n):
106 | factor = []
107 | c = float((b - (a - 1))) / (n + 1)
108 | for i in range(n + 2):
109 | factor = factor + [round(((a - 1) + c * i) / 10, 3)]
110 | return factor
111 |
112 |
113 | def getImpallariFactor (min, max, n):
114 | es = getLinearFactor(min, max, n)
115 | ls = getLucasFactor(min, max, n)
116 | return [round(l * (1 - i / (n + 1)) + e * (i / (n + 1)), 3) for (i, e, l) in zip(range(n + 2), es, ls)]
117 |
118 |
119 | def getFactorByStem (minStem, maxStem, midStem):
120 | if (midStem != 0) and (midStem != 1000):
121 | return 1000 * (midStem - minStem) / (maxStem - minStem)
122 | else:
123 | return midStem
124 |
125 |
126 | def getFactorListByStems (listStems): # listStems string: 10 20 30 40=0 50 60 70 80 90 100=1 110 120
127 | ld = listStems.split(' ')
128 | ls = []
129 | lf = []
130 | for i in ld:
131 | if '=' in i:
132 | lm = i.split('=')
133 | if lm[1] == '0':
134 | minStem = int(lm[0])
135 | ls.append(0)
136 | if lm[1] == '1':
137 | maxStem = int(lm[0])
138 | ls.append(1000)
139 | else:
140 | ls.append(int(i))
141 | for i in ls:
142 | lf.append(getFactorByStem(minStem, maxStem, i) / 1000.0)
143 | return lf
144 |
145 |
146 | def decomposeGlyph (glyph):
147 | if glyph.components != None:
148 | for c in glyph.components:
149 | c.decompose()
150 | return glyph
151 |
152 | # def interpolateFonts(factor, minFont, maxFont, kerning = False):
153 | # pass
154 |
155 | #===================================================================================
156 |
157 | def is_number (s):
158 | try:
159 | float(s)
160 | # print 'NUMBER'
161 | return True
162 | except ValueError:
163 | # print 'NOT NUMBER'
164 | return False
165 |
166 |
167 | class InterpolationWindow(BaseWindowController):
168 | class InstancesSelector(BaseWindowController):
169 | def __init__ (self, interpolationScales=[], selected=0, operation='Generate', minF=None, maxF=None):
170 | self.w = FloatingWindow((150, 300), minSize = (150, 150), maxSize = (150, 900))
171 | # self.w.lblLabel = TextBox((10, 5, 70, 47), 'Generate selected instances:')
172 | lwBorder = -120
173 | self.w.InstancesList = List((5, 5, -5, lwBorder), [],
174 | selectionCallback = self.selectionInstanceCallback)
175 | self.w.InstancesList.setSelection([selected])
176 |
177 | self.w.btnAction = Button((10, -32, -10, 22), operation, callback = self.btnActionCallback)
178 |
179 | self.w.chkKerning = CheckBox((10, lwBorder + 5, -10, 10), "Interpolate Kerning", value = True,
180 | sizeStyle = 'mini', callback = self.chkKerningCallback)
181 | self.w.chkDelSmallPairs = CheckBox((25, lwBorder + 20, -10, 10), "Delete small pairs", value = True,
182 | sizeStyle = 'mini', callback = self.chkDelSmallPairsCallback)
183 |
184 | self.w.lbl1 = TextBox((37, lwBorder + 37, 40, 15), 'from:', sizeStyle = 'mini')
185 | self.w.txtFrom = EditText((67, lwBorder + 35, 25, 15), '-5', sizeStyle = 'mini')
186 | self.w.lbl2 = TextBox((98, lwBorder + 37, 40, 15), 'to:', sizeStyle = 'mini')
187 | self.w.txtTo = EditText((115, lwBorder + 35, 25, 15), '5', sizeStyle = 'mini')
188 |
189 | self.w.chkReport = CheckBox((10, lwBorder + 53, -10, 10), "Make Report (slowly)", value = True,
190 | sizeStyle = 'mini')
191 | self.w.chkColorMark = CheckBox((10, lwBorder + 68, -10, 10), "Marks problem glyphs", value = True,
192 | sizeStyle = 'mini')
193 |
194 | # self.w.chkReport = CheckBox((10, 10, -10, 10), "Report", value=True, sizeStyle='mini')
195 |
196 |
197 | self.setListInstances(interpolationScales, selected)
198 | self.minFontName = minF
199 | self.maxFontName = maxF
200 |
201 | self.setUpBaseWindowBehavior()
202 | self.w.center()
203 | self.w.show()
204 |
205 | def setDelSmallPairs (self, value=True):
206 | if value:
207 | self.w.txtFrom.enable(True)
208 | self.w.lbl1.enable(True)
209 | self.w.lbl2.enable(True)
210 | self.w.txtTo.enable(True)
211 | self.w.txtFrom.set('-5')
212 | self.w.txtTo.set('5')
213 | else:
214 | self.w.txtFrom.enable(False)
215 | self.w.lbl1.enable(False)
216 | self.w.lbl2.enable(False)
217 | self.w.txtTo.enable(False)
218 | self.w.txtFrom.set('-5')
219 | self.w.txtTo.set('5')
220 |
221 | def chkDelSmallPairsCallback (self, sender):
222 | if self.w.chkDelSmallPairs.get():
223 | self.setDelSmallPairs(True)
224 | else:
225 | self.setDelSmallPairs(False)
226 |
227 | def chkKerningCallback (self, sender):
228 | if self.w.chkKerning.get():
229 | self.w.chkDelSmallPairs.enable(True)
230 | self.w.chkDelSmallPairs.set(True)
231 | self.setDelSmallPairs(True)
232 | else:
233 | self.w.chkDelSmallPairs.enable(False)
234 | self.w.chkDelSmallPairs.set(False)
235 | self.setDelSmallPairs(False)
236 |
237 |
238 | def InterpolateInstances (self, scale):
239 | glyphlist = []
240 | minFamily, minStyle = self.minFontName
241 | maxFamily, maxStyle = self.maxFontName
242 |
243 | _report = self.w.chkReport.get()
244 | _kerning = self.w.chkKerning.get()
245 | _deletesmallpairs = self.w.chkDelSmallPairs.get()
246 | _mark = self.w.chkColorMark.get()
247 |
248 | if is_number(self.w.txtFrom.get()):
249 | _lowpair = int(self.w.txtFrom.get())
250 | else:
251 | _deletesmallpairs = False
252 | print 'Wrong number!', _lowpair
253 | if is_number(self.w.txtTo.get()):
254 | _highpair = int(self.w.txtTo.get())
255 | else:
256 | _deletesmallpairs = False
257 | print 'Wrong number!', _highpair
258 |
259 | glyphlist = InterpolationLib.checkCompatibilityConsole(
260 | listfonts.getFontsByFamilyNameStyleName(minFamily, minStyle),
261 | listfonts.getFontsByFamilyNameStyleName(maxFamily, maxStyle),
262 | mark = _mark,
263 | report = _report)
264 |
265 | InterpolationLib.InterpolateFonts(listfonts.getFontsByFamilyNameStyleName(minFamily, minStyle),
266 | listfonts.getFontsByFamilyNameStyleName(maxFamily, maxStyle),
267 | compatibleGlyphs = glyphlist,
268 | intrepolateScale = scale,
269 | kerning = _kerning,
270 | deletesmallpairs = _deletesmallpairs,
271 | lowpair = _lowpair,
272 | highpair = _highpair)
273 |
274 |
275 | def selectionInstanceCallback (self, sender):
276 | pass
277 |
278 | def setListInstances (self, interpolationScales=[], selected=0):
279 | self.w.InstancesList.set([])
280 | for i in interpolationScales:
281 | ins = str(int(i * 1000))
282 | self.w.InstancesList.append(ins)
283 | self.w.InstancesList.setSelection([selected])
284 | self.w.InstancesList.scrollToSelection()
285 | self.w.InstancesList.remove('0')
286 | self.w.InstancesList.remove('1000')
287 |
288 | def getSelectedInstances (self):
289 | selectedInstances = []
290 | sellist = self.w.InstancesList.getSelection()
291 | for i in sellist:
292 | selectedInstances.append(round(float(self.w.InstancesList[i]) / 1000, 3))
293 | return selectedInstances
294 |
295 | def windowCloseCallback (self, sender):
296 | super(InstancesSelector, self).windowCloseCallback(sender)
297 |
298 | def btnActionCallback (self, sender):
299 | scale = []
300 | scale = self.getSelectedInstances()
301 | self.w.hide()
302 | self.InterpolateInstances(scale)
303 |
304 |
305 | def __init__ (self, font):
306 | self.interpolatingSteps = 5
307 | self.pointSize = 150
308 | self.viewMode = viewFull
309 | self.resizeInProgress = False
310 |
311 | self.w = Window((1000, 450), minSize = (400, 150), title = 'Interpolation Tool (beta 0.8.72)')
312 |
313 | # Upper panel
314 |
315 | self.w.p1 = Group((0, 0, -0, 100))
316 | self.w.p1.lblMethod = TextBox((10, 23, 70, 17), 'Method')
317 | self.w.p1.radioSelectMethod = RadioGroup((70, 5, 160, 55), #(70, 1, 160, 65)
318 | ["Luc(as) de Groot", "Pablo Impallari", "Linear"], #,"Manual"],
319 | sizeStyle = 'small',
320 | callback = self.radioSelectMethodCallback)
321 |
322 | # self.w.p1.txtStemsLine =
323 |
324 | self.w.p1.radioSelectMethod.set(0)
325 | self.w.p1.vline = VerticalLine((210, 6, 1, 53))
326 |
327 | self.w.p1.hline = HorizontalLine((10, 65, -10, 1))
328 | self.w.p1.lblAxis0001 = TextBox((230, 12, 100, 17), "Axis 00/01")
329 |
330 | self.w.p1.lblMinFont = TextBox((10, 75, 60, 17), "Axis 00")
331 | self.w.p1.cbMinFont = ComboBox((70, 72, 200, 21),
332 | getListOfOpenFonts(),
333 | callback = self.cbSelectFontCallback)
334 | self.w.p1.lblMaxFont = TextBox((-270, 75, 60, 17), "Axis 01")
335 | self.w.p1.cbMaxFont = ComboBox((-210, 72, 200, 21),
336 | getListOfOpenFonts(),
337 | callback = self.cbSelectFontCallback)
338 | self.w.p1.btnAddLowExtra = Button((280, 73, 100, 20), "- 100 Extra", #48
339 | callback = self.btnAddLowExtraCallback)
340 | self.w.p1.btnAddHighExtra = Button((-380, 73, 100, 20), "+ 500 Extra", #48
341 | callback = self.btnAddHighExtraCallback)
342 |
343 | self.w.p1.btnAddStep = Button((300, 35, 60, 20), "+ step", #48
344 | callback = self.btnAddStepCallback)
345 | self.w.p1.btnDelStep = Button((230, 35, 60, 20), "- step",
346 | callback = self.btnDelStepCallback)
347 | self.w.p1.vline2 = VerticalLine((380, 6, 1, 53))
348 |
349 | # Glyphs lineview
350 |
351 | self.w.lineView = MultiLineView((0, 100, -0, -80),
352 | pointSize = self.pointSize,
353 | lineHeight = self.pointSize * 1.75,
354 | bordered = True,
355 | hasVerticalScroller = True,
356 | # displayOptions = dict(previewOptions),
357 | selectionCallback = self.lineViewSelectionCallback)
358 |
359 | self.w.lblStatus = TextBox((15, -105, -20, 17), 'Status bar')
360 | self.w.lineView.setFont(font)
361 |
362 | # View panel
363 |
364 | self.w.pV = Group((-270, 12, 250, 100))
365 | segments = [{'width': 40, 'title': 'Full'}, {'width': 40, 'title': 'Short'}]
366 | yPosV = 10
367 | xPosV = 0
368 | self.w.pV.btnPreviwGlyphSmall = Button((0, yPosV + 3, 65, 14), 'Preview...',
369 | sizeStyle = 'mini',
370 | callback = self.btnPreviwButtonCallback)
371 | self.w.pV.btnSwitchViewMode = SegmentedButton((70, yPosV, 90, 20),
372 | segmentDescriptions = segments,
373 | selectionStyle = 'one', sizeStyle = 'mini', #48
374 | callback = self.btnSwitchViewMode)
375 | self.w.pV.btnSwitchViewMode.set(0)
376 | self.w.pV.lblGlyphBtnHint = TextBox((15, 0, 100, 12), "Glyph", sizeStyle = 'mini')
377 |
378 | self.w.pV.lblViewMode = TextBox((85, 0, 100, 12), "View mode", sizeStyle = 'mini')
379 | self.w.pV.lblPointSize = TextBox((175, 0, 100, 12), "Preview size", sizeStyle = 'mini')
380 | self.w.pV.sliderPointSize = Slider((165, yPosV + 3, 80, 17),
381 | stopOnTickMarks = False,
382 | callback = self.sliderPointSizeCallback,
383 | sizeStyle = 'mini')
384 | self.w.pV.sliderPointSize.enable(True)
385 | self.w.pV.sliderPointSize.setMinValue(72)
386 | self.w.pV.sliderPointSize.setMaxValue(512)
387 | self.w.pV.sliderPointSize.set(self.pointSize)
388 | self.w.pV.lblGlyphBtnHint.show(False)
389 | self.w.pV.btnPreviwGlyphSmall.show(False)
390 |
391 | # Bottom panel
392 |
393 | self.w.p2 = Group((0, -80, -0, -0))
394 | self.w.p2.lblTuner0001 = TextBox((10, -68, 100, 17), "Tuner 00/01")
395 | self.w.p2.sliderFactor = Slider((110, -65, 210, 23),
396 | tickMarkCount = 2,
397 | stopOnTickMarks = False,
398 | callback = self.sliderFactorCallback)
399 | self.w.p2.sliderFactor.enable(False)
400 | self.w.p2.sliderFactor.setMinValue(0)
401 | self.w.p2.sliderFactor.setMaxValue(1000)
402 | self.w.p2.sliderFactor.set(500)
403 | self.w.p2.lblMin = TextBox((110, -38, 70, 17), '0', alignment = 'left')
404 | self.w.p2.lblMax = TextBox((250, -38, 70, 17), '1000', alignment = 'right')
405 | self.w.p2.lblCurrent = TextBox((185, -38, 60, 17), '500', alignment = 'center')
406 | self.w.p2.lblMin.show(False)
407 | self.w.p2.lblMax.show(False)
408 | self.w.p2.lblCurrent.show(False)
409 |
410 | self.w.p2.vline3 = VerticalLine((340, -73, 1, -10))
411 |
412 | self.w.p2.btnPreviwGlyph = Button((360, -70, 130, 20), "Preview glyph...",
413 | callback = self.btnPreviwButtonCallback)
414 | self.w.p2.btnDeleteInstance = Button((360, -40, 130, 20), "Delete Instance",
415 | callback = self.btnDeleteInstanceCallback)
416 | self.w.p2.spinner = ProgressSpinner((503, 20, 32, 32),
417 | displayWhenStopped = False)
418 | # self.w.p2.btnGenerateSeleced = Button((-220, -70, -10, 20), "Generate Selected Instance...",
419 | # callback=self.btnGenerateSelectedCallback)
420 | self.w.p2.btnGenerateAll = Button((-220, -40, -10, 20), "Generate Instances...",
421 | callback = self.btnGenerateAllCallback)
422 | # self.w.p2.btnGenerateSeleced.enable(False)
423 | self.w.p2.btnGenerateAll.enable(False)
424 | self.w.p2.btnDeleteInstance.enable(False)
425 |
426 | # Init section
427 |
428 | self.minFont = None
429 | self.minFontName = []
430 | self.maxFont = None
431 | self.minFontName = []
432 | self.DDfont = OpenFont(DDfontPath, showUI = False)
433 |
434 | self.indexSelectedGlyph = None
435 | self.interpolateMethod = intLucas
436 | self.setInterpolateScale()
437 | self.drawGlyphsLine(dict(glyph = None))
438 |
439 | self.w.bind('resize', self.windowResize)
440 | events.addObserver(self, "drawMessagePreviewOnly", 'draw')
441 | events.addObserver(self, "drawGlyphsLine", "currentGlyphChanged")
442 | events.addObserver(self, "drawGlyphsLine", "draw")
443 |
444 | self.setUpBaseWindowBehavior()
445 | self.w.center()
446 | self.w.open()
447 |
448 | def changeViewMode (self):
449 | wS = self.w.getPosSize()
450 | lS = self.w.lineView.getPosSize()
451 | self.resizeInProgress = True
452 | if self.viewMode == viewShort:
453 | self.w.pV.setPosSize((-270, 2, 250, 100))
454 | self.w.p1.show(False)
455 | self.w.pV.lblGlyphBtnHint.show(True)
456 | self.w.pV.btnPreviwGlyphSmall.show(True)
457 | self.w.lineView.setPosSize((0, 0, -0, -0))
458 | self.w.p2.show(False)
459 | hW = wS[3] + lS[3] - lS[1]
460 | self.w.resize(wS[2], hW)
461 | else:
462 | self.w.pV.setPosSize((-270, 12, 250, 100))
463 | self.w.p1.show(True)
464 | self.w.p2.show(True)
465 | self.w.pV.lblGlyphBtnHint.show(False)
466 | self.w.pV.btnPreviwGlyphSmall.show(False)
467 | if wS[2] < 770:
468 | hW = 770
469 | else:
470 | hW = wS[2]
471 | self.w.resize(hW, wS[3] + 180)
472 | self.w.lineView.setPosSize((0, 100, -0, -80))
473 | self.resizeInProgress = False
474 |
475 | def btnSwitchViewMode (self, sender):
476 | if sender.get() != self.viewMode:
477 | self.viewMode = sender.get()
478 | self.changeViewMode()
479 |
480 | def windowResize (self, sender):
481 | wS = self.w.getPosSize()
482 | if (wS[3] < 313) or (wS[2] < 770):
483 | if not self.resizeInProgress:
484 | self.viewMode = viewShort
485 | self.w.pV.btnSwitchViewMode.set(1)
486 | self.changeViewMode()
487 |
488 | def windowCloseCallback (self, sender):
489 | events.removeObserver(self, "draw")
490 | events.removeObserver(self, "currentGlyphChanged")
491 | super(InterpolationWindow, self).windowCloseCallback(sender)
492 |
493 | def drawMessagePreviewOnly (self, info):
494 | glyph = info["glyph"]
495 | if self.minFont.has_key(glyph.name) and self.maxFont.has_key(glyph.name): pass
496 | else:
497 | r = 0
498 | g = 0
499 | b = 0
500 | a = .5
501 | font("Menlo", 20)
502 | stroke(None)
503 | fill(r, g, b, a)
504 | text('Preview ONLY. Any changes will be lost.', (20, -40))
505 |
506 | def sliderPointSizeCallback (self, sender):
507 | self.pointSize = sender.get()
508 | self.drawGlyphsLine(dict(glyph = CurrentGlyph()))
509 |
510 | def btnAddLowExtraCallback (self, sender):
511 | minf = self.interpolateScale[0]
512 | self.interpolateScale.insert(0, minf - .1)
513 | self.indexSelectedGlyph = None
514 | self.drawGlyphsLine(dict(glyph = CurrentGlyph()))
515 |
516 | def btnAddHighExtraCallback (self, sender):
517 | maxf = self.interpolateScale[-1]
518 | self.interpolateScale.append(maxf + .5)
519 | self.indexSelectedGlyph = None
520 | self.drawGlyphsLine(dict(glyph = CurrentGlyph()))
521 |
522 | def btnDeleteInstanceCallback (self, sender):
523 | self.interpolateScale.pop(self.indexSelectedGlyph)
524 | self.indexSelectedGlyph = None
525 | self.drawGlyphsLine(dict(glyph = CurrentGlyph()))
526 |
527 | def sliderFactorCallback (self, sender):
528 | if self.indexSelectedGlyph != None:
529 | factor = round(float(sender.get()) / 1000, 3)
530 | # if factor != 1000:
531 | self.interpolateScale[self.indexSelectedGlyph] = factor
532 | # else:
533 | # self.interpolateScale[self.indexSelectedGlyph] = factor + 1
534 | self.w.p2.lblCurrent.set(str(int(factor * 1000)))
535 | self.drawGlyphsLine(dict(glyph = CurrentGlyph()))
536 |
537 | def blockSlider (self, showFactor=0):
538 | self.w.p2.lblMin.set(0)
539 | self.w.p2.lblMax.set(10)
540 | self.w.p2.sliderFactor.set(5)
541 | self.w.p2.lblMin.show(False)
542 | self.w.p2.lblMax.show(False)
543 | self.w.p2.sliderFactor.enable(False)
544 | self.w.p2.lblCurrent.show(True)
545 | self.w.p2.lblCurrent.set(str(showFactor))
546 |
547 | # self.w.p2.btnGenerateSeleced.enable(False)
548 |
549 |
550 | def openSelectedGlyph (self):
551 | cg = CurrentGlyph()
552 | minFamily, minStyle = self.minFontName
553 | maxFamily, maxStyle = self.maxFontName
554 | lineGlyphs = self.w.lineView.get()
555 | selectedname = lineGlyphs[self.indexSelectedGlyph].name
556 | if selectedname != '0' and selectedname != '1000':
557 | tempname = cg.name + '.' + selectedname + '.Preview.'
558 | self.DDfont.newGlyph(tempname, clear = True)
559 | self.DDfont[tempname] = self.DDfont[selectedname].copy()
560 | for c in self.DDfont[tempname].components:
561 | self.DDfont[tempname].removeComponent(c)
562 | self.DDfont.round()
563 | OpenGlyphWindow(self.DDfont[tempname])
564 | elif selectedname == '0':
565 | OpenGlyphWindow(listfonts.getFontsByFamilyNameStyleName(minFamily, minStyle)[cg.name])
566 | elif selectedname == '1000':
567 | OpenGlyphWindow(listfonts.getFontsByFamilyNameStyleName(maxFamily, maxStyle)[cg.name])
568 |
569 | def btnPreviwButtonCallback (self, sender):
570 | self.openSelectedGlyph()
571 |
572 | def radioSelectMethodCallback (self, sender):
573 | self.interpolateMethod = sender.get()
574 | self.setInterpolateScale()
575 | self.drawGlyphsLine(dict(glyph = CurrentGlyph()))
576 |
577 | def btnAddStepCallback (self, sender):
578 | self.interpolatingSteps = self.interpolatingSteps + 1
579 | self.setInterpolateScale()
580 | self.indexSelectedGlyph = None
581 | self.drawGlyphsLine(dict(glyph = CurrentGlyph()))
582 |
583 | def btnDelStepCallback (self, sender):
584 | if self.interpolatingSteps != 1:
585 | self.interpolatingSteps = self.interpolatingSteps - 1
586 | self.indexSelectedGlyph = None
587 | self.setInterpolateScale()
588 | self.drawGlyphsLine(dict(glyph = CurrentGlyph()))
589 |
590 |
591 | def interpolateFonts (self, scale=[]):
592 | pass
593 |
594 |
595 | # def btnGenerateSelectedCallback(self,sender):
596 | # self.interpolateFonts(selectedOnly = True)
597 |
598 | def btnGenerateAllCallback (self, sender):
599 | Selector = self.InstancesSelector(interpolationScales = self.interpolateScale,
600 | selected = self.indexSelectedGlyph,
601 | operation = "Generate",
602 | minF = self.minFontName,
603 | maxF = self.maxFontName)
604 |
605 | # print Selector.getSelectedInstances()
606 |
607 | # self.interpolateFonts(selectedOnly = False)
608 |
609 | def cbSelectFontCallback (self, sender):
610 | self.w.p2.spinner.start()
611 | lfonts = getListOfOpenFonts()
612 | if sender.get() in lfonts:
613 | l2 = []
614 | l1 = sender.get()
615 | l2 = l1.split('/')
616 | if sender == self.w.p1.cbMinFont:
617 | self.minFontName = l2
618 | self.minFont = listfonts.getFontsByFamilyNameStyleName(l2[0], l2[1]).copy()
619 | if sender == self.w.p1.cbMaxFont:
620 | self.maxFontName = l2
621 | self.maxFont = listfonts.getFontsByFamilyNameStyleName(l2[0], l2[1]).copy()
622 | self.drawGlyphsLine(dict(glyph = CurrentGlyph()))
623 | self.w.p2.spinner.stop()
624 |
625 | # def lineViewDoubleSelectionCallback (self, sender):
626 | # self.openSelectedGlyph()
627 |
628 | def lineViewSelectionCallback (self, sender):
629 | lineGlyphs = self.w.lineView.get()
630 | selGlyph = self.w.lineView.getSelectedGlyph()
631 | # self.nameOfSelectedGlyph = selGlyph.name
632 | if selGlyph != None:
633 | i = 0
634 | for g in lineGlyphs:
635 | if selGlyph.name == g.name:
636 | self.indexSelectedGlyph = i
637 | break
638 | i = i + 1
639 |
640 | factor = int(selGlyph.name)
641 | if (factor != 0) and (factor != 1000):
642 | self.w.p2.sliderFactor.enable(True)
643 |
644 | if factor > 1000:
645 | minf = int(lineGlyphs[self.indexSelectedGlyph - 1].name) + 10
646 | else:
647 | minf = int(lineGlyphs[self.indexSelectedGlyph - 1].name) + 1
648 |
649 | if factor < 1000:
650 | maxf = int(lineGlyphs[self.indexSelectedGlyph + 1].name) - 1
651 | else:
652 | if factor == int(lineGlyphs[-1].name):
653 | maxf = factor + 500
654 | else:
655 | maxf = int(lineGlyphs[self.indexSelectedGlyph + 1].name) - 1
656 |
657 | if factor < 0:
658 | maxf = int(lineGlyphs[self.indexSelectedGlyph + 1].name) - 1
659 | if factor == int(lineGlyphs[0].name):
660 | minf = factor - 100
661 | else:
662 | minf = int(lineGlyphs[self.indexSelectedGlyph - 1].name) + 1
663 |
664 | self.w.p2.sliderFactor.setMaxValue(maxf)
665 | self.w.p2.lblMax.set(str(maxf))
666 | self.w.p2.lblMax.show(True)
667 |
668 | self.w.p2.sliderFactor.setMinValue(minf)
669 | self.w.p2.lblMin.show(True)
670 | self.w.p2.lblMin.set(str(minf))
671 |
672 | self.w.p2.sliderFactor.set(factor)
673 | self.w.p2.lblCurrent.set(str(factor))
674 | self.w.p2.lblCurrent.show(True)
675 | self.w.pV.btnPreviwGlyphSmall.setTitle('Preview...')
676 | self.w.p2.btnPreviwGlyph.setTitle('Preview glyph...')
677 | self.w.p2.btnDeleteInstance.enable(True)
678 | # self.w.p2.btnGenerateSeleced.enable(True)
679 | else:
680 | self.w.p2.btnPreviwGlyph.setTitle('Edit glyph...')
681 | self.w.pV.btnPreviwGlyphSmall.setTitle('Edit...')
682 | self.w.p2.btnDeleteInstance.enable(False)
683 | self.blockSlider(factor)
684 |
685 | self.drawGlyphsLine(dict(glyph = CurrentGlyph()))
686 |
687 |
688 | def setInterpolateScale (self):
689 | if self.interpolateMethod == intLucas:
690 | self.interpolateScale = getLucasFactor(minStem, maxStem, self.interpolatingSteps)
691 | if self.interpolateMethod == intImpallari:
692 | self.interpolateScale = getImpallariFactor(minStem, maxStem, self.interpolatingSteps)
693 | if self.interpolateMethod == intLinear:
694 | self.interpolateScale = getLinearFactor(minStem, maxStem, self.interpolatingSteps)
695 | if self.interpolateMethod == intManual:
696 | self.interpolateScale = getFactorListByStems(ListManualStems)
697 |
698 | def drawGlyphsLine (self, info):
699 | self.w.lblStatus.set('')
700 | if self.minFont and self.maxFont:
701 | self.w.p2.btnGenerateAll.enable(True)
702 | if self.indexSelectedGlyph == None:
703 | self.blockSlider()
704 |
705 | glyph = CurrentGlyph()
706 | glyphs = []
707 |
708 | if glyph is not None:
709 | glyphName = glyph.name
710 | idx = 0
711 | if self.minFont.has_key(glyphName) and self.maxFont.has_key(glyphName):
712 | minFamily, minStyle = self.minFontName
713 | maxFamily, maxStyle = self.maxFontName
714 | self.minFont.removeGlyph(glyphName)
715 | self.maxFont.removeGlyph(glyphName)
716 | self.minFont.insertGlyph(listfonts.getFontsByFamilyNameStyleName(minFamily, minStyle)[glyphName],
717 | name = glyphName)
718 | self.maxFont.insertGlyph(listfonts.getFontsByFamilyNameStyleName(maxFamily, maxStyle)[glyphName],
719 | name = glyphName)
720 | sg = decomposeGlyph(self.minFont[glyphName])
721 | dg = decomposeGlyph(self.maxFont[glyphName])
722 |
723 | ###
724 | # sg.leftMargin = 50
725 | # sg.rightMargin = 50
726 | # dg.leftMargin = 50
727 | # sg.rightMargin = 50
728 | ###
729 |
730 | for i in self.interpolateScale:
731 | gname = str(int(i * 1000))
732 | g = self.DDfont.newGlyph(gname, clear = True)
733 |
734 | isComp = sg.isCompatible(dg, True)
735 | if isComp[0]:
736 | g.interpolate(i, sg, dg)
737 | stname = getGlyphNameString(gname)
738 | ddXpos = 0
739 | ddYpos = -310
740 | if idx == self.indexSelectedGlyph:
741 | g.appendComponent('DDbracketleft', (ddXpos, ddYpos + 4 ), (.08, .08))
742 | ddXpos = ddXpos + 70
743 |
744 | for a in stname:
745 | g.appendComponent(a, (ddXpos, ddYpos), (.08, .08))
746 | ddXpos = ddXpos + 70
747 |
748 | if idx == self.indexSelectedGlyph:
749 | g.appendComponent('DDbracketright', (ddXpos, ddYpos + 4 ), (.08, .08))
750 |
751 | idx = idx + 1
752 | g.update()
753 | glyphs.append(g)
754 | else:
755 | # pass
756 | self.w.lblStatus.set(' '.join(isComp[1]))
757 |
758 | # self.w.lineView.setDisplayStates(previewOptions)
759 | self.w.lineView.setPointSize(self.pointSize)
760 | self.w.lineView.set(glyphs)
761 |
762 |
763 | InterpolationWindow(CurrentFont())
764 |
765 |
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/lib/ReportWindow.py:
--------------------------------------------------------------------------------
1 | #Embedded file name: /Users/alexander/Documents/WORKS/typedev/RoboFont/dev/OutputWindow.py
2 | """
3 | RoboFont Script
4 | ReportWindow.py
5 |
6 | Created by Alexander Lubovenko on 2013-10-24.
7 | http://github.com/typedev
8 | """
9 | from vanilla import *
10 | from AppKit import *
11 | # import codecs
12 | from time import asctime
13 | import sys, subprocess
14 |
15 | class ReportWindow(object):
16 |
17 | def __init__(self, titleReport = 'Report'):
18 | global _bufferTxT
19 | self.w = FloatingWindow((900, 500), title = titleReport, minSize=(360, 270))
20 | self.w.textBox = TextEditor((0, 0, 0, -50), '')
21 | self.w.textBox.getNSTextView().setRichText_(False)
22 | self.w.textBox.getNSTextView().setUsesFontPanel_(False)
23 | color = NSColor.colorWithCalibratedRed_green_blue_alpha_(20.0 / 255.0, 20.0 / 255.0, 20.0 / 255.0, 1)
24 | self.w.textBox.getNSTextView().setBackgroundColor_(color)
25 | self.w.textBox.getNSTextView().setTextColor_(NSColor.whiteColor())
26 | self.w.textBox.getNSTextView().setFont_(NSFont.fontWithName_size_('Menlo', 14))
27 | self.w.btnClose = Button((-80, -40, 65, 22), 'Close', callback=self.btnCloseCallback)
28 | self.w.center()
29 | self.report = []
30 |
31 | def btnCloseCallback(self, sender):
32 | self.w.hide()
33 |
34 | def showReport(self):
35 | text = '\n'.join(self.report)
36 | self.w.textBox.set(text)
37 | self.w.textBox.getNSTextView().scrollRangeToVisible_((len(text), 0))
38 | self.w.center()
39 | self.w.show()
40 |
41 | def addToReport(self, txt = ''):
42 | self.report.append(txt)
43 |
44 |
45 | if __name__ == '__main__':
46 | report = ReportWindow(titleReport = 'Test ReportWindow')
47 | for i in range(10):
48 | report.addToReport(str(i) +'. Test Report Window. '+asctime())
49 | # report.addToReport('Test Report Window 2'+asctime())
50 | report.showReport()
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/lib/tempfont.ufo/fontinfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ascender
6 | 770
7 | capHeight
8 | 700
9 | descender
10 | -230
11 | familyName
12 | Temporary Font
13 | italicAngle
14 | 0.0
15 | macintoshFONDFamilyID
16 | 128
17 | openTypeHeadLowestRecPPEM
18 | 9
19 | openTypeHheaAscender
20 | 885
21 | openTypeHheaDescender
22 | -235
23 | openTypeHheaLineGap
24 | 0
25 | openTypeNameLicenseURL
26 |
27 | openTypeOS2CodePageRanges
28 |
29 |
30 | openTypeOS2FamilyClass
31 |
32 | 0
33 | 0
34 |
35 | openTypeOS2Panose
36 |
37 | 2
38 | 6
39 | 5
40 | 9
41 | 2
42 | 2
43 | 5
44 | 2
45 | 2
46 | 4
47 |
48 | openTypeOS2StrikeoutPosition
49 | 250
50 | openTypeOS2StrikeoutSize
51 | 50
52 | openTypeOS2SubscriptXOffset
53 | 0
54 | openTypeOS2SubscriptXSize
55 | 650
56 | openTypeOS2SubscriptYOffset
57 | 75
58 | openTypeOS2SubscriptYSize
59 | 600
60 | openTypeOS2SuperscriptXOffset
61 | 0
62 | openTypeOS2SuperscriptXSize
63 | 650
64 | openTypeOS2SuperscriptYOffset
65 | 350
66 | openTypeOS2SuperscriptYSize
67 | 600
68 | openTypeOS2Type
69 |
70 |
71 | openTypeOS2TypoAscender
72 | 770
73 | openTypeOS2TypoDescender
74 | -230
75 | openTypeOS2TypoLineGap
76 | 120
77 | openTypeOS2UnicodeRanges
78 |
79 | 0
80 | 1
81 | 2
82 | 3
83 | 5
84 | 6
85 | 7
86 | 10
87 | 32
88 | 33
89 | 34
90 | 35
91 | 37
92 | 38
93 | 39
94 | 44
95 | 45
96 | 46
97 | 47
98 | 63
99 | 65
100 |
101 | openTypeOS2VendorID
102 | type
103 | openTypeOS2WeightClass
104 | 400
105 | openTypeOS2WidthClass
106 | 5
107 | openTypeOS2WinAscent
108 | 885
109 | openTypeOS2WinDescent
110 | 235
111 | postscriptBlueFuzz
112 | 1
113 | postscriptBlueScale
114 | 0.039625
115 | postscriptBlueShift
116 | 7
117 | postscriptBlueValues
118 |
119 |
120 | postscriptDefaultWidthX
121 | 500
122 | postscriptFamilyBlues
123 |
124 |
125 | postscriptFamilyOtherBlues
126 |
127 |
128 | postscriptForceBold
129 |
130 | postscriptIsFixedPitch
131 |
132 | postscriptOtherBlues
133 |
134 |
135 | postscriptSlantAngle
136 | 0.0
137 | postscriptStemSnapH
138 |
139 |
140 | postscriptStemSnapV
141 |
142 |
143 | postscriptUnderlinePosition
144 | -75
145 | postscriptUnderlineThickness
146 | 50
147 | postscriptUniqueID
148 | -1
149 | postscriptWindowsCharacterSet
150 | 1
151 | styleMapFamilyName
152 | Temporary Font Regular
153 | styleMapStyleName
154 | regular
155 | styleName
156 | Regular
157 | unitsPerEm
158 | 1000
159 | versionMajor
160 | 1
161 | versionMinor
162 | 3
163 | xHeight
164 | 500
165 | year
166 | 0
167 |
168 |
169 |
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/lib/tempfont.ufo/glyphs/DDbracketleft_.glif:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | com.typemytype.robofont.layerData
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/lib/tempfont.ufo/glyphs/DDbracketright_.glif:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | com.typemytype.robofont.layerData
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/lib/tempfont.ufo/glyphs/DDeight_.glif:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 | com.typemytype.robofont.layerData
99 |
100 |
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/lib/tempfont.ufo/glyphs/DDfive_.glif:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 | com.typemytype.robofont.layerData
46 |
47 |
48 |
49 |
50 |
51 |
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/lib/tempfont.ufo/glyphs/DDfour_.glif:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | com.typemytype.robofont.layerData
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/lib/tempfont.ufo/glyphs/DDminus_.glif:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | com.typemytype.robofont.layerData
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/lib/tempfont.ufo/glyphs/DDnine_.glif:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | com.typemytype.robofont.layerData
68 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/lib/tempfont.ufo/glyphs/DDone_.glif:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | com.typemytype.robofont.layerData
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/lib/tempfont.ufo/glyphs/DDseven_.glif:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | com.typemytype.robofont.layerData
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/lib/tempfont.ufo/glyphs/DDsix_.glif:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 | com.typemytype.robofont.layerData
74 |
75 |
76 |
77 |
78 |
79 |
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/lib/tempfont.ufo/glyphs/DDthree_.glif:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | com.typemytype.robofont.layerData
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/lib/tempfont.ufo/glyphs/DDtwo_.glif:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | com.typemytype.robofont.layerData
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/lib/tempfont.ufo/glyphs/DDzero_.glif:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | com.typemytype.robofont.layerData
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/lib/tempfont.ufo/glyphs/contents.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | DDbracketleft
6 | DDbracketleft_.glif
7 | DDbracketright
8 | DDbracketright_.glif
9 | DDeight
10 | DDeight_.glif
11 | DDfive
12 | DDfive_.glif
13 | DDfour
14 | DDfour_.glif
15 | DDminus
16 | DDminus_.glif
17 | DDnine
18 | DDnine_.glif
19 | DDone
20 | DDone_.glif
21 | DDseven
22 | DDseven_.glif
23 | DDsix
24 | DDsix_.glif
25 | DDthree
26 | DDthree_.glif
27 | DDtwo
28 | DDtwo_.glif
29 | DDzero
30 | DDzero_.glif
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/lib/tempfont.ufo/lib.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.typedev.markers.groupsclear
6 | Cleared
7 | com.typemytype.robofont.compileSettings.autohint
8 |
9 | com.typemytype.robofont.compileSettings.checkOutlines
10 |
11 | com.typemytype.robofont.compileSettings.decompose
12 |
13 | com.typemytype.robofont.compileSettings.generateFormat
14 | 0
15 | com.typemytype.robofont.compileSettings.releaseMode
16 |
17 | com.typemytype.robofont.foreground.layerStrokeColor
18 |
19 | 0.5
20 | 0.0
21 | 0.5
22 | 0.7
23 |
24 | com.typemytype.robofont.italicSlantOffset
25 | 0
26 | com.typemytype.robofont.layerOrder
27 |
28 |
29 | com.typemytype.robofont.segmentType
30 | curve
31 | com.typemytype.robofont.shouldAddPointsInSplineConversion
32 |
33 | com.typemytype.robofont.sort
34 |
35 |
36 | ascending
37 |
38 | zero
39 | one
40 | two
41 | three
42 | four
43 | five
44 | six
45 | seven
46 | eight
47 | nine
48 | bracketleft
49 | bracketright
50 | minus
51 |
52 | type
53 | glyphList
54 |
55 |
56 | org.robofab.glyphOrder
57 |
58 | bracketleft
59 | bracketright
60 | eight
61 | five
62 | four
63 | nine
64 | one
65 | seven
66 | six
67 | three
68 | two
69 | zero
70 |
71 | public.glyphOrder
72 |
73 | zero
74 | one
75 | two
76 | three
77 | four
78 | five
79 | six
80 | seven
81 | eight
82 | nine
83 | bracketleft
84 | bracketright
85 | minus
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/Interpolation Tool/Interpolation Tool (beta).roboFontExt/lib/tempfont.ufo/metainfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | creator
6 | org.robofab.ufoLib
7 | formatVersion
8 | 2
9 |
10 |
11 |
--------------------------------------------------------------------------------
/LatCyrl-CharacterSet-RF.txt:
--------------------------------------------------------------------------------
1 | space exclam quotesingle quotedbl numbersign dollar percent ampersand parenleft parenright asterisk plus comma hyphen period slash zero one two three four five six seven eight nine colon semicolon less equal greater question at A B C D E F G H I J K L M N O P Q R S T U V W X Y Z bracketleft backslash bracketright asciicircum underscore grave a b c d e f g h i j k l m n o p q r s t u v w x y z braceleft bar braceright asciitilde exclamdown cent sterling currency yen brokenbar section dieresis copyright ordfeminine guillemotleft logicalnot registered macron degree plusminus twosuperior threesuperior acute mu paragraph periodcentered cedilla onesuperior ordmasculine guillemotright onequarter onehalf threequarters questiondown Agrave Aacute Acircumflex Atilde Adieresis Aring AE Ccedilla Egrave Eacute Ecircumflex Edieresis Igrave Iacute Icircumflex Idieresis Eth Ntilde Ograve Oacute Ocircumflex Otilde Odieresis multiply Oslash Ugrave Uacute Ucircumflex Udieresis Yacute Thorn germandbls agrave aacute acircumflex atilde adieresis aring ae ccedilla egrave eacute ecircumflex edieresis igrave iacute icircumflex idieresis eth ntilde ograve oacute ocircumflex otilde odieresis divide oslash ugrave uacute ucircumflex udieresis yacute thorn ydieresis dotlessi circumflex caron breve dotaccent ring ogonek tilde hungarumlaut quoteleft quoteright minus u00A0|00A0 afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10023 afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030 afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037 afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044 afii10045 afii10046 afii10047 afii10048 afii10049 afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10071 afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078 afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085 afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092 afii10093 afii10094 afii10095 afii10096 afii10097 afii10051 afii10099 afii10050 afii10055 afii10052 afii10100 afii10103 afii10098 afii10057 afii10053 afii10101 afii10056 afii10104 afii10058 afii10106 afii10059 afii10107 afii10105 afii10054 afii10060 afii10108 afii10061 afii10109 afii10102 afii10062 afii10110 afii10145 afii10193 afii10146 afii10194 afii10147 afii10195 afii10148 afii10196 afii61352
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | typedev RoboFont scripts and Extensions
2 | ========
3 |
4 | A collection of free and open-source RoboFont extensions and scripts.
5 | --------
6 |
7 |
8 |
9 | ## MIT License
10 |
11 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
16 |
--------------------------------------------------------------------------------
/Show all glyphs.py:
--------------------------------------------------------------------------------
1 | # RoboFont Script
2 | # Just one click to show all ready glyphs in SpaceCenter
3 | # Alexander Lubovenko
4 | # http://github.com/typedev
5 |
6 | from mojo.UI import *
7 |
8 | font = CurrentFont()
9 |
10 | a=[]
11 | for i in font:
12 | if i:
13 | a.append(i.name)
14 |
15 | OpenSpaceCenter(font)
16 | SC = CurrentSpaceCenter()
17 | SC.set(a)
18 |
--------------------------------------------------------------------------------
/TestInstallAdvanced.py:
--------------------------------------------------------------------------------
1 | # RoboFont Script
2 | # Install current font with empty glyphs. It is useful when you are testing font in InDesign
3 | # Alexander Lubovenko
4 | # http://github.com/typedev
5 |
6 | from robofab.world import CurrentFont
7 |
8 |
9 | s = 'space exclam quotesingle quotedbl numbersign dollar percent ampersand parenleft parenright asterisk plus comma hyphen period slash zero one two three four five six seven eight nine colon semicolon less equal greater question at A B C D E F G H I J K L M N O P Q R S T U V W X Y Z bracketleft backslash bracketright asciicircum underscore grave a b c d e f g h i j k l m n o p q r s t u v w x y z braceleft bar braceright asciitilde exclamdown cent sterling currency yen brokenbar section dieresis copyright ordfeminine guillemotleft logicalnot registered macron degree plusminus twosuperior threesuperior acute mu paragraph periodcentered cedilla onesuperior ordmasculine guillemotright onequarter onehalf threequarters questiondown Agrave Aacute Acircumflex Atilde Adieresis Aring AE Ccedilla Egrave Eacute Ecircumflex Edieresis Igrave Iacute Icircumflex Idieresis Eth Ntilde Ograve Oacute Ocircumflex Otilde Odieresis multiply Oslash Ugrave Uacute Ucircumflex Udieresis Yacute Thorn germandbls agrave aacute acircumflex atilde adieresis aring ae ccedilla egrave eacute ecircumflex edieresis igrave iacute icircumflex idieresis eth ntilde ograve oacute ocircumflex otilde odieresis divide oslash ugrave uacute ucircumflex udieresis yacute thorn ydieresis dotlessi circumflex caron breve dotaccent ring ogonek tilde hungarumlaut quoteleft quoteright minus u00A0|00A0 afii10017 afii10018 afii10019 afii10020 afii10021 afii10022 afii10023 afii10024 afii10025 afii10026 afii10027 afii10028 afii10029 afii10030 afii10031 afii10032 afii10033 afii10034 afii10035 afii10036 afii10037 afii10038 afii10039 afii10040 afii10041 afii10042 afii10043 afii10044 afii10045 afii10046 afii10047 afii10048 afii10049 afii10065 afii10066 afii10067 afii10068 afii10069 afii10070 afii10071 afii10072 afii10073 afii10074 afii10075 afii10076 afii10077 afii10078 afii10079 afii10080 afii10081 afii10082 afii10083 afii10084 afii10085 afii10086 afii10087 afii10088 afii10089 afii10090 afii10091 afii10092 afii10093 afii10094 afii10095 afii10096 afii10097 afii10051 afii10099 afii10050 afii10055 afii10052 afii10100 afii10103 afii10098 afii10057 afii10053 afii10101 afii10056 afii10104 afii10058 afii10106 afii10059 afii10107 afii10105 afii10054 afii10060 afii10108 afii10061 afii10109 afii10102 afii10062 afii10110 afii10145 afii10193 afii61352'
10 |
11 | ng = s.split(' ')
12 |
13 | font = CurrentFont()
14 |
15 | for gname in ng:
16 | if gname not in font.keys():
17 | d = RGlyph()
18 | font[gname] = d
19 | missglyph = font[gname]
20 | missglyph.width = 0
21 | missglyph.update()
22 |
23 | font.update()
24 |
25 | font.testInstall()
26 |
27 | glyphOrder = font.glyphOrder
28 |
29 | for gname in ng:
30 | if font[gname].width == 0:
31 | font.removeGlyph(gname)
32 |
33 | font.glyphOrder = glyphOrder
34 | font.update()
35 |
--------------------------------------------------------------------------------
/Version Control/README.md:
--------------------------------------------------------------------------------
1 | # Version Control RoboFont Extension
2 |
3 | Version Control allows saving the current glyph as version and managing these versions.
For example, if you draw a glyph and doubt in correctness of current position you can save it as the version and continue drawing. Then, if necessary, return to any previous versions, manage them, compare with current or view all glyph revisions in SpaceCenter, replace the drawing of current glyph with version\`s drawing or delete it.
4 |
5 |
> The number of versions for each glyph is to 999. Versions of the glyphs are stored in the glyph general table with names GlyphName.ver.XXX - where XXX is the version number from 001 to 999. If necessary, they can be manually removed, as usual glyphs.
6 |
7 | 
8 |
9 |
1. Preview of the selected version
10 |
11 |
2. Versions list of the current glyph.
12 | Edit window of glyph version is opened by double-click
13 |
14 |
3. Note field
15 |
16 |
4. Save the current glyph as version
17 |
18 |
5. Remove the selected glyph version
19 |
20 |
6. Replace the current glyph`s drawing with the selected version. The current glyph will be saved instead of the selected version.
21 |
7. View all glyph versions in SpaceCenter
22 |
23 | ## Installation
24 | Double click VersionControl.roboFontExt
## MIT License
25 |
26 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
27 |
28 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
29 |
30 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/Version Control/VersionControl.roboFontExt/html/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | README
7 |
8 |
20 |
21 |
22 |
23 |
24 |
Version Control RoboFont Extension
25 |
26 |
Version Control allows saving the current glyph as version and managing these versions.
27 | For example, if you draw a glyph and doubt in correctness of current position you can save it as the version and continue drawing. Then, if necessary, return to any previous versions, manage them, compare with current or view all glyph revisions in SpaceCenter, replace the drawing of current glyph with version`s drawing or delete it.
28 |
29 |
30 | The number of versions for each glyph is to 999. Versions of the glyphs are stored in the glyph general table with names GlyphName.ver.XXX - where XXX is the version number from 001 to 999. If necessary, they can be manually removed, as usual glyphs.
31 |
32 |
33 |
34 |
35 | Version Control window
36 |
37 |
38 |
39 |
40 | Preview of the selected version
41 | Versions list of the current glyph.
42 | Edit window of glyph version is opened by double-click
43 | Note field
44 | Save the current glyph as version
45 | Remove the selected glyph version
46 | Replace the current glyph`s drawing with the selected version. The current glyph will be saved instead of the selected version.
47 | View all glyph versions in SpaceCenter
48 |
49 |
50 |
Installation
51 |
52 |
Double click VersionControl.roboFontExt
53 |
54 |
MIT License
55 |
56 |
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
57 |
58 |
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
59 |
60 |
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
61 |
62 |
63 |
--------------------------------------------------------------------------------
/Version Control/VersionControl.roboFontExt/info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | addToMenu
6 |
7 |
8 | path
9 | VersionControl.py
10 | preferredName
11 | Version Control
12 | shortKey
13 |
14 |
15 |
16 | developer
17 | Alexander Lubovenko
18 | developerURL
19 | https://github.com/typedev
20 | html
21 |
22 | launchAtStartUp
23 | 0
24 | mainScript
25 |
26 | name
27 | VersionControl
28 | requiresVersionMajor
29 | 1
30 | requiresVersionMinor
31 | 4
32 | timeStamp
33 | 1377714391.681957
34 | version
35 | 1.2
36 | repository
37 | typedev/RoboFont
38 | extensionPath
39 | Version Control/VersionControl.roboFontExt
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Version Control/VersionControl.roboFontExt/lib/VersionControl.py:
--------------------------------------------------------------------------------
1 | # RoboFont Script
2 | # Version Control
3 | # Alexander Lubovenko
4 | # http://github.com/typedev
5 |
6 | from mojo.UI import *
7 | from vanilla import *
8 | from mojo.glyphPreview import GlyphPreview
9 | from mojo.events import addObserver, removeObserver
10 | from mojo.roboFont import OpenWindow
11 | from time import asctime
12 |
13 |
14 | libVC = 'com.typedev.version_control.'
15 | font = CurrentFont()
16 |
17 | def getVersionNumber(glyphName):
18 | libKey = libVC + glyphName
19 | if font.lib.has_key(libKey):
20 | font.lib[libKey] = font.lib[libKey] + 1
21 | else:
22 | font.lib[libKey] = 1
23 | return font.lib[libKey]
24 |
25 |
26 | def setVersionNumber(glyphName, versionNumber = 0):
27 | libKey = libVC + glyphName
28 | font.lib[libKey] = versionNumber
29 |
30 |
31 | def checkVersionNumbers():
32 | gversions = []
33 | for g in font:
34 | if '.ver.' not in g.name:
35 | gversions = GetListVersions(g.name)
36 | if gversions != []:
37 | gname = gversions[-1]
38 | a = gname.split('.')
39 | lastnumber = int(a[-1])
40 | setVersionNumber( g.name, lastnumber )
41 | else:
42 | setVersionNumber( g.name )
43 |
44 |
45 | def cloneGlyph(glyph,name=''):
46 | if name == '':
47 | oldname = glyph.name
48 | else:
49 | oldname = name
50 | i = getVersionNumber(oldname)
51 | newName = oldname+'.ver.'+'%03d' % i
52 | font.insertGlyph(glyph,newName)
53 | font.update()
54 | font[newName].note = 'Version created ' + asctime()
55 | font[newName].update()
56 | font.update()
57 |
58 | def GetListVersions(glyphName):
59 | gversions = []
60 | if '.ver.' in glyphName:
61 | selname = glyphName.split('.')
62 | if 'ver' == selname[-2]:
63 | selname.pop()
64 | selname.pop()
65 | glyphName='.'.join(selname)
66 | gversions.append(glyphName)
67 | for g in font:
68 | if (glyphName + '.ver.') in g.name:
69 | gversions.append(g.name)
70 | gversions.sort()
71 | return gversions
72 |
73 |
74 | class VersionControl:
75 |
76 | def __init__(self):
77 |
78 | self.w = FloatingWindow((250, 530),minSize=(200, 400),title = 'Version Control')
79 |
80 | self.PreviewPanel = Group((0, 0, -0, -0))
81 | self.PreviewPanel.Preview = GlyphPreview((0, 0, -15, 0))
82 | self.PreviewPanel.GlyphInfo = TextBox((5, -13, 0, 12), '', alignment='left', selectable=False, sizeStyle='mini')
83 | self.PreviewPanel.hline = HorizontalLine((5, -1, -5, 1))
84 | self.Control = Group((0, 0, -0, -0))
85 |
86 | self.Control.VersionsList = List((0, 30, -0, -0), [], allowsMultipleSelection = False,
87 | selectionCallback=self.selectionVersionCallback,
88 | doubleClickCallback=self.selectionDoubleVersionCallback)
89 |
90 | self.Control.btnAdd = Button((5,5,30,20), '+', callback=self.btnAddCallback)
91 | self.Control.btnDel = Button((40,5,30,20), '-', callback=self.btnDelCallback)
92 | self.Control.btnSwap = Button((75,5,40,20), '<>', callback=self.btnSwapCallback)
93 | self.Control.btnShow = Button((120,5,40,20), 'Sc', callback=self.btnShowCallback)
94 |
95 | self.Note = TextEditor((5, 5, -5, -5))
96 |
97 | descriptions = [
98 | dict(label="Preview", view=self.PreviewPanel, size=320, collapsed=False, canResize=True),
99 | dict(label="Control", view=self.Control, minSize=100, size=140, collapsed=False, canResize=True),
100 | dict(label="Note", view=self.Note, minSize=100, size=140, collapsed=True, canResize=True),
101 | ]
102 |
103 |
104 |
105 | addObserver(self, "_currentGlyphChanged", "currentGlyphChanged")
106 | self.w.bind("close", self.windowClose)
107 | self.w.accordionView = AccordionView((0, 0, -0, -0), descriptions )
108 | checkVersionNumbers()
109 | self.updateVersionsList()
110 | self.w.open()
111 |
112 | def selectionVersionCallback(self, sender):
113 | idx = sender.getSelection()
114 | if idx != []:
115 | self.setGlyph( font[ self.Control.VersionsList[ idx[0] ] ] )
116 |
117 | def selectionDoubleVersionCallback(self, sender):
118 | idx = sender.getSelection()
119 | if idx != []:
120 | name = self.Control.VersionsList[idx [0]]
121 | SetCurrentGlyphByName(name)
122 | self.setGlyph( font[ name ] )
123 | OpenGlyphWindow( font[ name ] )
124 |
125 | def updateVersionsList(self):
126 | if CurrentGlyph() != None:
127 | self.setGlyph(CurrentGlyph())
128 | self.Control.VersionsList.set([])
129 | self.Control.VersionsList.set( GetListVersions( CurrentGlyph().name ) )
130 | if CurrentGlyph().name in self.Control.VersionsList:
131 | self.Control.VersionsList.setSelection([ self.Control.VersionsList.index(CurrentGlyph().name) ])
132 |
133 | def _currentGlyphChanged(self, info):
134 | self.updateVersionsList()
135 |
136 | def btnAddCallback(self, sender):
137 | glyph = CurrentGlyph()
138 | if '.ver.' in glyph.name:
139 | lname = glyph.name.split('.')
140 | if 'ver' == lname[-2]:
141 | lname.pop()
142 | lname.pop()
143 | sname='.'.join(lname)
144 | cloneGlyph(glyph,sname)
145 | else:
146 | cloneGlyph(glyph)
147 | font.update()
148 | self.updateVersionsList()
149 |
150 | def btnDelCallback(self, sender):
151 | idx = self.Control.VersionsList.getSelection()
152 | if idx != []:
153 | name = self.Control.VersionsList[idx [0]]
154 | if '.ver.' in name:
155 |
156 | aa = font.lib[ 'public.glyphOrder' ]
157 | if name in aa:
158 | aa.remove(name)
159 | font.lib[ 'public.glyphOrder' ] = aa
160 | font.removeGlyph (name)
161 | font.update()
162 |
163 | self.Control.VersionsList.remove(name)
164 | self.updateVersionsList()
165 |
166 | def btnSwapCallback(self, sender):
167 | idx = self.Control.VersionsList.getSelection()
168 | if idx != []:
169 | vName = self.Control.VersionsList[idx [0]]
170 | vGlyph = font[vName]
171 | vUcode = font[vName].unicode
172 |
173 | cGlyph = CurrentGlyph()
174 | cName = cGlyph.name
175 | cUcode = cGlyph.unicode
176 |
177 | if (vName != cName) and ('.ver.' not in cName):
178 | font.removeGlyph(cName)
179 | font.insertGlyph(vGlyph,cName)
180 | font[cName].unicode = cUcode
181 | font[cName].update()
182 | font.removeGlyph(vName)
183 | font.insertGlyph(cGlyph,vName)
184 | font[vName].update()
185 | font.glyphOrder = font.lib['public.glyphOrder']
186 | font.update()
187 | self.updateVersionsList()
188 | OpenGlyphWindow( font[ cName ] )
189 |
190 | def btnShowCallback(self, sender):
191 | cGlyph = CurrentGlyph().name
192 | gversions = GetListVersions(cGlyph)
193 | if gversions != []:
194 | OpenSpaceCenter(font)
195 | SC = CurrentSpaceCenter()
196 | if '.ver.' not in cGlyph:
197 | gversions.insert(0,cGlyph)
198 | SC.set(gversions)
199 |
200 |
201 | def setGlyph(self, glyph):
202 | self.PreviewPanel.GlyphInfo.set('')
203 | self.PreviewPanel.Preview.setGlyph(glyph)
204 | ucode = '-'
205 | if glyph.unicode != None:
206 | ucode = "%04X" % (glyph.unicode)
207 | gInfo = 'Glyph: ' + glyph.name + ' | U: '+ ucode + ' | Left: ' + str(int(round(glyph.leftMargin,0))) + ' | Right: ' + str(int(round(glyph.rightMargin)))
208 | self.PreviewPanel.GlyphInfo.set(gInfo)
209 | self.Note.set('')
210 | if glyph.note != None:
211 | self.Note.set(glyph.note)
212 |
213 | def windowClose(self, sender):
214 | removeObserver(self, "_currentGlyphChanged")
215 |
216 | VersionControl()
--------------------------------------------------------------------------------
/Version Control/doc/VersionControl-RobofontExtension.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/typedev/RoboFont/d74e13781b1685a28b1e6fe59f24a42f75d74432/Version Control/doc/VersionControl-RobofontExtension.pdf
--------------------------------------------------------------------------------
/checkOverlaping.py:
--------------------------------------------------------------------------------
1 | font = CurrentFont()
2 | total = len(font)
3 | count = total
4 | for glyph in font:
5 | print '%i/%i %s' % (count, total, glyph.name)
6 | glyph.removeOverlap()
7 | glyph.update()
8 | count -= 1
9 | print 'Done..'
--------------------------------------------------------------------------------
/drawReferenceGlyph.py:
--------------------------------------------------------------------------------
1 | """
2 | An example script of adding an observers and do *something*
3 |
4 | It draws a simple unicode reference of an existing installed font.
5 | """
6 |
7 | from mojo.events import addObserver
8 | from mojo.drawingTools import *
9 |
10 | class DrawReferenceGlyph(object):
11 |
12 | def __init__(self):
13 | addObserver(self, "drawReferenceGlyph", "draw")
14 |
15 | def drawReferenceGlyph(self, info):
16 |
17 | glyph = info["glyph"]
18 |
19 | r = 0
20 | g = 0
21 | b = 0
22 | a = .5
23 |
24 | if glyph is not None and glyph.unicode is not None:
25 | # if glyph.unicode is not None:
26 | t = unichr(glyph.unicode)
27 | font("Brill Roman", 100)
28 | stroke(None)
29 | fill(r, g, b, a)
30 | text(t, (glyph.width + 25, -120))
31 |
32 |
33 | DrawReferenceGlyph()
--------------------------------------------------------------------------------
/dump All-to-All to SpaceCenter.py:
--------------------------------------------------------------------------------
1 | # RoboFont Script
2 | # Generate dump text from the selected glyphs to SpaceCenter
3 | # Alexander Lubovenko
4 | # http://github.com/typedev
5 |
6 | from robofab.world import CurrentFont
7 | from mojo.UI import *
8 |
9 | font = CurrentFont()
10 |
11 | listglyphs = font.selection
12 |
13 | result = []
14 |
15 | for b in listglyphs:
16 | for i in listglyphs:
17 | result.append(i)
18 | result.append(b)
19 |
20 | OpenSpaceCenter(font)
21 | SC = CurrentSpaceCenter()
22 | SC.set(result)
23 |
24 |
--------------------------------------------------------------------------------
/getInterpolationFactorByStems.py:
--------------------------------------------------------------------------------
1 |
2 | # listStems string: 10 20 30 40=0 50 60 70 80 90 100=1 110 120
3 |
4 | ListManualStems = '48=0 74 94 128 165 192 218=1'
5 |
6 | def getFactorByStem (minStem, maxStem, midStem):
7 | if (midStem != 0) and (midStem != 1000):
8 | return 1000 * (midStem - minStem) / (maxStem - minStem)
9 | else:
10 | return midStem
11 |
12 |
13 | def getFactorListByStems (listStems):
14 | ld = listStems.split(' ')
15 | ls = []
16 | lf = []
17 | for i in ld:
18 | if '=' in i:
19 | lm = i.split('=')
20 | if lm[1] == '0':
21 | minStem = int(lm[0])
22 | ls.append(0)
23 | if lm[1] == '1':
24 | maxStem = int(lm[0])
25 | ls.append(1000)
26 | else:
27 | ls.append(int(i))
28 | for i in ls:
29 | lf.append(getFactorByStem(minStem, maxStem, i) / 1000.0)
30 | return lf
31 |
32 | stemslist = ListManualStems.split(' ')
33 | for idx, value in enumerate(stemslist):
34 | print 'stem\t', value
35 | print 'factor\t',getFactorListByStems(ListManualStems)[idx]
36 | # print ListManualStems.split(' ')
37 | # print getFactorListByStems(ListManualStems)
--------------------------------------------------------------------------------
/makeGroupsFromFeature.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | from robofab.world import CurrentFont
4 |
5 | font = CurrentFont()
6 |
7 | featxt = font.features.text
8 | featxt = ' '.join(featxt.split()).split(';')
9 | for id, line in enumerate(featxt):
10 | line = line.strip()
11 | if line.startswith('@'):
12 | a = line.split(' ')
13 | groupname = a[0].replace('@','')
14 | a.remove('=')
15 | a.remove('[')
16 | a.remove(']')
17 | content = a[1:]
18 | # print groupname, '>', content
19 |
20 | print 'New group created: ' + groupname
21 | font.groups[groupname] = content
22 |
--------------------------------------------------------------------------------
/makeTableAlltoAll.py:
--------------------------------------------------------------------------------
1 | font = CurrentFont()
2 |
3 | listglyphs = font.selection
4 |
5 | result = ''
6 |
7 | for b in listglyphs:
8 | gb = font[b].unicode
9 | for i in listglyphs:
10 | gi = font[i].unicode
11 | result = result + unichr(gb) + unichr(gi)
12 | result = result + '\n'
13 |
14 | print result
15 |
--------------------------------------------------------------------------------
/make_ALT_fea.py:
--------------------------------------------------------------------------------
1 | # Make AALT feature
2 | from robofab.world import CurrentFont
3 |
4 | font = CurrentFont()
5 |
6 | sfx_names = []
7 | print 'Available Suffixes in:', font
8 | for glyph in font:
9 | name = glyph.name
10 | if ('.' in name) and (name != '.notdef'):
11 | a = name.split('.')
12 | gname = a[0]
13 | sfx = a[1]
14 | if '.' + sfx not in sfx_names:
15 | sfx_names.append('.' + sfx)
16 | print sfx_names
17 |
18 | aaltdic = {}
19 | for glyph in font:
20 | if ('.' in glyph.name) and (glyph.name != '.notdef'):
21 | a = glyph.name.split('.')
22 | gname = a[0]
23 | if gname not in aaltdic:
24 | aaltdic[gname] = ['%s.' % gname + '.'.join(a[1:])]
25 | else:
26 | aaltdic[gname].append('%s.' % gname + '.'.join(a[1:]))
27 |
28 | print 'feature aalt {'
29 | for name, alts in sorted(aaltdic.items()):
30 | print '\tsub %s from [ %s ];' % (name, ' '.join(alts))
31 | print '} aalt;'
32 |
--------------------------------------------------------------------------------
/polygon selection tool/polygon-select.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/typedev/RoboFont/d74e13781b1685a28b1e6fe59f24a42f75d74432/polygon selection tool/polygon-select.png
--------------------------------------------------------------------------------
/polygon selection tool/polygonSelectionTool.py:
--------------------------------------------------------------------------------
1 | from mojo.events import EditingTool, installTool
2 | from mojo.drawingTools import *
3 | from AppKit import NSImage
4 | from fontTools.pens.cocoaPen import CocoaPen
5 |
6 | class PolygonSelectionTool(EditingTool):
7 |
8 | def setup(self):
9 | self.pen = None
10 | self._oldPen = None
11 |
12 | def mouseDown(self, point, clickCount):
13 | if self.selection.hasSelection():
14 | return
15 | if not self.optionDown:
16 | self.pen = CocoaPen(None)
17 | else:
18 | self.pen = self._oldPen
19 | self.pen.moveTo((point.x, point.y))
20 |
21 | def mouseDragged(self, point, delta):
22 | if self.pen is None:
23 | return
24 | self.pen.lineTo((point.x, point.y))
25 |
26 | def mouseUp(self, point):
27 | if self.pen is None:
28 | return
29 | self.pen.closePath()
30 |
31 | glyph = self.getGlyph()
32 | path = self.pen.path
33 | for contour in glyph:
34 | for point in contour.points:
35 | result = path.containsPoint_((point.x, point.y))
36 | if self.controlDown:
37 | point.selected = not result
38 | else:
39 | point.selected = result
40 |
41 | self._oldPen = self.pen
42 | self.pen = None
43 |
44 | def draw(self, scale):
45 | if self.pen is None:
46 | return
47 | fill( 1 , 0 , 0 , .2 )
48 | #stroke(0, .6)
49 | #strokeWidth(scale)
50 | drawPath(self.pen.path)
51 |
52 | def canSelectWithMarque(self):
53 | return False
54 |
55 | def getToolbarTip(self):
56 | return "Polygon Selection Tool"
57 |
58 | def getToolbarIcon(self):
59 | icon = NSImage.alloc().initWithContentsOfFile_("polygon-select.pdf")
60 | if icon :
61 | return icon
62 |
63 |
64 | installTool(PolygonSelectionTool())
--------------------------------------------------------------------------------
/removeAllGuides.py:
--------------------------------------------------------------------------------
1 | font = CurrentFont()
2 | for guide in font.guides:
3 | font.removeGuide(guide)
4 | for glyph in font:
5 | for guide in glyph.guides:
6 | glyph.removeGuide(guide)
--------------------------------------------------------------------------------
/renameGroupsOBSR.py:
--------------------------------------------------------------------------------
1 | from mojo.events import addObserver
2 | from afiiTabl import *
3 |
4 |
5 | def renameToAfiiCyrl(glyphName):
6 | if 'uni' in glyphName:
7 | n = getCyrlLetter(uName=glyphName)
8 | if n:
9 | print 'Glyph', n[uniN], 'renamed to', n[afiiN], '-Note:', n[noteCyrl]
10 | glyphName = n[afiiN]
11 | return glyphName
12 |
13 | def checkGlyphNames(font):
14 | print "=== Rename glyphs from uniXXXX to afiiXXXXX ==="
15 | glyphChanged = False
16 | for glyph in font:
17 | oldGlyphName = glyph.name
18 | newGlyphName = renameToAfiiCyrl(glyph.name)
19 | if oldGlyphName != newGlyphName:
20 | font.renameGlyph(oldGlyphName, newGlyphName)
21 | font[newGlyphName].update()
22 | glyphChanged = True
23 | #font.update()
24 | print "=== done renaming glyph names ==="
25 | if glyphChanged:
26 | print "=== Clearing GlyphOrder ==="
27 | font.glyphOrder = []
28 | print "===DONE==="
29 |
30 | def checkGroupNames(font):
31 | print "=== Checking Group Names for Single Quotes ==="
32 | for groupName, items in font.groups.items():
33 | newItems = []
34 | for glyphName in items:
35 | if "'" in glyphName:
36 | glyphName = glyphName.replace("'", "")
37 | print glyphName,' changed'
38 | #glyphName = renameToAfiiCyrl(glyphName)
39 | newItems.append(glyphName)
40 |
41 | if newItems != items:
42 | ## something changed
43 | font.groups[groupName] = newItems
44 | font.lib['com.typedev.markers.groupsclear'] = 'Cleared'
45 | print "=== done checking group names ==="
46 |
47 |
48 |
49 | class RenameGroupsObserver(object):
50 |
51 | def __init__(self):
52 | addObserver(self, "checkFontNames", "fontDidOpen")
53 |
54 | def checkFontNames(self, info):
55 | font = info["font"]
56 | # print font.lib['com.typedev.markers.groupsok']
57 | if font.lib.has_key('com.typedev.markers.groupsclear'):
58 | print "=== Groups OK ==="
59 | else:
60 | checkGroupNames(font)
61 | font.update()
62 | #checkGlyphNames(font)
63 | #font.glyphOrder = glyphOrder
64 |
65 |
66 |
67 |
68 |
69 | RenameGroupsObserver()
--------------------------------------------------------------------------------
/resortGlyphOrder.py:
--------------------------------------------------------------------------------
1 | font = CurrentFont()
2 |
3 | sortedlist = sorted(font.selection)
4 |
5 | glyphOrder = font.lib[ 'public.glyphOrder' ]
6 |
7 | indexes = []
8 | start = None
9 |
10 | for name in font.selection:
11 | for id, fglyph in enumerate(glyphOrder):
12 | if fglyph == name:
13 | indexes.append(id)
14 |
15 | for id, index in enumerate(indexes):
16 | print glyphOrder[index], ' << ', sortedlist[id]
17 | glyphOrder[index]= sortedlist[id]
18 | font[sortedlist[id]].update()
19 |
20 | font.lib['public.glyphOrder'] = glyphOrder
21 | font.glyphOrder = font.lib['public.glyphOrder']
22 | font.update()
--------------------------------------------------------------------------------