示例#1
0
 def testInfo(self):
     self.setUpFont(doInfo=True)
     otherResults = self.compareToUFO(doInfo=False)
     self.assertEqual(otherResults["kerning"], False)
     self.assertEqual(otherResults["groups"], False)
     expectedPath = os.path.join(ufoPath1, "fontinfo.plist")
     writtenPath = os.path.join(self.dstDir, "fontinfo.plist")
     expected = readPlist(expectedPath)
     written = readPlist(writtenPath)
     for attr, expectedValue in expected.items():
         self.assertEqual((attr, expectedValue), (attr, written[attr]))
     self.tearDownFont()
	def testInfo(self):
		self.setUpFont(doInfo=True)
		otherResults = self.compareToUFO(doInfo=False)
		self.assertEqual(otherResults["kerning"], False)
		self.assertEqual(otherResults["groups"], False)
		expectedPath = os.path.join(ufoPath1, "fontinfo.plist")
		writtenPath = os.path.join(self.dstDir, "fontinfo.plist")
		expected = readPlist(expectedPath)
		written = readPlist(writtenPath)
		for attr, expectedValue in expected.items():
			self.assertEqual((attr, expectedValue), (attr, written[attr]))
		self.tearDownFont()
示例#3
0
def exportGlyph(glyphName, flGlyph, glyphSet):
    """Export a FontLab glyph."""

    glyph = GlyphPlaceholder()
    glyph.width = flGlyph.width
    glyph.unicodes = flGlyph.unicodes
    if flGlyph.note:
        glyph.note = flGlyph.note
    customdata = flGlyph.customdata
    if customdata:
        from cStringIO import StringIO
        from robofab.plistlib import readPlist, Data
        f = StringIO(customdata)
        try:
            glyph.lib = readPlist(f)
        except:  # XXX ugh, plistlib can raise lots of things
            # Anyway, customdata does not contain valid plist data,
            # but we don't need to toss it!
            glyph.lib = {"org.robofab.fontlab.customdata": Data(customdata)}

    def drawPoints(pen):
        # whoohoo, nested scopes are cool.
        drawFLGlyphOntoPointPen(flGlyph, pen)

    glyphSet.writeGlyph(glyphName, glyph, drawPoints)
示例#4
0
def exportGlyph(glyphName, flGlyph, glyphSet):
	"""Export a FontLab glyph."""

	glyph = GlyphPlaceholder()
	glyph.width = flGlyph.width
	glyph.unicodes = flGlyph.unicodes
	if flGlyph.note:
		glyph.note = flGlyph.note
	customdata = flGlyph.customdata
	if customdata:
		from cStringIO import StringIO
		from robofab.plistlib import readPlist, Data
		f = StringIO(customdata)
		try:
			glyph.lib = readPlist(f)
		except: # XXX ugh, plistlib can raise lots of things
			# Anyway, customdata does not contain valid plist data,
			# but we don't need to toss it!
			glyph.lib = {"org.robofab.fontlab.customdata": Data(customdata)}

	def drawPoints(pen):
		# whoohoo, nested scopes are cool.
		drawFLGlyphOntoPointPen(flGlyph, pen)

	glyphSet.writeGlyph(glyphName, glyph, drawPoints)
示例#5
0
	def readLib(self):
		"""
		Read lib.plist. Returns a dict.
		"""
		path = os.path.join(self._path, LIB_FILENAME)
		if not self._checkForFile(path):
			return {}
		return readPlist(path)
示例#6
0
	def readGroups(self):
		"""
		Read groups.plist. Returns a dict.
		"""
		path = os.path.join(self._path, GROUPS_FILENAME)
		if not self._checkForFile(path):
			return {}
		return readPlist(path)
示例#7
0
	def compareToUFO(self):
		readerExpected = UFOReader(ufoPath1)
		readerWritten = UFOReader(self.dstDir)
		results = {}
		# info
		matches = True
		expectedPath = os.path.join(ufoPath1, "fontinfo.plist")
		writtenPath = os.path.join(self.dstDir, "fontinfo.plist")
		if not os.path.exists(writtenPath):
			matches = False
		else:
			expected = readPlist(expectedPath)
			written = readPlist(writtenPath)
			for attr, expectedValue in expected.items():
				if expectedValue != written.get(attr):
					matches = False
					break
		results["info"] = matches
		# kerning
		matches = True
		expectedPath = os.path.join(ufoPath1, "kerning.plist")
		writtenPath = os.path.join(self.dstDir, "kerning.plist")
		if not os.path.exists(writtenPath):
			matches = False
		else:
			matches = readPlist(expectedPath) == readPlist(writtenPath)
		results["kerning"] = matches
		# groups
		matches = True
		expectedPath = os.path.join(ufoPath1, "groups.plist")
		writtenPath = os.path.join(self.dstDir, "groups.plist")
		if not os.path.exists(writtenPath):
			matches = False
		else:
			matches = readPlist(expectedPath) == readPlist(writtenPath)
		results["groups"] = matches
		# features
		matches = True
		expectedPath = os.path.join(ufoPath1, "features.fea")
		writtenPath = os.path.join(self.dstDir, "features.fea")
		if os.path.exists(writtenPath):
			matches = False
		results["features"] = matches
		# lib
		matches = True
		expectedPath = os.path.join(ufoPath1, "lib.plist")
		writtenPath = os.path.join(self.dstDir, "lib.plist")
		if not os.path.exists(writtenPath):
			matches = False
		else:
			writtenLib = readPlist(writtenPath)
			matches = readPlist(expectedPath) == writtenLib
		results["lib"] = matches
		return results
示例#8
0
def convertUFOFormatVersion2ToFormatVersion1(inPath, outPath=None):
	"""
	Function for converting a version format 2 UFO
	to version format 1. inPath should be a path
	to a UFO. outPath is the path where the new UFO
	should be written. If outPath is not given, the
	inPath will be used and, therefore, the UFO will
	be converted in place. Otherwise, if outPath is
	specified, nothing must exist at that path.
	"""
	if outPath is None:
		outPath = inPath
	if inPath != outPath and os.path.exists(outPath):
		raise UFOLibError("A file already exists at %s." % outPath)
	# use a reader for loading most of the data
	reader = UFOReader(inPath)
	if reader.formatVersion == 1:
		raise UFOLibError("The UFO at %s is already format version 1." % inPath)
	groups = reader.readGroups()
	kerning = reader.readKerning()
	libData = reader.readLib()
	# read the info data manually and convert
	infoPath = os.path.join(inPath, FONTINFO_FILENAME)
	if not os.path.exists(infoPath):
		infoData = {}
	else:
		infoData = readPlist(infoPath)
	infoData = _convertFontInfoDataVersion2ToVersion1(infoData)
	# if the paths are the same, only need to change the
	# fontinfo, metainfo and feature files.
	infoPath = os.path.join(outPath, FONTINFO_FILENAME)
	if inPath == outPath:
		metaInfoPath = os.path.join(inPath, METAINFO_FILENAME)
		metaInfo = dict(
			creator="org.robofab.ufoLib",
			formatVersion=1
		)
		writePlistAtomically(metaInfo, metaInfoPath)
		writePlistAtomically(infoData, infoPath)
		featuresPath = os.path.join(inPath, FEATURES_FILENAME)
		if os.path.exists(featuresPath):
			os.remove(featuresPath)
	# otherwise write everything.
	else:
		writer = UFOWriter(outPath, formatVersion=1)
		writer.writeGroups(groups)
		writer.writeKerning(kerning)
		writer.writeLib(libData)
		# write the info manually
		writePlistAtomically(infoData, infoPath)
		# copy the glyph tree
		inGlyphs = os.path.join(inPath, GLYPHS_DIRNAME)
		outGlyphs = os.path.join(outPath, GLYPHS_DIRNAME)
		if os.path.exists(inGlyphs):
			shutil.copytree(inGlyphs, outGlyphs)
	def testInfo(self):
		self.setUpFont(doInfo=True)
		otherResults = self.compareToUFO(doInfo=False)
		self.assertEqual(otherResults["kerning"], False)
		self.assertEqual(otherResults["groups"], False)
		self.assertEqual(otherResults["features"], False)
		self.assertEqual(otherResults["lib"], False)
		expectedPath = os.path.join(ufoPath2, "fontinfo.plist")
		writtenPath = os.path.join(self.dstDir, "fontinfo.plist")
		expected = readPlist(expectedPath)
		written = readPlist(writtenPath)
		dummyFont = NewFont()
		_ufoToFLAttrMapping = dict(dummyFont.info._ufoToFLAttrMapping)
		dummyFont.close()
		for attr, expectedValue in expected.items():
			# cheat by skipping attrs that aren't supported
			if _ufoToFLAttrMapping[attr]["nakedAttribute"] is None:
				continue
			self.assertEqual((attr, expectedValue), (attr, written[attr]))
		self.tearDownFont()
示例#10
0
 def testInfo(self):
     self.setUpFont(doInfo=True)
     otherResults = self.compareToUFO(doInfo=False)
     self.assertEqual(otherResults["kerning"], False)
     self.assertEqual(otherResults["groups"], False)
     self.assertEqual(otherResults["features"], False)
     self.assertEqual(otherResults["lib"], False)
     expectedPath = os.path.join(ufoPath2, "fontinfo.plist")
     writtenPath = os.path.join(self.dstDir, "fontinfo.plist")
     expected = readPlist(expectedPath)
     written = readPlist(writtenPath)
     dummyFont = NewFont()
     _ufoToFLAttrMapping = dict(dummyFont.info._ufoToFLAttrMapping)
     dummyFont.close()
     for attr, expectedValue in expected.items():
         # cheat by skipping attrs that aren't supported
         if _ufoToFLAttrMapping[attr]["nakedAttribute"] is None:
             continue
         self.assertEqual((attr, expectedValue), (attr, written[attr]))
     self.tearDownFont()
示例#11
0
    def __init__(self, fonts, glyphs, mode, callback):
        self.allGlyphs = set()
        for path, font in fonts.items():
            if font is None:
                contentsPath = os.path.join(path, "glyphs", "contents.plist")
                if not os.path.exists(contentsPath):
                    continue
                else:
                    contents = readPlist(contentsPath)
                    self.allGlyphs = self.allGlyphs | set(contents.keys())
            else:
                self.allGlyphs = self.allGlyphs | set(font.keys())
        if glyphs is None:
            self.selectedGlyphs = list(self.allGlyphs)
            self.selectedGlyphs.sort()
            self.unselectedGlyphs = []
        else:
            self.selectedGlyphs = glyphs
            self.unselectedGlyphs = list(self.allGlyphs - set(glyphs))
            self.unselectedGlyphs.sort()

        self.callback = callback
        mode = mode.title()

        self.w = dialogKit.ModalDialog((472, 400),
                                       "Glyphs",
                                       okCallback=self.okCallback)

        self.w.unselectedTitle = dialogKit.TextBox((12, 12, 150, 20),
                                                   "Ignore:")
        self.w.unselectedGlyphsList = dialogKit.List((12, 37, 150, -60),
                                                     self.unselectedGlyphs)

        self.w.addSelectionButton = dialogKit.Button(
            (172, 37, 130, 20), ">>>", callback=self.addSelectionCallback)
        self.w.removeSelectionButton = dialogKit.Button(
            (172, 67, 130, 20), "<<<", callback=self.removeSelectionCallback)
        self.w.addAllButton = dialogKit.Button((172, 97, 130, 20),
                                               "%s All" % mode,
                                               callback=self.addAllCallback)
        self.w.removeAllButton = dialogKit.Button(
            (172, 127, 130, 20), "Ignore All", callback=self.removeAllCallback)
        self.w.fromFontSelection = dialogKit.Button(
            (172, 157, 130, 20),
            "Font Selection",
            callback=self.fontSelectionCallback)

        self.w.selectedTitle = dialogKit.TextBox((310, 12, 150, 20),
                                                 "%s:" % mode)
        self.w.selectedGlyphsList = dialogKit.List((310, 37, 150, -60),
                                                   self.selectedGlyphs)

        self.w.open()
示例#12
0
	def readKerning(self):
		"""
		Read kerning.plist. Returns a dict.
		"""
		path = os.path.join(self._path, KERNING_FILENAME)
		if not self._checkForFile(path):
			return {}
		kerningNested = readPlist(path)
		kerning = {}
		for left in kerningNested:
			for right in kerningNested[left]:
				value = kerningNested[left][right]
				kerning[left, right] = value
		return kerning
示例#13
0
	def readMetaInfo(self):
		"""
		Read metainfo.plist. Only used for internal operations.
		"""
		path = os.path.join(self._path, METAINFO_FILENAME)
		if not self._checkForFile(path):
			raise UFOLibError("metainfo.plist is missing in %s. This file is required." % self._path)
		# should there be a blind try/except with a UFOLibError
		# raised in except here (and elsewhere)? It would be nice to
		# provide external callers with a single exception to catch.
		data = readPlist(path)
		formatVersion = data["formatVersion"]
		if formatVersion not in supportedUFOFormatVersions:
			raise UFOLibError("Unsupported UFO format (%d) in %s." % (formatVersion, self._path))
		self._formatVersion = formatVersion
示例#14
0
    def readInfo(self, info):
        """
		Read fontinfo.plist. It requires an object that allows
		setting attributes with names that follow the fontinfo.plist
		version 2 specification. This will write the attributes
		defined in the file into the object.
		"""
        # load the file and return if there is no file
        path = os.path.join(self._path, FONTINFO_FILENAME)
        if not self._checkForFile(path):
            return
        infoDict = readPlist(path)
        infoDataToSet = {}
        # version 1
        if self._formatVersion == 1:
            for attr in fontInfoAttributesVersion1:
                value = infoDict.get(attr)
                if value is not None:
                    infoDataToSet[attr] = value
            infoDataToSet = _convertFontInfoDataVersion1ToVersion2(
                infoDataToSet)
        # version 2
        elif self._formatVersion == 2:
            for attr, dataValidationDict in _fontInfoAttributesVersion2ValueData.items(
            ):
                value = infoDict.get(attr)
                if value is None:
                    continue
                infoDataToSet[attr] = value
        # unsupported version
        else:
            raise NotImplementedError
        # validate data
        infoDataToSet = _validateInfoVersion2Data(infoDataToSet)
        # populate the object
        for attr, value in infoDataToSet.items():
            try:
                setattr(info, attr, value)
            except AttributeError:
                raise UFOLibError(
                    "The supplied info object does not support setting a necessary attribute (%s)."
                    % attr)
    def __init__(self, fonts, glyphs, mode, callback):
        self.allGlyphs = set()
        for path, font in fonts.items():
            if font is None:
                contentsPath = os.path.join(path, "glyphs", "contents.plist")
                if not os.path.exists(contentsPath):
                    continue
                else:
                    contents = readPlist(contentsPath)
                    self.allGlyphs = self.allGlyphs | set(contents.keys())
            else:
                self.allGlyphs = self.allGlyphs | set(font.keys())
        if glyphs is None:
            self.selectedGlyphs = list(self.allGlyphs)
            self.selectedGlyphs.sort()
            self.unselectedGlyphs = []
        else:
            self.selectedGlyphs = glyphs
            self.unselectedGlyphs = list(self.allGlyphs - set(glyphs))
            self.unselectedGlyphs.sort()

        self.callback = callback
        mode = mode.title()

        self.w = dialogKit.ModalDialog((472, 400), "Glyphs", okCallback=self.okCallback)

        self.w.unselectedTitle = dialogKit.TextBox((12, 12, 150, 20), "Ignore:")
        self.w.unselectedGlyphsList = dialogKit.List((12, 37, 150, -60), self.unselectedGlyphs)

        self.w.addSelectionButton = dialogKit.Button((172, 37, 130, 20), ">>>", callback=self.addSelectionCallback)
        self.w.removeSelectionButton = dialogKit.Button((172, 67, 130, 20), "<<<", callback=self.removeSelectionCallback)
        self.w.addAllButton = dialogKit.Button((172, 97, 130, 20), "%s All" % mode, callback=self.addAllCallback)
        self.w.removeAllButton = dialogKit.Button((172, 127, 130, 20), "Ignore All", callback=self.removeAllCallback)
        self.w.fromFontSelection = dialogKit.Button((172, 157, 130, 20), "Font Selection", callback=self.fontSelectionCallback)

        self.w.selectedTitle = dialogKit.TextBox((310, 12, 150, 20), "%s:" % mode)
        self.w.selectedGlyphsList = dialogKit.List((310, 37, 150, -60), self.selectedGlyphs)

        self.w.open()
示例#16
0
	def readInfo(self, info):
		"""
		Read fontinfo.plist. It requires an object that allows
		setting attributes with names that follow the fontinfo.plist
		version 2 specification. This will write the attributes
		defined in the file into the object.
		"""
		# load the file and return if there is no file
		path = os.path.join(self._path, FONTINFO_FILENAME)
		if not self._checkForFile(path):
			return
		infoDict = readPlist(path)
		infoDataToSet = {}
		# version 1
		if self._formatVersion == 1:
			for attr in fontInfoAttributesVersion1:
				value = infoDict.get(attr)
				if value is not None:
					infoDataToSet[attr] = value
			infoDataToSet = _convertFontInfoDataVersion1ToVersion2(infoDataToSet)
		# version 2
		elif self._formatVersion == 2:
			for attr, dataValidationDict in _fontInfoAttributesVersion2ValueData.items():
				value = infoDict.get(attr)
				if value is None:
					continue
				infoDataToSet[attr] = value
		# unsupported version
		else:
			raise NotImplementedError
		# validate data
		infoDataToSet = _validateInfoVersion2Data(infoDataToSet)
		# populate the object
		for attr, value in infoDataToSet.items():
			try:
				setattr(info, attr, value)
			except AttributeError:
				raise UFOLibError("The supplied info object does not support setting a necessary attribute (%s)." % attr)
示例#17
0
 def compareToUFO(self,
                  doInfo=True,
                  doKerning=True,
                  doGroups=True,
                  doLib=True,
                  doFeatures=True):
     readerExpected = UFOReader(ufoPath2)
     readerWritten = UFOReader(self.dstDir)
     results = {}
     if doInfo:
         matches = True
         expectedPath = os.path.join(ufoPath2, "fontinfo.plist")
         writtenPath = os.path.join(self.dstDir, "fontinfo.plist")
         if not os.path.exists(writtenPath):
             matches = False
         else:
             dummyFont = NewFont()
             _ufoToFLAttrMapping = dict(dummyFont.info._ufoToFLAttrMapping)
             dummyFont.close()
             expected = readPlist(expectedPath)
             written = readPlist(writtenPath)
             for attr, expectedValue in expected.items():
                 # cheat by skipping attrs that aren't supported
                 if _ufoToFLAttrMapping[attr]["nakedAttribute"] is None:
                     continue
                 if expectedValue != written[attr]:
                     matches = False
                     break
         results["info"] = matches
     if doKerning:
         matches = True
         expectedPath = os.path.join(ufoPath2, "kerning.plist")
         writtenPath = os.path.join(self.dstDir, "kerning.plist")
         if not os.path.exists(writtenPath):
             matches = False
         else:
             matches = readPlist(expectedPath) == readPlist(writtenPath)
         results["kerning"] = matches
     if doGroups:
         matches = True
         expectedPath = os.path.join(ufoPath2, "groups.plist")
         writtenPath = os.path.join(self.dstDir, "groups.plist")
         if not os.path.exists(writtenPath):
             matches = False
         else:
             matches = readPlist(expectedPath) == readPlist(writtenPath)
         results["groups"] = matches
     if doFeatures:
         matches = True
         expectedPath = os.path.join(ufoPath2, "features.fea")
         writtenPath = os.path.join(self.dstDir, "features.fea")
         if not os.path.exists(writtenPath):
             matches = False
         else:
             f = open(expectedPath, "r")
             expectedText = f.read()
             f.close()
             f = open(writtenPath, "r")
             writtenText = f.read()
             f.close()
             # FontLab likes to add lines to the features, so skip blank lines.
             expectedText = [
                 line for line in expectedText.splitlines() if line
             ]
             writtenText = [
                 line for line in writtenText.splitlines() if line
             ]
             matches = "\n".join(expectedText) == "\n".join(writtenText)
         results["features"] = matches
     if doLib:
         matches = True
         expectedPath = os.path.join(ufoPath2, "lib.plist")
         writtenPath = os.path.join(self.dstDir, "lib.plist")
         if not os.path.exists(writtenPath):
             matches = False
         else:
             # the test file doesn't have the glyph order
             # so purge it from the written
             writtenLib = readPlist(writtenPath)
             del writtenLib["org.robofab.glyphOrder"]
             matches = readPlist(expectedPath) == writtenLib
         results["lib"] = matches
     return results
示例#18
0
def importUFO(ufoPath,
              newFile=True,
              saveFile=True,
              closeFile=True,
              doInfo=True,
              doKerning=True,
              doGroups=True,
              doLib=True,
              doFeatures=True,
              doHints=False,
              doMarks=True,
              doMasks=True,
              glyphs=None):
    # get the VFB path
    vfbPath = os.path.splitext(ufoPath)[0] + ".vfb"
    if not newFile:
        font = None
        for font in AllFonts():
            if font.path == vfbPath:
                break
        if font is None:
            if not os.path.exists(vfbPath):
                Message("Could not find the FontLab file \"%s\"." %
                        os.path.basename(vfbPath))
                return
            font = OpenFont(vfbPath)
    else:
        if saveFile:
            if os.path.exists(vfbPath):
                vfbPath = _findAvailablePathName(vfbPath)
        font = NewFont()
    # make the font the top font in FL
    fl.ifont = font.fontIndex
    # read the UFO
    font.readUFO(ufoPath,
                 doHints=doHints,
                 doInfo=doInfo,
                 doKerning=doKerning,
                 doGroups=doGroups,
                 doLib=doLib,
                 doFeatures=doFeatures,
                 glyphs=glyphs)
    # load the masks and marks
    if doMasks or doMarks:
        for glyph in font:
            lib = glyph.lib
            if doMarks:
                if lib.has_key(MARK_LIB_KEY):
                    glyph.mark = lib[MARK_LIB_KEY]
                    del lib[MARK_LIB_KEY]
            if doMasks:
                if lib.has_key(MASK_LIB_KEY):
                    # open a glyph window
                    fl.EditGlyph(glyph.index)
                    # switch to the mask layer
                    fl.CallCommand(fl_cmd.ViewEditMask)
                    # add the mask data
                    instructions = lib[MASK_LIB_KEY]
                    pen = glyph.getPointPen()
                    instructionsDrawPoints(instructions, pen)
                    # switch back to the edit layer
                    fl.CallCommand(fl_cmd.ViewEditMask)
                    # clear the mask data from the glyph lib
                    del lib[MASK_LIB_KEY]
        # close all glyph windows. sometimes this actually works.
        fl.CallCommand(fl_cmd.WindowCloseAllGlyphWindows)
    # load the WWS names
    if doInfo:
        info = readPlist(os.path.join(ufoPath, "fontInfo.plist"))
        if "openTypeNameWWSFamilyName" in info:
            font.lib[WWS_FAMILY_KEY] = info["openTypeNameWWSFamilyName"]
        elif "openTypeNameWWSFamilyName" in font.lib:
            del font.lib[WWS_FAMILY_KEY]
        if "openTypeNameWWSSubfamilyName" in info:
            font.lib[WWS_SUBFAMILY_KEY] = info["openTypeNameWWSSubfamilyName"]
        elif "openTypeNameWWSSubfamilyName" in font.lib:
            del font.lib[WWS_SUBFAMILY_KEY]
    # update the font
    font.update()
    # save and close
    if saveFile:
        font.save(vfbPath)
        if closeFile:
            font.close()
示例#19
0
def exportUFO(font,
              newFile=True,
              doInfo=True,
              doKerning=True,
              doGroups=True,
              doLib=True,
              doFeatures=True,
              doHints=False,
              doMarks=True,
              doMasks=True,
              glyphs=None,
              formatVersion=2):
    # get the UFO path
    ufoPath = os.path.splitext(font.path)[0] + ".ufo"
    if not newFile:
        if not os.path.exists(ufoPath):
            Message("Could not find the UFO file \"%s\"." %
                    os.path.basename(ufoPath))
            return
    else:
        if os.path.exists(ufoPath):
            ufoPath = _findAvailablePathName(ufoPath)
    # make sure no bogus glyph names are coming in
    if glyphs is not None:
        glyphs = [glyphName for glyphName in glyphs if font.has_key(glyphName)]
    # make the font the top font in FL
    fl.ifont = font.fontIndex
    # add the masks and marks to the glyph.lib
    if doMasks or doMarks:
        if glyphs is None:
            glyphNames = font.keys()
        else:
            glyphNames = glyphs
        for glyphName in glyphNames:
            glyph = font[glyphName]
            if doMarks:
                mark = glyph.mark
                glyph.lib[MARK_LIB_KEY] = mark
            if doMasks:
                # open a glyph window
                fl.EditGlyph(glyph.index)
                # switch to the mask layer
                fl.CallCommand(fl_cmd.ViewEditMask)
                # if the mask is empty, skip this step
                if not len(glyph):
                    # switch back to the edit layer
                    fl.CallCommand(fl_cmd.ViewEditMask)
                    continue
                # get the mask data
                pen = InstructionPointPen()
                glyph.drawPoints(pen)
                # switch back to the edit layer
                fl.CallCommand(fl_cmd.ViewEditMask)
                # write the mask data to the glyph lib
                instructions = pen.getInstructions()
                if instructions:
                    glyph.lib[MASK_LIB_KEY] = instructions
        # close all glyph windows. sometimes this actually works.
        fl.CallCommand(fl_cmd.WindowCloseAllGlyphWindows)
    # remove WWS names from the lib
    wwsStorage = {}
    if "openTypeNameWWSFamilyName" in font.lib:
        wwsStorage["openTypeNameWWSFamilyName"] = font.lib.pop(WWS_FAMILY_KEY)
    if "openTypeNameWWSSubfamilyName" in font.lib:
        wwsStorage["openTypeNameWWSSubfamilyName"] = font.lib.pop(
            WWS_SUBFAMILY_KEY)
    # write the UFO
    font.writeUFO(path=ufoPath,
                  doHints=doHints,
                  doInfo=doInfo,
                  doKerning=doKerning,
                  doGroups=doGroups,
                  doLib=doLib,
                  doFeatures=doFeatures,
                  glyphs=glyphs,
                  formatVersion=formatVersion)
    # add the WWS names to the info
    if doInfo:
        infoPath = os.path.join(ufoPath, "fontinfo.plist")
        info = readPlist(infoPath)
        newInfo = deepcopy(info)
        newInfo.update(wwsStorage)
        if info != newInfo:
            writePlist(newInfo, infoPath)
    # put the WWS names back in the lib
    font.lib.update(wwsStorage)
    # remove the masks and marks from the glyph.lib
    if doMasks or doMarks:
        if glyphs is None:
            glyphNames = font.keys()
        else:
            glyphNames = glyphs
        for glyphName in glyphNames:
            glyph = font[glyphName]
            lib = glyph.lib
            if lib.has_key(MASK_LIB_KEY):
                del lib[MASK_LIB_KEY]
            if lib.has_key(MARK_LIB_KEY):
                del lib[MARK_LIB_KEY]
def importUFO(ufoPath, newFile=True, saveFile=True, closeFile=True, doInfo=True, doKerning=True, doGroups=True,
    doLib=True, doFeatures=True, doHints=False, doMarks=True, doMasks=True, glyphs=None):
    # get the VFB path
    vfbPath = os.path.splitext(ufoPath)[0] + ".vfb"
    if not newFile:
        font = None
        for font in AllFonts():
            if font.path == vfbPath:
                break
        if font is None:
            if not os.path.exists(vfbPath):
                Message("Could not find the FontLab file \"%s\"." % os.path.basename(vfbPath))
                return
            font = OpenFont(vfbPath)
    else:
        if saveFile:
            if os.path.exists(vfbPath):
                vfbPath = _findAvailablePathName(vfbPath)
        font = NewFont()
    # make the font the top font in FL
    fl.ifont = font.fontIndex
    # read the UFO
    font.readUFO(ufoPath, doHints=doHints, doInfo=doInfo, doKerning=doKerning,
        doGroups=doGroups, doLib=doLib, doFeatures=doFeatures, glyphs=glyphs)
    # load the masks and marks
    if doMasks or doMarks:
        for glyph in font:
            lib = glyph.lib
            if doMarks:
                if lib.has_key(MARK_LIB_KEY):
                    glyph.mark = lib[MARK_LIB_KEY]
                    del lib[MARK_LIB_KEY]
            if doMasks:
                if lib.has_key(MASK_LIB_KEY):
                    # open a glyph window
                    fl.EditGlyph(glyph.index)
                    # switch to the mask layer
                    fl.CallCommand(fl_cmd.ViewEditMask)
                    # add the mask data
                    instructions = lib[MASK_LIB_KEY]
                    pen = glyph.getPointPen()
                    instructionsDrawPoints(instructions, pen)
                    # switch back to the edit layer
                    fl.CallCommand(fl_cmd.ViewEditMask)
                    # clear the mask data from the glyph lib
                    del lib[MASK_LIB_KEY]
        # close all glyph windows. sometimes this actually works.
        fl.CallCommand(fl_cmd.WindowCloseAllGlyphWindows)
    # load the WWS names
    if doInfo:
        info = readPlist(os.path.join(ufoPath, "fontInfo.plist"))
        if "openTypeNameWWSFamilyName" in info:
            font.lib[WWS_FAMILY_KEY] = info["openTypeNameWWSFamilyName"]
        elif "openTypeNameWWSFamilyName" in font.lib:
            del font.lib[WWS_FAMILY_KEY]
        if "openTypeNameWWSSubfamilyName" in info:
            font.lib[WWS_SUBFAMILY_KEY] = info["openTypeNameWWSSubfamilyName"]
        elif "openTypeNameWWSSubfamilyName" in font.lib:
            del font.lib[WWS_SUBFAMILY_KEY]
    # update the font
    font.update()
    # save and close
    if saveFile:
        font.save(vfbPath)
        if closeFile:
            font.close()
示例#21
0
"""
This implements the PlistLib Writer for python < 2.2.
Deconstructed from Just van Rossums's plistlib.py (I apoligise!),
but without the 2.3 python dependencies, so it can be used in elderly
programs with elderly embedded pythons. This produces a plist file
with macroman encoding as the whole unicode schtick doesn't exist in
1.5.2.
For comments and notes on how to use this module, please have a look
at the original plistlib.py.

Supported:
	string
	integer
	dictionary
	list
	tuple
	
Not supported:
	binary data, uses base64 which might be available,
		I'll add it when I need it.
	dates: uses xml.utils.iso8601
		I'll add it when I need it.
"""
import string
import sys
from types import StringType, IntType, FloatType, ListType, TupleType, DictType
FogPlistWriterError = "FogPlistWriterError"

PLISTHEADER = """\
<?xml version="1.0" encoding="macroman"?>
示例#22
0
 def compareToUFO(self,
                  doInfo=True,
                  doKerning=True,
                  doGroups=True,
                  doLib=True,
                  doFeatures=True):
     readerExpected = UFOReader(ufoPath1)
     readerWritten = UFOReader(self.dstDir)
     results = {}
     if doInfo:
         matches = True
         expectedPath = os.path.join(ufoPath1, "fontinfo.plist")
         writtenPath = os.path.join(self.dstDir, "fontinfo.plist")
         if not os.path.exists(writtenPath):
             matches = False
         else:
             expected = readPlist(expectedPath)
             written = readPlist(writtenPath)
             for attr, expectedValue in expected.items():
                 if expectedValue != written[attr]:
                     matches = False
                     break
         results["info"] = matches
     if doKerning:
         matches = True
         expectedPath = os.path.join(ufoPath1, "kerning.plist")
         writtenPath = os.path.join(self.dstDir, "kerning.plist")
         if not os.path.exists(writtenPath):
             matches = False
         else:
             matches = readPlist(expectedPath) == readPlist(writtenPath)
         results["kerning"] = matches
     if doGroups:
         matches = True
         expectedPath = os.path.join(ufoPath1, "groups.plist")
         writtenPath = os.path.join(self.dstDir, "groups.plist")
         if not os.path.exists(writtenPath):
             matches = False
         else:
             matches = readPlist(expectedPath) == readPlist(writtenPath)
         results["groups"] = matches
     if doFeatures:
         matches = True
         featuresPath = os.path.join(self.dstDir, "features.fea")
         libPath = os.path.join(self.dstDir, "lib.plist")
         if os.path.exists(featuresPath):
             matches = False
         else:
             fontLib = readPlist(libPath)
             writtenText = [fontLib.get("org.robofab.opentype.classes", "")]
             features = fontLib.get("org.robofab.opentype.features", {})
             featureOrder = fontLib.get("org.robofab.opentype.featureorder",
                                        [])
             for featureName in featureOrder:
                 writtenText.append(features.get(featureName, ""))
             writtenText = "\n".join(writtenText)
             # FontLab likes to add lines to the features, so skip blank lines.
             expectedText = [
                 line
                 for line in expectedFormatVersion1Features.splitlines()
                 if line
             ]
             writtenText = [
                 line for line in writtenText.splitlines() if line
             ]
             matches = "\n".join(expectedText) == "\n".join(writtenText)
         results["features"] = matches
     if doLib:
         matches = True
         expectedPath = os.path.join(ufoPath1, "lib.plist")
         writtenPath = os.path.join(self.dstDir, "lib.plist")
         if not os.path.exists(writtenPath):
             matches = False
         else:
             # the test file doesn't have the glyph order
             # so purge it from the written
             writtenLib = readPlist(writtenPath)
             del writtenLib["org.robofab.glyphOrder"]
             matches = readPlist(expectedPath) == writtenLib
         results["lib"] = matches
     return results
def exportUFO(font, newFile=True, doInfo=True, doKerning=True, doGroups=True, doLib=True, doFeatures=True,
    doHints=False, doMarks=True, doMasks=True, glyphs=None, formatVersion=2):
    # get the UFO path
    ufoPath = os.path.splitext(font.path)[0] + ".ufo"
    if not newFile:
        if not os.path.exists(ufoPath):
            Message("Could not find the UFO file \"%s\"." % os.path.basename(ufoPath))
            return
    else:
        if os.path.exists(ufoPath):
            ufoPath = _findAvailablePathName(ufoPath)
    # make sure no bogus glyph names are coming in
    if glyphs is not None:
        glyphs = [glyphName for glyphName in glyphs if font.has_key(glyphName)]
    # make the font the top font in FL
    fl.ifont = font.fontIndex
    # add the masks and marks to the glyph.lib
    if doMasks or doMarks:
        if glyphs is None:
            glyphNames = font.keys()
        else:
            glyphNames = glyphs
        for glyphName in glyphNames:
            glyph = font[glyphName]
            if doMarks:
                mark = glyph.mark
                glyph.lib[MARK_LIB_KEY] = mark
            if doMasks:
                # open a glyph window
                fl.EditGlyph(glyph.index)
                # switch to the mask layer
                fl.CallCommand(fl_cmd.ViewEditMask)
                # if the mask is empty, skip this step
                if not len(glyph):
                    # switch back to the edit layer
                    fl.CallCommand(fl_cmd.ViewEditMask)
                    continue
                # get the mask data
                pen = InstructionPointPen()
                glyph.drawPoints(pen)
                # switch back to the edit layer
                fl.CallCommand(fl_cmd.ViewEditMask)
                # write the mask data to the glyph lib
                instructions = pen.getInstructions()
                if instructions:
                    glyph.lib[MASK_LIB_KEY] = instructions
        # close all glyph windows. sometimes this actually works.
        fl.CallCommand(fl_cmd.WindowCloseAllGlyphWindows)
    # remove WWS names from the lib
    wwsStorage = {}
    if "openTypeNameWWSFamilyName" in font.lib:
        wwsStorage["openTypeNameWWSFamilyName"] = font.lib.pop(WWS_FAMILY_KEY)
    if "openTypeNameWWSSubfamilyName" in font.lib:
        wwsStorage["openTypeNameWWSSubfamilyName"] = font.lib.pop(WWS_SUBFAMILY_KEY)
    # write the UFO
    font.writeUFO(path=ufoPath, doHints=doHints, doInfo=doInfo,
        doKerning=doKerning, doGroups=doGroups, doLib=doLib, doFeatures=doFeatures, glyphs=glyphs,
        formatVersion=formatVersion)
    # add the WWS names to the info
    if doInfo:
        infoPath = os.path.join(ufoPath, "fontinfo.plist")
        info = readPlist(infoPath)
        newInfo = deepcopy(info)
        newInfo.update(wwsStorage)
        if info != newInfo:
            writePlist(newInfo, infoPath)
    # put the WWS names back in the lib
    font.lib.update(wwsStorage)
    # remove the masks and marks from the glyph.lib
    if doMasks or doMarks:
        if glyphs is None:
            glyphNames = font.keys()
        else:
            glyphNames = glyphs
        for glyphName in glyphNames:
            glyph = font[glyphName]
            lib = glyph.lib
            if lib.has_key(MASK_LIB_KEY):
                del lib[MASK_LIB_KEY]
            if lib.has_key(MARK_LIB_KEY):
                del lib[MARK_LIB_KEY]
示例#24
0
	def compareToUFO(self, doInfo=True, doKerning=True, doGroups=True, doLib=True, doFeatures=True):
		readerExpected = UFOReader(ufoPath2)
		readerWritten = UFOReader(self.dstDir)
		results = {}
		if doInfo:
			matches = True
			expectedPath = os.path.join(ufoPath2, "fontinfo.plist")
			writtenPath = os.path.join(self.dstDir, "fontinfo.plist")
			if not os.path.exists(writtenPath):
				matches = False
			else:
				dummyFont = NewFont()
				_ufoToFLAttrMapping = dict(dummyFont.info._ufoToFLAttrMapping)
				dummyFont.close()
				expected = readPlist(expectedPath)
				written = readPlist(writtenPath)
				for attr, expectedValue in expected.items():
					# cheat by skipping attrs that aren't supported
					if _ufoToFLAttrMapping[attr]["nakedAttribute"] is None:
						continue
					if expectedValue != written[attr]:
						matches = False
						break
			results["info"] = matches
		if doKerning:
			matches = True
			expectedPath = os.path.join(ufoPath2, "kerning.plist")
			writtenPath = os.path.join(self.dstDir, "kerning.plist")
			if not os.path.exists(writtenPath):
				matches = False
			else:
				matches = readPlist(expectedPath) == readPlist(writtenPath)
			results["kerning"] = matches
		if doGroups:
			matches = True
			expectedPath = os.path.join(ufoPath2, "groups.plist")
			writtenPath = os.path.join(self.dstDir, "groups.plist")
			if not os.path.exists(writtenPath):
				matches = False
			else:
				matches = readPlist(expectedPath) == readPlist(writtenPath)
			results["groups"] = matches
		if doFeatures:
			matches = True
			expectedPath = os.path.join(ufoPath2, "features.fea")
			writtenPath = os.path.join(self.dstDir, "features.fea")
			if not os.path.exists(writtenPath):
				matches = False
			else:
				f = open(expectedPath, "r")
				expectedText = f.read()
				f.close()
				f = open(writtenPath, "r")
				writtenText = f.read()
				f.close()
				# FontLab likes to add lines to the features, so skip blank lines.
				expectedText = [line for line in expectedText.splitlines() if line]
				writtenText = [line for line in writtenText.splitlines() if line]
				matches = "\n".join(expectedText) == "\n".join(writtenText)
			results["features"] = matches
		if doLib:
			matches = True
			expectedPath = os.path.join(ufoPath2, "lib.plist")
			writtenPath = os.path.join(self.dstDir, "lib.plist")
			if not os.path.exists(writtenPath):
				matches = False
			else:
				# the test file doesn't have the glyph order
				# so purge it from the written
				writtenLib = readPlist(writtenPath)
				del writtenLib["org.robofab.glyphOrder"]
				matches = readPlist(expectedPath) == writtenLib
			results["lib"] = matches
		return results
示例#25
0
	def compareToUFO(self, doInfo=True, doKerning=True, doGroups=True, doLib=True, doFeatures=True):
		readerExpected = UFOReader(ufoPath1)
		readerWritten = UFOReader(self.dstDir)
		results = {}
		if doInfo:
			matches = True
			expectedPath = os.path.join(ufoPath1, "fontinfo.plist")
			writtenPath = os.path.join(self.dstDir, "fontinfo.plist")
			if not os.path.exists(writtenPath):
				matches = False
			else:
				expected = readPlist(expectedPath)
				written = readPlist(writtenPath)
				for attr, expectedValue in expected.items():
					if expectedValue != written[attr]:
						matches = False
						break
			results["info"] = matches
		if doKerning:
			matches = True
			expectedPath = os.path.join(ufoPath1, "kerning.plist")
			writtenPath = os.path.join(self.dstDir, "kerning.plist")
			if not os.path.exists(writtenPath):
				matches = False
			else:
				matches = readPlist(expectedPath) == readPlist(writtenPath)
			results["kerning"] = matches
		if doGroups:
			matches = True
			expectedPath = os.path.join(ufoPath1, "groups.plist")
			writtenPath = os.path.join(self.dstDir, "groups.plist")
			if not os.path.exists(writtenPath):
				matches = False
			else:
				matches = readPlist(expectedPath) == readPlist(writtenPath)
			results["groups"] = matches
		if doFeatures:
			matches = True
			featuresPath = os.path.join(self.dstDir, "features.fea")
			libPath = os.path.join(self.dstDir, "lib.plist")
			if os.path.exists(featuresPath):
				matches = False
			else:
				fontLib = readPlist(libPath)
				writtenText = [fontLib.get("org.robofab.opentype.classes", "")]
				features = fontLib.get("org.robofab.opentype.features", {})
				featureOrder= fontLib.get("org.robofab.opentype.featureorder", [])
				for featureName in featureOrder:
					writtenText.append(features.get(featureName, ""))
				writtenText = "\n".join(writtenText)
				# FontLab likes to add lines to the features, so skip blank lines.
				expectedText = [line for line in expectedFormatVersion1Features.splitlines() if line]
				writtenText = [line for line in writtenText.splitlines() if line]
				matches = "\n".join(expectedText) == "\n".join(writtenText)
			results["features"] = matches
		if doLib:
			matches = True
			expectedPath = os.path.join(ufoPath1, "lib.plist")
			writtenPath = os.path.join(self.dstDir, "lib.plist")
			if not os.path.exists(writtenPath):
				matches = False
			else:
				# the test file doesn't have the glyph order
				# so purge it from the written
				writtenLib = readPlist(writtenPath)
				del writtenLib["org.robofab.glyphOrder"]
				matches = readPlist(expectedPath) == writtenLib
			results["lib"] = matches
		return results
示例#26
0
	def compareToUFO(self):
		readerExpected = UFOReader(ufoPath2)
		readerWritten = UFOReader(self.dstDir)
		results = {}
		# info
		matches = True
		expectedPath = os.path.join(ufoPath2, "fontinfo.plist")
		writtenPath = os.path.join(self.dstDir, "fontinfo.plist")
		if not os.path.exists(writtenPath):
			matches = False
		else:
			expected = readPlist(expectedPath)
			written = readPlist(writtenPath)
			for attr, expectedValue in expected.items():
				if expectedValue != written[attr]:
					matches = False
					break
		results["info"] = matches
		# kerning
		matches = True
		expectedPath = os.path.join(ufoPath2, "kerning.plist")
		writtenPath = os.path.join(self.dstDir, "kerning.plist")
		if not os.path.exists(writtenPath):
			matches = False
		else:
			matches = readPlist(expectedPath) == readPlist(writtenPath)
		results["kerning"] = matches
		# groups
		matches = True
		expectedPath = os.path.join(ufoPath2, "groups.plist")
		writtenPath = os.path.join(self.dstDir, "groups.plist")
		if not os.path.exists(writtenPath):
			matches = False
		else:
			matches = readPlist(expectedPath) == readPlist(writtenPath)
		results["groups"] = matches
		# features
		matches = True
		expectedPath = os.path.join(ufoPath2, "features.fea")
		writtenPath = os.path.join(self.dstDir, "features.fea")
		if not os.path.exists(writtenPath):
			matches = False
		else:
			f = open(expectedPath, "r")
			expectedText = f.read()
			f.close()
			f = open(writtenPath, "r")
			writtenText = f.read()
			f.close()
			# FontLab likes to add lines to the features, so skip blank lines.
			expectedText = [line for line in expectedText.splitlines() if line]
			writtenText = [line for line in writtenText.splitlines() if line]
			matches = "\n".join(expectedText) == "\n".join(writtenText)
		results["features"] = matches
		# lib
		matches = True
		expectedPath = os.path.join(ufoPath2, "lib.plist")
		writtenPath = os.path.join(self.dstDir, "lib.plist")
		if not os.path.exists(writtenPath):
			matches = False
		else:
			writtenLib = readPlist(writtenPath)
			matches = readPlist(expectedPath) == writtenLib
		results["lib"] = matches
		return results