def buildAccents(font, list, message, overwrite, preflight=False): """ Takes in a list of accents to build in the format of (baseGlyph, finalName, accentList) Marks glyphs that it has built, and updates the font """ tickCount = len(list) bar = ProgressBar(message, tickCount) tick = 0 for item in list: baseGlyph, outputName, accents = item if font.has_key(baseGlyph): if font.has_key(outputName): if overwrite == 1 or overwrite == 3: answer = AskYesNoCancel(outputName + ' exists in font, overwrite?') if answer == 1: font.compileGlyph(outputName, baseGlyph, accents, preflight=preflight) font[outputName].mark = 200 font[outputName].autoUnicodes() font[outputName].update() font.update() if overwrite == 2: font.compileGlyph(outputName, baseGlyph, accents, preflight=preflight) font[outputName].mark = 200 font[outputName].autoUnicodes() font[outputName].update() font.update() else: font.compileGlyph(outputName, baseGlyph, accents, preflight=preflight) font[outputName].mark = 200 font[outputName].autoUnicodes() font[outputName].update() font.update() bar.tick(tick) tick = tick+1 bar.close()
def dump(font): filePath = checkPath(font.path[:-4] + ".txt") if filePath is not None: tickCount = len(font) bar = ProgressBar('Writing dump file', tickCount) tick = 0 outList = [] for glyph in font: bar.tick(tick) tick = tick+1 if len(glyph.components) != 0: output = glyph.name + ';' + str(glyph.width) componentNumber = 0 while componentNumber < len(glyph.components): x, y = glyph.components[componentNumber].offset output = output + ';' + glyph.components[componentNumber].baseGlyph + ';' + str(x) + ';' + str(y) componentNumber = componentNumber + 1 output = output + '\n' outList.append((glyph.index, output)) # Create a dictionary for sorting the glyphs by GID outDictionary = dict(outList) outKeys = outDictionary.keys() outKeys.sort() # Write out the file file = open(filePath, 'w') keyCount = 0 while keyCount < len(outKeys): file.write(outDictionary[outKeys[keyCount]]) keyCount = keyCount + 1 file.close() bar.close() Message('Dump file written')
def clearAnchors(self, doProgress=True): """clear all anchors in the font""" tickCount = len(self.font) if doProgress: bar = ProgressBar("Cleaning all anchors...", tickCount) tick = 0 for glyphName in self.accentList: if doProgress: bar.label(glyphName) baseName, stripedSuffixName, accentNames, errors = nameBuster( glyphName, self.glyphConstructions) existError = False if len(errors) > 0: existError = True if not existError: toClear = [baseName] for accent, position in accentNames: toClear.append(accent) for glyphName in toClear: try: self.font[glyphName].clearAnchors() except IndexError: pass if doProgress: bar.tick(tick) tick = tick + 1 if doProgress: bar.close()
def exportGlyphs(font, glyphs=None, dest=None, doProgress=True, bar=None): """Export all glyphs in a FontLab font""" if dest is None: dir, base = os.path.split(font.file_name) base = base.split(".")[0] + ".glyphs" dest = os.path.join(dir, base) if not os.path.exists(dest): os.makedirs(dest) glyphSet = GlyphSet(dest) if glyphs is None: indices = range(len(font)) else: indices = [] for glyphName in glyphs: indices.append(font.FindGlyph(glyphName)) barStart = 0 closeBar = False if doProgress: if not bar: bar = ProgressBar("Exporting Glyphs", len(indices)) closeBar = True else: barStart = bar.getCurrentTick() else: bar = None try: done = {} for i in range(len(indices)): #if not (i % 10) and not bar.tick(i + barStart): # raise KeyboardInterrupt index = indices[i] flGlyph = font[index] if flGlyph is None: continue glyphName = flGlyph.name if not glyphName: print "can't dump glyph #%s, it has no glyph name" % i else: if glyphName in done: n = 1 while ("%s#%s" % (glyphName, n)) in done: n += 1 glyphName = "%s#%s" % (glyphName, n) done[glyphName] = None exportGlyph(glyphName, flGlyph, glyphSet) if bar and not i % 10: bar.tick(barStart + i) # Write out contents.plist glyphSet.writeContents() except KeyboardInterrupt: if bar: bar.close() bar = None if bar and closeBar: bar.close()
def decomposeFont(font): nakedFont = font.naked() tickCount = len(nakedFont) tick = 0 bar = ProgressBar('Cleaning up glyphs', tickCount) for g in font: nakedFont[g.name].Decompose() nakedFont[g.name].RemoveOverlap() bar.tick(tick) tick = tick+1 bar.close() tickCount = len(font) tick = 0 bar = ProgressBar('Correcting direction', tickCount) for g in font: fl.TransformGlyph(g.naked(), TR_CODE_REVERSE_ALL, '0002') bar.close() return nakedFont
def decomposeComp(f): '''decompose composites for all glyphs in the font''' myBar = ProgressBar('Decomposing...', len(f)) for g in f: if g.components: for c in range(len(g.components)): g.components[-1].decompose() g.update() myBar.tick() myBar.close() f.update()
while numberOfLayers >= 0: layers.append(numberOfLayers) numberOfLayers = numberOfLayers - 1 whichLayer = OneList(layers, message) return int(whichLayer) fontToChange = CurrentFont() if not hasMM(fontToChange.naked()): Message('Font needs to be MM') else: orignalMetricsFont = OpenFont(None, "Which font's sidebearings do you want?") orignalMetrics = {} tickCount = len(orignalMetricsFont) bar = ProgressBar('Getting metrics', tickCount) tick = 0 if hasMM(orignalMetricsFont.naked()): layer = getLayer(orignalMetricsFont.naked(), 'Which layer do you want?') for glyph in orignalMetricsFont: advanceWidth = int(glyph.naked().GetMetrics(layer).x) glyphWidth = int(glyph.naked().GetBoundingRect(layer).width) glyphLeft = int(glyph.naked().GetBoundingRect(layer).x) glyphRight = advanceWidth - (glyphWidth + glyphLeft) orignalMetrics[glyph.name] = [glyphLeft, glyphRight] bar.tick(tick) tick = tick + 1 bar.close() orignalMetricsFont.close()
def perform(self, sender): senderInput = sender.getTitle() f = CurrentFont() tickCount = len(CurrentFont()) progressBar = ProgressBar(title=senderInput, ticks=tickCount, label="checking all the glyphs...") tick = 0 if senderInput == "Open Contours": for glyph in f: self.testForOpenContours(glyph) tick = tick + 1 progressBar.tick(tick) progressBar.close() if senderInput == "Extreme points": for glyph in f: self.testForExtremePoints(glyph) tick = tick + 1 progressBar.tick(tick) progressBar.close() if senderInput == "Straight Lines": for glyph in f: self.testForStraightLines(glyph) tick = tick + 1 progressBar.tick(tick) progressBar.close() if senderInput == "Crossed handles": for glyph in f: self.testForCrossedHandles(glyph) tick = tick + 1 progressBar.tick(tick) progressBar.close() if senderInput == "Unicode values": for glyph in f: self.testUnicodeValue(glyph) tick = tick + 1 progressBar.tick(tick) progressBar.close() if senderInput == "Contour Count": for glyph in f: self.testContourCount(glyph) tick = tick + 1 progressBar.tick(tick) progressBar.close() if senderInput == "Duplicate Contours": for glyph in f: self.testDuplicateContours(glyph) tick = tick + 1 progressBar.tick(tick) progressBar.close() if senderInput == "Small Contours": for glyph in f: self.testForSmallContours(glyph) tick = tick + 1 progressBar.tick(tick) progressBar.close() if senderInput == "Complex Curves": for glyph in f: self.testForComplexCurves(glyph) tick = tick + 1 progressBar.tick(tick) progressBar.close() if senderInput == "Unnecessary Points": for glyph in f: self.testForUnnecessaryPoints(glyph) tick = tick + 1 progressBar.tick(tick) progressBar.close() if senderInput == "Overlapping Points": for glyph in f: self.testForOverlappingPoints(glyph) tick = tick + 1 progressBar.tick(tick) progressBar.close() if senderInput == "Unnecessary Handles": for glyph in f: self.testForUnnecessaryHandles(glyph) tick = tick + 1 progressBar.tick(tick) progressBar.close() if senderInput == "Stray Points": for glyph in f: self.testForStrayPoints(glyph) tick = tick + 1 progressBar.tick(tick) progressBar.close() if senderInput == "Points near vert. Metrics": for glyph in f: self.testForPointsNearVerticalMetrics(glyph) tick = tick + 1 progressBar.tick(tick) progressBar.close()
def save(self, destDir=None, doProgress=False, formatVersion=2): """Save the Font in UFO format.""" # XXX note that when doing "save as" by specifying the destDir argument # _all_ glyphs get loaded into memory. This could be optimized by either # copying those .glif files that have not been edited or (not sure how # well that would work) by simply clearing out self._objects after the # save. from robofab.ufoLib import UFOWriter from robofab.tools.fontlabFeatureSplitter import splitFeaturesForFontLab # if no destination is given, or if # the given destination is the current # path, this is not a save as operation if destDir is None or destDir == self._path: saveAs = False destDir = self._path else: saveAs = True # start a progress bar nonGlyphCount = 5 bar = None if doProgress: from robofab.interface.all.dialogs import ProgressBar bar = ProgressBar("Exporting UFO", nonGlyphCount + len(self._object.keys())) # write writer = UFOWriter(destDir, formatVersion=formatVersion) try: # make a shallow copy of the lib. stuff may be added to it. fontLib = dict(self.lib) # info if bar: bar.label("Saving info...") writer.writeInfo(self.info) if bar: bar.tick() # kerning if self.kerning.changed or saveAs: if bar: bar.label("Saving kerning...") writer.writeKerning(self.kerning.asDict()) if bar: bar.tick() # groups if bar: bar.label("Saving groups...") writer.writeGroups(self.groups) if bar: bar.tick() # features if bar: bar.label("Saving features...") features = self.features.text if features is None: features = "" if formatVersion == 2: writer.writeFeatures(features) elif formatVersion == 1: classes, features = splitFeaturesForFontLab(features) if classes: fontLib["org.robofab.opentype.classes"] = classes.strip( ) + "\n" if features: featureDict = {} for featureName, featureText in features: featureDict[featureName] = featureText.strip() + "\n" fontLib["org.robofab.opentype.features"] = featureDict fontLib["org.robofab.opentype.featureorder"] = [ featureName for featureName, featureText in features ] if bar: bar.tick() # lib if formatVersion == 1: fontLib[postScriptHintDataLibKey] = self.psHints.asDict() if bar: bar.label("Saving lib...") writer.writeLib(fontLib) if bar: bar.tick() # glyphs glyphNameToFileNameFunc = self.getGlyphNameToFileNameFunc() glyphSet = writer.getGlyphSet(glyphNameToFileNameFunc) if len(self._scheduledForDeletion) != 0: if bar: bar.label("Removing deleted glyphs...") for glyphName in self._scheduledForDeletion: if glyphSet.has_key(glyphName): glyphSet.deleteGlyph(glyphName) if bar: bar.tick() if bar: bar.label("Saving glyphs...") count = nonGlyphCount if saveAs: glyphNames = self.keys() else: glyphNames = self._object.keys() for glyphName in glyphNames: glyph = self[glyphName] glyph.psHints._saveToLib(glyph.lib) glyph._saveToGlyphSet(glyphSet, glyphName=glyphName, force=saveAs) if bar and not count % 10: bar.tick(count) count = count + 1 glyphSet.writeContents() self._glyphSet = glyphSet # only blindly stop if the user says to except KeyboardInterrupt: bar.close() bar = None # kill the progress bar if bar: bar.close() # reset internal stuff self._path = destDir self._scheduledForDeletion = [] self.setChanged(False)
# 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. #Imports from robofab.world import CurrentFont from robofab.interface.all.dialogs import PutFile, Message, ProgressBar #Script font = CurrentFont() filePath = PutFile() file = open(filePath, 'w') tickCount = len(font) bar = ProgressBar('Writing dump file', tickCount) tick = 0 outList = [] for glyph in font: bar.tick(tick) tick = tick+1 if len(glyph.components) != 0: output = glyph.name + ';' + str(glyph.width) componentNumber = 0 while componentNumber < len(glyph.components): x, y = glyph.components[componentNumber].offset output = output + ';' + glyph.components[componentNumber].baseGlyph + ';' + str(x) + ';' + str(y) componentNumber = componentNumber + 1 output = output + '\n' outList.append((glyph.index, output)) outDictionary = dict(outList)
def makeGlyph(glyphList, font, message, mark, saveBackup): # Initialize the progress bar tickCount = len(glyphList) bar = ProgressBar(message, tickCount) tick = 0 testingFont = _RFont() for item in glyphList: glyphName, advanceWidth, components = item # If the font has the glyph, lots of checking is required to see if changes have been made if font.has_key(glyphName): glyph = font[glyphName] #Build new glyph for comparisons testingFont.newGlyph(glyphName, clear=True) newGlyph = testingFont[glyphName] newGlyphCount = 0 while newGlyphCount < len(components): component, x, y = components[newGlyphCount] newGlyph.appendComponent(component, offset=(x,y)) newGlyphCount = newGlyphCount+1 newGlyph.width = advanceWidth newGlyph.round() # Make digest of the new glyph pointPen = DigestPointPen() newGlyph.drawPoints(pointPen) newDigest = pointPen.getDigest() # Make digest of the old glyph pointPen = DigestPointPen() glyph.drawPoints(pointPen) oldDigest = pointPen.getDigest() # Check the advance width if glyph.width != advanceWidth: glyph.width = advanceWidth if mark == 1: glyph.mark = 200 # If the digests don't match, rebuild components if oldDigest != newDigest: if saveBackup == 1: backupName = glyph.name + '.bkup' font.insertGlyph(glyph, as=backupName) font[backupName].update() glyph.clearComponents() count = 0 while count < len(components): component, x, y = components[count] glyph.appendComponent(component, offset=(x,y)) count = count+1 if mark == 1: glyph.mark = 200 # Clean up things glyph.update() bar.tick(tick) tick = tick+1 # If the glyph is not in the font, build a new glyph else: font.newGlyph(glyphName, clear=True) glyph = font[glyphName] glyph.width = advanceWidth count = 0 while count < len(components): component, x, y = components[count] glyph.appendComponent(component, offset=(x,y)) count = count+1 if mark == 1: glyph.mark = 300 glyph.update() bar.tick(tick) tick = tick+1 font.update() testingFont.close() bar.close()
""" Remove overlap on all glyphs in a .ufo font. This script sis more than a little silly, but it demonstrates how objectsRF and objectsFL can work hand in hand. """ from robofab.objects.objectsRF import OpenFont from robofab.objects.objectsFL import NewFont from robofab.interface.all.dialogs import ProgressBar ufoFont = OpenFont(note="Select a .ufo") if ufoFont: bar = ProgressBar('Removing Overlap...', len(ufoFont)) flFont = NewFont() flGlyph = flFont.newGlyph('OverlapRemover') for ufoGlyph in ufoFont: flPen = flGlyph.getPointPen() ufoGlyph.drawPoints(flPen) flGlyph.removeOverlap() ufoPen = ufoGlyph.getPointPen() ufoGlyph.clear() flGlyph.drawPoints(ufoPen) flGlyph.clear() bar.tick() flFont.close(save=0) bar.close() ufoFont.save(doProgress=True)
def buildAccents(self, clear=True, adjustWidths=True, markGlyph=True, doProgress=True): """build accented glyphs. some flag definitions: clear=1 clear the glyphs if they already exist markGlyph=1 mark the glyph that is created doProgress=1 show a progress bar adjustWidths=1 will fix right and left margins when left or right accents are added""" tickCount = len(self.accentList) if doProgress: bar = ProgressBar('Building accented glyphs...', tickCount) tick = 0 for glyphName in self.accentList: if doProgress: bar.label(glyphName) existError = False anchorError = False baseName, stripedSuffixName, accentNames, errors = nameBuster( glyphName, self.glyphConstructions) if len(errors) > 0: existError = True for accentError in errors: self.accentErrors.append(accentError) if not existError: baseAnchors = [] try: self.font[baseName] except IndexError: self.accentErrors.append('%s: %s does not exist.' % (glyphName, baseName)) existError = True else: for anchor in self.font[baseName].anchors: baseAnchors.append(anchor.name) for accentName, accentPosition in accentNames: accentAnchors = [] try: self.font[accentName] except IndexError: self.accentErrors.append('%s: %s does not exist.' % (glyphName, accentName)) existError = True else: for anchor in self.font[accentName].getAnchors(): accentAnchors.append(anchor.name) if accentPosition not in baseAnchors: self.accentErrors.append( '%s: %s not in %s anchors.' % (glyphName, accentPosition, baseName)) anchorError = True if ''.join(['_', accentPosition]) not in accentAnchors: self.accentErrors.append( '%s: %s not in %s anchors.' % (glyphName, ''.join(['_', accentPosition ]), accentName)) anchorError = True if not existError and not anchorError: destination = self.font.compileGlyph( glyphName, baseName, self.glyphConstructions[stripedSuffixName][1:], adjustWidths) if markGlyph: destination.mark = accentColor if doProgress: bar.tick(tick) tick = tick + 1 if doProgress: bar.close()
def importAllGlifFiles(font, dirName=None, doProgress=True, bar=None): """import all GLIFs into a FontLab font""" if dirName is None: if font.file_name: dir, base = os.path.split(font.file_name) base = base.split(".")[0] + ".glyphs" dirName = os.path.join(dir, base) else: dirName = GetFolder("Please select a folder with .glif files") glyphSet = GlyphSet(dirName) glyphNames = glyphSet.keys() glyphNames.sort() barStart = 0 closeBar = False if doProgress: if not bar: bar = ProgressBar("Importing Glyphs", len(glyphNames)) closeBar = True else: barStart = bar.getCurrentTick() else: bar = None try: for i in range(len(glyphNames)): #if not (i % 10) and not bar.tick(barStart + i): # raise KeyboardInterrupt glyphName = glyphNames[i] flGlyph = NewGlyph(font, glyphName, clear=True) pen = FLPointPen(flGlyph) glyph = GlyphPlaceholder() glyphSet.readGlyph(glyphName, glyph, pen) if hasattr(glyph, "width"): flGlyph.width = int(round(glyph.width)) if hasattr(glyph, "unicodes"): flGlyph.unicodes = glyph.unicodes if hasattr(glyph, "note"): flGlyph.note = glyph.note # XXX must encode if hasattr(glyph, "lib"): from cStringIO import StringIO from robofab.plistlib import writePlist lib = glyph.lib if lib: if len(lib ) == 1 and "org.robofab.fontlab.customdata" in lib: data = lib["org.robofab.fontlab.customdata"].data else: f = StringIO() writePlist(glyph.lib, f) data = f.getvalue() flGlyph.customdata = data # XXX the next bit is only correct when font is the current font :-( fl.UpdateGlyph(font.FindGlyph(glyphName)) if bar and not i % 10: bar.tick(barStart + i) except KeyboardInterrupt: if bar: bar.close() bar = None fl.UpdateFont(FontIndex(font)) if bar and closeBar: bar.close()
def buildAnchors(self, ucXOffset=0, ucYOffset=0, lcXOffset=0, lcYOffset=0, markGlyph=True, doProgress=True): """add the necessary anchors to the glyphs if they don't exist some flag definitions: uc/lc/X/YOffset=20 offset values for the anchors markGlyph=1 mark the glyph that is created doProgress=1 show a progress bar""" accentOffset = 10 tickCount = len(self.accentList) if doProgress: bar = ProgressBar('Adding anchors...', tickCount) tick = 0 for glyphName in self.accentList: if doProgress: bar.label(glyphName) previousPositions = {} baseName, stripedSuffixName, accentNames, errors = nameBuster( glyphName, self.glyphConstructions) existError = False if len(errors) > 0: existError = True for anchorError in errors: self.anchorErrors.append(anchorError) if not existError: existError = False try: self.font[baseName] except IndexError: self.anchorErrors.append(' '.join( [glyphName, ':', baseName, 'does not exist.'])) existError = True for accentName, accentPosition in accentNames: try: self.font[accentName] except IndexError: self.anchorErrors.append(' '.join( [glyphName, ':', accentName, 'does not exist.'])) existError = True if not existError: #glyph = self.font.newGlyph(glyphName, clear=True) for accentName, accentPosition in accentNames: if baseName.split('.')[0] in lowercase_plain: xOffset = lcXOffset - accentOffset yOffset = lcYOffset - accentOffset else: xOffset = ucXOffset - accentOffset yOffset = ucYOffset - accentOffset # should I add a cedilla and ogonek yoffset override here? if accentPosition not in previousPositions.keys(): self._dropAnchor(self.font[baseName], accentPosition, xOffset, yOffset) if markGlyph: self.font[baseName].mark = anchorColor if inFontLab: self.font[baseName].update() else: self._dropAnchor( self.font[previousPositions[accentPosition]], accentPosition, xOffset, yOffset) self._dropAnchor(self.font[accentName], accentPosition, accentOffset, accentOffset, doAccentPosition=1) previousPositions[accentPosition] = accentName if markGlyph: self.font[accentName].mark = anchorColor if inFontLab: self.font[accentName].update() if inFontLab: self.font.update() if doProgress: bar.tick(tick) tick = tick + 1 if doProgress: bar.close()
"""Correct contour direction for all glyphs in the font""" from robofab.world import OpenFont from robofab.interface.all.dialogs import ProgressBar font = OpenFont() bar = ProgressBar('Correcting contour direction...', len(font)) for glyph in font: bar.label(glyph.name) glyph.correctDirection() glyph.update() bar.tick() font.update() bar.close()
for a in forigen[gname].anchors: if a.name in actualAnchors: print gname + " ya tiene anchor " + a.name else: fdestino[gname].appendAnchor(a.name, (a.x, a.y)) print "Anchor " + a.name + ' copiado a' + gname fdestino[gname].mark = 180 bar.tick(tick) tick = tick + 1 fonts = AllFonts() for f in fonts: if f.info.postscriptFullName == forigen: forigen = f fcurrent = CurrentFont() glyph = CurrentGlyph() fl.SetUndo() tickCount = len(fcurrent.selection) bar = ProgressBar('Copiando anchors...', tickCount) tick = 0 for gname in fcurrent.selection: copiaAnchors(forigen, fcurrent, gname, tick) bar.close() Message('Anchors copiados.') fdestino.update()
src2 = SelectFont('Select source font two:') if src2: # collect a list of all compatible glyphs common = [] for glyphName in src1.keys(): if src2.has_key(glyphName): if src1[glyphName].isCompatible(src2[glyphName]): common.append(glyphName) common.sort() selName = OneList(common, 'Select a glyph:') if selName: dest = NewFont() g1 = src1[selName] g2 = src2[selName] count = 1 bar = ProgressBar('Interpolating...', 100) # add the sourec one glyph for reference dest.newGlyph(selName + '_000') dest[selName + '_000'].width = src1[selName].width dest[selName + '_000'].appendGlyph(src1[selName]) dest[selName + '_000'].mark = 1 dest[selName + '_000'].update() # add a new glyph and interpolate it while count != 100: factor = count * .01 newName = selName + '_' + ` count `.zfill(3) gD = dest.newGlyph(newName) gD.interpolate(factor, g1, g2) gD.update() bar.tick() count = count + 1
#FLM: AT Duplicate contours from robofab.world import CurrentFont from robofab.interface.all.dialogs import ProgressBar import collections f = CurrentFont() tickCount = len(f) bar = ProgressBar('Chequeando...', tickCount) tick = 0 myNodes = [] for g in f.selection: myNodes = [] bar.tick(tick) tick = tick + 1 for c in f[g]: for p in c.points: if p.type != 'move' and p.type != 'offcurve': myNodes.append((p.x, p.y)) myNodes.sort() duplicates = [x for x, y in collections.Counter(myNodes).items() if y > 1] contNumber = len(f[g]) if len(duplicates) > contNumber: f[g].mark = 255 print f[g].name print duplicates print '-----' else: f[g].mark = 0 myNodes = []