Exemple #1
0
 def reloadLayers(self, layerData):
     """
     Reload the layers. This should not be called externally.
     """
     reader = UFOReader(self.font.path)
     # handle the layers
     currentLayerOrder = self.layerOrder
     for layerName, l in list(layerData.get("layers", {}).items()):
         # new layer
         if layerName not in currentLayerOrder:
             glyphSet = reader.getGlyphSet(layerName)
             self.newLayer(layerName, glyphSet)
         # get the layer
         layer = self[layerName]
         # reload the layer info
         if l.get("info"):
             layer.color = None
             layer.lib.clear()
             layer._glyphSet.readLayerInfo(layer)
             self._stampLayerInfoDataState(layer)
         # reload the glyphs
         glyphNames = l.get("glyphNames", [])
         if glyphNames:
             layer.reloadGlyphs(glyphNames)
     # handle the order
     if layerData.get("order", False):
         newLayerOrder = reader.getLayerNames()
         for layerName in self.layerOrder:
             if layerName not in newLayerOrder:
                 newLayerOrder.append(layerName)
         self.layerOrder = newLayerOrder
     # handle the default layer
     if layerData.get("default", False):
         newDefaultLayerName = reader.getDefaultLayerName()
         self.defaultLayer = self[newDefaultLayerName]
Exemple #2
0
def extractFontFromVFB(pathOrFile, destination, doGlyphs=True, doInfo=True, doKerning=True, doGroups=True, doFeatures=True, doLib=True, customFunctions=[]):
    ufoPath = tempfile.mkdtemp(suffix=".ufo")
    cmds = [_ufo2vfbLocation, "-64", pathOrFile, ufoPath]
    cmds = subprocess.list2cmdline(cmds)
    popen = subprocess.Popen(cmds, shell=True)
    popen.wait()
    try:
        # vfb2ufo writes ufo2, and has no update since 2015...so dont get to crazy here...
        source = UFOReader(ufoPath)
        if doInfo:
            source.readInfo(destination.info)
        if doKerning:
            kerning = source.readKerning()
            destination.kerning.update(kerning)
        if doGroups:
            groups = source.readGroups()
            destination.groups.update(groups)
        if doFeatures:
            features = source.readFeatures()
            destination.features.text = features
        if doLib:
            lib = source.readLib()
            destination.lib.update(lib)
        if doGlyphs:
            glyphSet = source.getGlyphSet()
            for glyphName in glyphSet.keys():
                destination.newGlyph(glyphName)
                glyph = destination[glyphName]
                pointPen = glyph.getPointPen()
                glyphSet.readGlyph(glyphName=glyphName, glyphObject=glyph, pointPen=pointPen)
        for function in customFunctions:
            function(source, destination)
    finally:
        shutil.rmtree(ufoPath)
 def reloadLayers(self, layerData):
     """
     Reload the layers. This should not be called externally.
     """
     reader = UFOReader(self.font.path)
     # handle the layers
     currentLayerOrder = self.layerOrder
     for layerName, l in list(layerData.get("layers", {}).items()):
         # new layer
         if layerName not in currentLayerOrder:
             glyphSet = reader.getGlyphSet(layerName)
             self.newLayer(layerName, glyphSet)
         # get the layer
         layer = self[layerName]
         # reload the layer info
         if l.get("info"):
             layer.color = None
             layer.lib.clear()
             layer._glyphSet.readLayerInfo(layer)
             self._stampLayerInfoDataState(layer)
         # reload the glyphs
         glyphNames = l.get("glyphNames", [])
         if glyphNames:
             layer.reloadGlyphs(glyphNames)
     # handle the order
     if layerData.get("order", False):
         newLayerOrder = reader.getLayerNames()
         for layerName in self.layerOrder:
             if layerName not in newLayerOrder:
                 newLayerOrder.append(layerName)
         self.layerOrder = newLayerOrder
     # handle the default layer
     if layerData.get("default", False):
         newDefaultLayerName = reader.getDefaultLayerName()
         self.defaultLayer = self[newDefaultLayerName]
Exemple #4
0
	def _loadData(self, path):
		from ufoLib import UFOReader
		reader = UFOReader(path)
		fontLib = reader.readLib()
		# info
		reader.readInfo(self.info)
		# kerning
		self.kerning.update(reader.readKerning())
		self.kerning.setChanged(False)
		# groups
		self.groups.update(reader.readGroups())
		# features
		if reader.formatVersion == 1:
			# migrate features from the lib
			features = []
			classes = fontLib.get("org.robofab.opentype.classes")
			if classes is not None:
				del fontLib["org.robofab.opentype.classes"]
				features.append(classes)
			splitFeatures = fontLib.get("org.robofab.opentype.features")
			if splitFeatures is not None:
				order = fontLib.get("org.robofab.opentype.featureorder")
				if order is None:
					order = splitFeatures.keys()
					order.sort()
				else:
					del fontLib["org.robofab.opentype.featureorder"]
				del fontLib["org.robofab.opentype.features"]
				for tag in order:
					oneFeature = splitFeatures.get(tag)
					if oneFeature is not None:
						features.append(oneFeature)
			features = "\n".join(features)
		else:
			features = reader.readFeatures()
		self.features.text = features
		# hint data
		self.psHints = PostScriptFontHintValues(self)
		if postScriptHintDataLibKey in fontLib:
			del fontLib[postScriptHintDataLibKey]
		# lib
		self.lib.update(fontLib)
		# glyphs
		self._glyphSet = reader.getGlyphSet()
		self._hasNotChanged(doGlyphs=False)
 def _loadData(self, path):
     from ufoLib import UFOReader
     reader = UFOReader(path)
     fontLib = reader.readLib()
     # info
     reader.readInfo(self.info)
     # kerning
     self.kerning.update(reader.readKerning())
     self.kerning.setChanged(False)
     # groups
     self.groups.update(reader.readGroups())
     # features
     if reader.formatVersion == 1:
         # migrate features from the lib
         features = []
         classes = fontLib.get("org.robofab.opentype.classes")
         if classes is not None:
             del fontLib["org.robofab.opentype.classes"]
             features.append(classes)
         splitFeatures = fontLib.get("org.robofab.opentype.features")
         if splitFeatures is not None:
             order = fontLib.get("org.robofab.opentype.featureorder")
             if order is None:
                 order = splitFeatures.keys()
                 order.sort()
             else:
                 del fontLib["org.robofab.opentype.featureorder"]
             del fontLib["org.robofab.opentype.features"]
             for tag in order:
                 oneFeature = splitFeatures.get(tag)
                 if oneFeature is not None:
                     features.append(oneFeature)
         features = "\n".join(features)
     else:
         features = reader.readFeatures()
     self.features.text = features
     # hint data
     self.psHints = PostScriptFontHintValues(self)
     if postScriptHintDataLibKey in fontLib:
         del fontLib[postScriptHintDataLibKey]
     # lib
     self.lib.update(fontLib)
     # glyphs
     self._glyphSet = reader.getGlyphSet()
     self._hasNotChanged(doGlyphs=False)
Exemple #6
0
def extractFontFromVFB(pathOrFile,
                       destination,
                       doGlyphs=True,
                       doInfo=True,
                       doKerning=True,
                       doGroups=True,
                       doFeatures=True,
                       doLib=True,
                       customFunctions=[]):
    ufoPath = tempfile.mkdtemp(suffix=".ufo")
    cmds = [_ufo2vfbLocation, "-64", pathOrFile, ufoPath]
    cmds = subprocess.list2cmdline(cmds)
    popen = subprocess.Popen(cmds, shell=True)
    popen.wait()
    try:
        # vfb2ufo writes ufo2, and has no update since 2015...so dont get to crazy here...
        source = UFOReader(ufoPath)
        if doInfo:
            source.readInfo(destination.info)
        if doKerning:
            kerning = source.readKerning()
            destination.kerning.update(kerning)
        if doGroups:
            groups = source.readGroups()
            destination.groups.update(groups)
        if doFeatures:
            features = source.readFeatures()
            destination.features.text = features
        if doLib:
            lib = source.readLib()
            destination.lib.update(lib)
        if doGlyphs:
            glyphSet = source.getGlyphSet()
            for glyphName in glyphSet.keys():
                destination.newGlyph(glyphName)
                glyph = destination[glyphName]
                pointPen = glyph.getPointPen()
                glyphSet.readGlyph(glyphName=glyphName,
                                   glyphObject=glyph,
                                   pointPen=pointPen)
        for function in customFunctions:
            function(source, destination)
    finally:
        shutil.rmtree(ufoPath)
Exemple #7
0
def copyAnchors(font, latinUFO):
    ufo = UFOReader(latinUFO)
    glyphset = ufo.getGlyphSet()
    # mark types are: "mark" "base" "ligature" "basemark" "entry" "exit"
    className2markType = {
        'MarkBelow': 'mark',
        'TashkilBelow': 'mark',
        'TashkilTashkilBelow': 'mark'
    }
    for name in glyphset.keys():
        if name not in font: continue
        glyph = glyphset[name]
        # need to draw to receive the data of the glyph and that ControlBoundsPen is harmless
        glyph.draw(ControlBoundsPen(glyphset))
        anchors = getattr(glyph, 'anchors', None)
        if not anchors: continue
        ffglyph = font[name]
        for anchor in anchors:
            ffglyph.addAnchorPoint(anchor['name'],
                                   className2markType[anchor['name']],
                                   anchor['x'], anchor['y'])
Exemple #8
0
class UFOFontData:
    def __init__(self, path, log_only, allow_decimal_coords,
                 write_to_default_layer):
        self._reader = UFOReader(path, validate=False)

        self.path = path
        self.glyphMap = {}
        self.processedLayerGlyphMap = {}
        self.newGlyphMap = {}
        self.glyphList = []
        self._fontInfo = None
        self._glyphsets = {}
        # If True, we are running in report mode and not doing any changes, so
        # we skip the hash map and process all glyphs.
        self.log_only = log_only
        # Used to store the hash of glyph data of already processed glyphs. If
        # the stored hash matches the calculated one, we skip the glyph.
        self._hashmap = None
        self.fontDict = None
        self.hashMapChanged = False
        # If True, then write data to the default layer
        self.writeToDefaultLayer = write_to_default_layer
        # if True, do NOT round x,y values when processing.
        self.allowDecimalCoords = allow_decimal_coords

        self._load_glyphmap()

    def getUnitsPerEm(self):
        return self.fontInfo.get("unitsPerEm", 1000)

    def getPSName(self):
        return self.fontInfo.get("postscriptFontName", "PSName-Undefined")

    @staticmethod
    def isCID():
        return False

    def convertToBez(self, glyphName, read_hints, doAll=False):
        # We do not yet support reading hints, so read_hints is ignored.
        width, bez, skip = self._get_or_skip_glyph(glyphName, doAll)
        if skip:
            return None, width

        bezString = "\n".join(bez)
        bezString = "\n".join(["% " + glyphName, "sc", bezString, "ed", ""])
        return bezString, width

    def updateFromBez(self, bezData, name, width):
        # For UFO font, we don't use the width parameter:
        # it is carried over from the input glif file.
        layer = None
        if name in self.processedLayerGlyphMap:
            layer = PROCESSED_LAYER_NAME
        glyphset = self._get_glyphset(layer)

        glyph = BezGlyph(bezData)
        glyphset.readGlyph(name, glyph)
        self.newGlyphMap[name] = glyph

        # updateFromBez is called only if the glyph has been autohinted which
        # might also change its outline data. We need to update the edit status
        # in the hash map entry. I assume that convertToBez has been run
        # before, which will add an entry for this glyph.
        self.updateHashEntry(name)

    def save(self, path):
        if path is None:
            path = self.path

        if os.path.abspath(self.path) != os.path.abspath(path):
            # If user has specified a path other than the source font path,
            # then copy the entire UFO font, and operate on the copy.
            log.info("Copying from source UFO font to output UFO font before "
                     "processing...")
            if os.path.exists(path):
                shutil.rmtree(path)
            shutil.copytree(self.path, path)

        writer = UFOWriter(path, self._reader.formatVersion, validate=False)

        if self.hashMapChanged:
            self.writeHashMap(writer)
        self.hashMapChanged = False

        layer = PROCESSED_LAYER_NAME
        if self.writeToDefaultLayer:
            layer = None

        # Write glyphs.
        glyphset = writer.getGlyphSet(layer, defaultLayer=layer is None)
        for name, glyph in self.newGlyphMap.items():
            filename = self.glyphMap[name]
            if not self.writeToDefaultLayer and \
                    name in self.processedLayerGlyphMap:
                filename = self.processedLayerGlyphMap[name]
            glyphset.contents[name] = filename
            glyphset.writeGlyph(name, glyph, glyph.drawPoints)
        glyphset.writeContents()

        # Write layer contents.
        layers = {DEFAULT_LAYER_NAME: DEFAULT_GLYPHS_DIRNAME}
        if self.processedLayerGlyphMap:
            layers[PROCESSED_LAYER_NAME] = PROCESSED_GLYPHS_DIRNAME
        writer.layerContents.update(layers)
        writer.writeLayerContents([DEFAULT_LAYER_NAME, PROCESSED_LAYER_NAME])

    @property
    def hashMap(self):
        if self._hashmap is None:
            data = self._reader.readBytesFromPath(
                os.path.join(DATA_DIRNAME, HASHMAP_NAME))
            if data:
                hashmap = ast.literal_eval(data.decode("utf-8"))
            else:
                hashmap = {HASHMAP_VERSION_NAME: HASHMAP_VERSION}

            version = (0, 0)
            if HASHMAP_VERSION_NAME in hashmap:
                version = hashmap[HASHMAP_VERSION_NAME]

            if version[0] > HASHMAP_VERSION[0]:
                raise FontParseError("Hash map version is newer than "
                                     "psautohint. Please update.")
            elif version[0] < HASHMAP_VERSION[0]:
                log.info("Updating hash map: was older version")
                hashmap = {HASHMAP_VERSION_NAME: HASHMAP_VERSION}

            self._hashmap = hashmap
        return self._hashmap

    def writeHashMap(self, writer):
        hashMap = self.hashMap
        if not hashMap:
            return  # no glyphs were processed.

        hasMapKeys = hashMap.keys()
        hasMapKeys = sorted(hasMapKeys)
        data = ["{"]
        for gName in hasMapKeys:
            data.append("'%s': %s," % (gName, hashMap[gName]))
        data.append("}")
        data.append("")
        data = "\n".join(data)

        writer.writeBytesToPath(os.path.join(DATA_DIRNAME, HASHMAP_NAME),
                                data.encode("utf-8"))

    def updateHashEntry(self, glyphName):
        # srcHash has already been set: we are fixing the history list.

        # Get hash entry for glyph
        srcHash, historyList = self.hashMap[glyphName]

        self.hashMapChanged = True
        # If the program is not in the history list, add it.
        if AUTOHINT_NAME not in historyList:
            historyList.append(AUTOHINT_NAME)

    def checkSkipGlyph(self, glyphName, newSrcHash, doAll):
        skip = False
        if self.log_only:
            return skip

        srcHash = None
        historyList = []

        # Get hash entry for glyph
        if glyphName in self.hashMap:
            srcHash, historyList = self.hashMap[glyphName]

        if srcHash == newSrcHash:
            if AUTOHINT_NAME in historyList:
                # The glyph has already been autohinted, and there have been no
                # changes since.
                skip = not doAll
            if not skip and AUTOHINT_NAME not in historyList:
                historyList.append(AUTOHINT_NAME)
        else:
            if CHECKOUTLINE_NAME in historyList:
                log.error("Glyph '%s' has been edited. You must first "
                          "run '%s' before running '%s'. Skipping.",
                          glyphName, CHECKOUTLINE_NAME, AUTOHINT_NAME)
                skip = True

            # If the source hash has changed, we need to delete the processed
            # layer glyph.
            self.hashMapChanged = True
            self.hashMap[glyphName] = [newSrcHash, [AUTOHINT_NAME]]
            if glyphName in self.processedLayerGlyphMap:
                del self.processedLayerGlyphMap[glyphName]

        return skip

    def _get_glyphset(self, layer_name=None):
        if layer_name not in self._glyphsets:
            glyphset = None
            if layer_name is None or layer_name in \
                    self._reader.getLayerNames():
                glyphset = self._reader.getGlyphSet(layer_name)
            self._glyphsets[layer_name] = glyphset
        return self._glyphsets[layer_name]

    def get_glyph_bez(self, glyph):
        pen = BezPen(glyph.glyphSet, self)
        glyph.draw(pen)
        if not hasattr(glyph, "width"):
            glyph.width = 1000
        return pen.bez

    def _get_or_skip_glyph(self, name, doAll):
        # Get default glyph layer data, so we can check if the glyph
        # has been edited since this program was last run.
        # If the program name is in the history list, and the srcHash
        # matches the default glyph layer data, we can skip.
        glyphset = self._get_glyphset()
        glyph = glyphset[name]
        bez = self.get_glyph_bez(glyph)

        # Hash is always from the default glyph layer.
        hash_pen = HashPointPen(glyph)
        glyph.drawPoints(hash_pen)
        skip = self.checkSkipGlyph(name, hash_pen.getHash(), doAll)

        # If there is a glyph in the processed layer, get the outline from it.
        if name in self.processedLayerGlyphMap:
            glyphset = self._get_glyphset(PROCESSED_LAYER_NAME)
            glyph = glyphset[name]
            bez = self.get_glyph_bez(glyph)

        return glyph.width, bez, skip

    def getGlyphList(self):
        return self.glyphList

    def _load_glyphmap(self):
        # Need to both get the list of glyphs in the font, and also the glyph
        # order. The latter is taken from the public.glyphOrder key in the lib,
        # if it exists, else it is taken from the contents.  Any existing
        # glyphs which are not named in the public.glyphOrder are sorted after
        # all glyphs which are named in the public.glyphOrder, in the order
        # that they occurred in contents.plist.
        glyphset = self._get_glyphset()
        self.glyphMap = glyphset.contents
        self.glyphList = glyphset.keys()

        self.orderMap = {}
        fontlib = self._reader.readLib()
        glyphOrder = fontlib.get(PUBLIC_GLYPH_ORDER, self.glyphList)
        for i, name in enumerate(glyphOrder):
            self.orderMap[name] = i

        # If there are glyphs in the font which are not named in the
        # public.glyphOrder entry, add them in the order of the
        # contents.plist file.
        for name in self.glyphList:
            if name not in self.orderMap:
                self.orderMap[name] = len(self.orderMap)
        self.glyphList = sorted(list(self.orderMap.keys()))

        # I also need to get the glyph map for the processed layer,
        # and use this when the glyph is read from the processed layer.
        # glyph file names that differ from what is in the default glyph layer.
        # Because checkOutliensUFO used the defcon library, it can write
        glyphset = self._get_glyphset(PROCESSED_LAYER_NAME)
        if glyphset is not None:
            self.processedLayerGlyphMap = glyphset.contents

    @property
    def fontInfo(self):
        if self._fontInfo is None:
            info = SimpleNamespace()
            self._reader.readInfo(info)
            self._fontInfo = vars(info)
        return self._fontInfo

    def getFontInfo(self, allow_no_blues, noFlex,
                    vCounterGlyphs, hCounterGlyphs, fdIndex=0):
        if self.fontDict is not None:
            return self.fontDict

        fdDict = fdTools.FDDict()
        # should be 1 if the glyphs are ideographic, else 0.
        fdDict.LanguageGroup = self.fontInfo.get("languagegroup", "0")
        fdDict.OrigEmSqUnits = self.getUnitsPerEm()
        fdDict.FontName = self.getPSName()
        upm = self.getUnitsPerEm()
        low = min(-upm * 0.25,
                  self.fontInfo.get("openTypeOS2WinDescent", 0) - 200)
        high = max(upm * 1.25,
                   self.fontInfo.get("openTypeOS2WinAscent", 0) + 200)
        # Make a set of inactive alignment zones: zones outside of the font
        # bbox so as not to affect hinting. Used when src font has no
        # BlueValues or has invalid BlueValues. Some fonts have bad BBox
        # values, so I don't let this be smaller than -upm*0.25, upm*1.25.
        inactiveAlignmentValues = [low, low, high, high]
        blueValues = self.fontInfo.get("postscriptBlueValues", [])
        numBlueValues = len(blueValues)
        if numBlueValues < 4:
            if allow_no_blues:
                blueValues = inactiveAlignmentValues
                numBlueValues = len(blueValues)
            else:
                raise FontParseError(
                    "Font must have at least four values in its "
                    "BlueValues array for PSAutoHint to work!")
        blueValues.sort()
        # The first pair only is a bottom zone, where the first value is the
        # overshoot position; the rest are top zones, and second value of the
        # pair is the overshoot position.
        blueValues[0] = blueValues[0] - blueValues[1]
        for i in range(3, numBlueValues, 2):
            blueValues[i] = blueValues[i] - blueValues[i - 1]

        blueValues = [str(v) for v in blueValues]
        numBlueValues = min(numBlueValues, len(fdTools.kBlueValueKeys))
        for i in range(numBlueValues):
            key = fdTools.kBlueValueKeys[i]
            value = blueValues[i]
            setattr(fdDict, key, value)

        otherBlues = self.fontInfo.get("postscriptOtherBlues", [])
        numBlueValues = len(otherBlues)

        if len(otherBlues) > 0:
            i = 0
            numBlueValues = len(otherBlues)
            otherBlues.sort()
            for i in range(0, numBlueValues, 2):
                otherBlues[i] = otherBlues[i] - otherBlues[i + 1]
            otherBlues = [str(v) for v in otherBlues]
            numBlueValues = min(numBlueValues,
                                len(fdTools.kOtherBlueValueKeys))
            for i in range(numBlueValues):
                key = fdTools.kOtherBlueValueKeys[i]
                value = otherBlues[i]
                setattr(fdDict, key, value)

        vstems = self.fontInfo.get("postscriptStemSnapV", [])
        if not vstems:
            if allow_no_blues:
                # dummy value. Needs to be larger than any hint will likely be,
                # as the autohint program strips out any hint wider than twice
                # the largest global stem width.
                vstems = [fdDict.OrigEmSqUnits]
            else:
                raise FontParseError("Font does not have postscriptStemSnapV!")

        vstems.sort()
        if not vstems or (len(vstems) == 1 and vstems[0] < 1):
            # dummy value that will allow PyAC to run
            vstems = [fdDict.OrigEmSqUnits]
            log.warning("There is no value or 0 value for DominantV.")
        fdDict.DominantV = "[" + " ".join([str(v) for v in vstems]) + "]"

        hstems = self.fontInfo.get("postscriptStemSnapH", [])
        if not hstems:
            if allow_no_blues:
                # dummy value. Needs to be larger than any hint will likely be,
                # as the autohint program strips out any hint wider than twice
                # the largest global stem width.
                hstems = [fdDict.OrigEmSqUnits]
            else:
                raise FontParseError("Font does not have postscriptStemSnapH!")

        hstems.sort()
        if not hstems or (len(hstems) == 1 and hstems[0] < 1):
            # dummy value that will allow PyAC to run
            hstems = [fdDict.OrigEmSqUnits]
            log.warning("There is no value or 0 value for DominantH.")
        fdDict.DominantH = "[" + " ".join([str(v) for v in hstems]) + "]"

        if noFlex:
            fdDict.FlexOK = "false"
        else:
            fdDict.FlexOK = "true"

        # Add candidate lists for counter hints, if any.
        if vCounterGlyphs:
            temp = " ".join(vCounterGlyphs)
            fdDict.VCounterChars = "( %s )" % (temp)
        if hCounterGlyphs:
            temp = " ".join(hCounterGlyphs)
            fdDict.HCounterChars = "( %s )" % (temp)

        fdDict.BlueFuzz = self.fontInfo.get("postscriptBlueFuzz", 1)
        # postscriptBlueShift
        # postscriptBlueScale
        self.fontDict = fdDict
        return fdDict

    def getfdInfo(self, allow_no_blues, noFlex, vCounterGlyphs, hCounterGlyphs,
                  glyphList, fdIndex=0):
        fdGlyphDict = None
        fdDict = self.getFontInfo(allow_no_blues, noFlex,
                                  vCounterGlyphs, hCounterGlyphs, fdIndex)
        fontDictList = [fdDict]

        # Check the fontinfo file, and add any other font dicts
        srcFontInfo = os.path.dirname(self.path)
        srcFontInfo = os.path.join(srcFontInfo, "fontinfo")
        maxX = self.getUnitsPerEm() * 2
        maxY = maxX
        minY = -self.getUnitsPerEm()
        if os.path.exists(srcFontInfo):
            with open(srcFontInfo, "r", encoding="utf-8") as fi:
                fontInfoData = fi.read()
            fontInfoData = re.sub(r"#[^\r\n]+", "", fontInfoData)

            if "FDDict" in fontInfoData:
                fdGlyphDict, fontDictList, finalFDict = \
                    fdTools.parseFontInfoFile(
                        fontDictList, fontInfoData, glyphList, maxY, minY,
                        self.getPSName())
                if finalFDict is None:
                    # If a font dict was not explicitly specified for the
                    # output font, use the first user-specified font dict.
                    fdTools.mergeFDDicts(fontDictList[1:], self.fontDict)
                else:
                    fdTools.mergeFDDicts([finalFDict], self.fontDict)

        return fdGlyphDict, fontDictList

    def getGlyphID(self, glyphName):
        try:
            gid = self.orderMap[glyphName]
        except IndexError:
            raise FontParseError(
                "Could not find glyph name '%s' in UFO font contents plist. "
                "'%s'. " % (glyphName, self.path))
        return gid

    @staticmethod
    def close():
        return
Exemple #9
0
            or 0x0750 <= uni <= 0x077F \
            or 0x08A0 <= uni <= 0x08FF:
        return False

    # print 'kept uni name:', name;
    return True

if __name__ == '__main__':
    # opened with ufoLib
    sourceFontPath = sys.argv[1]
    # suppose this is a fontforge format, it will be opened with the
    # fontforge api
    existingFontPath = sys.argv[2]

    sourceReader = UFOReader(sourceFontPath)
    sourceGlyphSet = sourceReader.getGlyphSet()
    sourceGlyphNames = set(sourceGlyphSet.keys())

    existingFont = fontforge.open(existingFontPath)
    existingGlyphNames = set(existingFont.__iter__())

    justInSource = sourceGlyphNames - existingGlyphNames
    # print 'glyphs in both:', sourceGlyphNames & existingGlyphNames
    # print 'glyphs only in source:', justInSource

    filtered = [name for name in justInSource if isValid(name)]
    overlapping = [name for name in (sourceGlyphNames & existingGlyphNames) if isValid(name)]
    print 'from the latin and valid:', sorted(filtered)
    print '------------------'
    print 'overlapping and valid', sorted(overlapping)