Пример #1
0
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()
Пример #2
0
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()
Пример #3
0
	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()
Пример #4
0
	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()
Пример #5
0
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')
Пример #6
0
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()
Пример #7
0
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
Пример #8
0
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()
Пример #9
0
	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)
	numberOfLayers = nakedFont[0].layers_number - 1
	layers = []
	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()
	else:
Пример #11
0
"""
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)
Пример #12
0
"""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()
Пример #13
0
	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()	
Пример #14
0
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()