def setupFile_menuName(self, path): """ Make the menu name source file. This gets the values for the file using the fallback system as described below: ==== === [PS] postscriptFontName f= openTypeNamePreferredFamilyName s= openTypeNamePreferredSubfamilyName l= styleMapFamilyName m=1, openTypeNameCompatibleFullName ==== === **This should not be called externally.** Subclasses may override this method to handle the file creation in a different way if desired. """ psName = getAttrWithFallback(self.font.info, "postscriptFontName") lines = ["[%s]" % psName] # family name familyName = getAttrWithFallback(self.font.info, "openTypeNamePreferredFamilyName") encodedFamilyName = winStr(familyName) lines.append("f=%s" % encodedFamilyName) if encodedFamilyName != familyName: lines.append("f=1,%s" % macStr(familyName)) # style name styleName = getAttrWithFallback(self.font.info, "openTypeNamePreferredSubfamilyName") encodedStyleName = winStr(styleName) lines.append("s=%s" % encodedStyleName) if encodedStyleName != styleName: lines.append("s=1,%s" % macStr(styleName)) # compatible name winCompatible = getAttrWithFallback(self.font.info, "styleMapFamilyName") ## the second qualification here is in place for Mac Office <= 2004. ## in that app the menu name is pulled from name ID 18. the font ## may have standard naming data that combines to a length longer ## than the app can handle (see Adobe Tech Note #5088). the designer ## may have created a specific openTypeNameCompatibleFullName to ## get around this problem. sigh, old app bugs live long lives. if winCompatible != familyName or self.font.info.openTypeNameCompatibleFullName is not None: # windows l = "l=%s" % normalizeStringForPostscript(winCompatible) lines.append(l) # mac macCompatible = getAttrWithFallback( self.font.info, "openTypeNameCompatibleFullName") l = "m=1,%s" % macStr(macCompatible) lines.append(l) text = "\n".join(lines) + "\n" f = open(path, "wb") f.write(text) f.close()
def setupFile_menuName(self, path): """ Make the menu name source file. This gets the values for the file using the fallback system as described below: ==== === [PS] postscriptFontName f= openTypeNamePreferredFamilyName s= openTypeNamePreferredSubfamilyName l= styleMapFamilyName m=1, openTypeNameCompatibleFullName ==== === **This should not be called externally.** Subclasses may override this method to handle the file creation in a different way if desired. """ psName = getAttrWithFallback(self.font.info,"postscriptFontName") lines = [ "[%s]" % psName ] # family name familyName = getAttrWithFallback(self.font.info,"openTypeNamePreferredFamilyName") encodedFamilyName = winStr(familyName) lines.append("f=%s" % encodedFamilyName) if encodedFamilyName != familyName: lines.append("f=1,%s" % macStr(familyName)) # style name styleName = getAttrWithFallback(self.font.info,"openTypeNamePreferredSubfamilyName") encodedStyleName = winStr(styleName) lines.append("s=%s" % encodedStyleName) if encodedStyleName != styleName: lines.append("s=1,%s" % macStr(styleName)) # compatible name winCompatible = getAttrWithFallback(self.font.info,"styleMapFamilyName") ## the second qualification here is in place for Mac Office <= 2004. ## in that app the menu name is pulled from name ID 18. the font ## may have standard naming data that combines to a length longer ## than the app can handle (see Adobe Tech Note #5088). the designer ## may have created a specific openTypeNameCompatibleFullName to ## get around this problem. sigh, old app bugs live long lives. if winCompatible != familyName or self.font.info.openTypeNameCompatibleFullName is not None: # windows l = "l=%s" % normalizeStringForPostscript(winCompatible) lines.append(l) # mac macCompatible = getAttrWithFallback(self.font.info,"openTypeNameCompatibleFullName") l = "m=1,%s" % macStr(macCompatible) lines.append(l) text = "\n".join(lines) + "\n" f = open(path, "wb") f.write(text) f.close()
def setupTable_CFF(self): """ Make the CFF table. **This should not be called externally.** Subclasses may override or supplement this method to handle the table creation in a different way if desired. """ self.otf["CFF "] = cff = newTable("CFF ") cff = cff.cff # set up the basics cff.major = 1 cff.minor = 0 cff.hdrSize = 4 cff.offSize = 4 cff.fontNames = [] strings = IndexedStrings() cff.strings = strings private = PrivateDict(strings=strings) private.rawDict.update(private.defaults) globalSubrs = GlobalSubrsIndex(private=private) topDict = TopDict(GlobalSubrs=globalSubrs, strings=strings) topDict.Private = private charStrings = topDict.CharStrings = CharStrings( file=None, charset=None, globalSubrs=globalSubrs, private=private, fdSelect=None, fdArray=None) charStrings.charStringsAreIndexed = True topDict.charset = [] charStringsIndex = charStrings.charStringsIndex = SubrsIndex( private=private, globalSubrs=globalSubrs) cff.topDictIndex = topDictIndex = TopDictIndex() topDictIndex.append(topDict) topDictIndex.strings = strings cff.GlobalSubrs = globalSubrs # populate naming data info = self.ufo.info psName = getAttrWithFallback(info, "postscriptFontName") cff.fontNames.append(psName) topDict = cff.topDictIndex[0] topDict.version = "%d.%d" % (getAttrWithFallback( info, "versionMajor"), getAttrWithFallback(info, "versionMinor")) trademark = getAttrWithFallback(info, "trademark") if trademark: trademark = normalizeStringForPostscript( trademark.replace(u"\u00A9", "Copyright")) if trademark != self.ufo.info.trademark: self.log.append( "[Warning] The trademark was normalized for storage in the CFF table and consequently some characters were dropped: '%s'" % trademark) if trademark is None: trademark = "" topDict.Notice = trademark copyright = getAttrWithFallback(info, "copyright") if copyright: copyright = normalizeStringForPostscript( copyright.replace(u"\u00A9", "Copyright")) if copyright != self.ufo.info.copyright: self.log.append( "[Warning] The copyright was normalized for storage in the CFF table and consequently some characters were dropped: '%s'" % copyright) if copyright is None: copyright = "" topDict.Copyright = copyright topDict.FullName = getAttrWithFallback(info, "postscriptFullName") topDict.FamilyName = getAttrWithFallback( info, "openTypeNamePreferredFamilyName") topDict.Weight = getAttrWithFallback(info, "postscriptWeightName") topDict.FontName = getAttrWithFallback(info, "postscriptFontName") # populate various numbers topDict.isFixedPitch = getAttrWithFallback(info, "postscriptIsFixedPitch") topDict.ItalicAngle = getAttrWithFallback(info, "italicAngle") underlinePosition = getAttrWithFallback(info, "postscriptUnderlinePosition") if underlinePosition is None: underlinePosition = 0 topDict.UnderlinePosition = _roundInt(underlinePosition) underlineThickness = getAttrWithFallback( info, "postscriptUnderlineThickness") if underlineThickness is None: underlineThickness = 0 topDict.UnderlineThickness = _roundInt(underlineThickness) # populate font matrix unitsPerEm = _roundInt(getAttrWithFallback(info, "unitsPerEm")) topDict.FontMatrix = [1.0 / unitsPerEm, 0, 0, 1.0 / unitsPerEm, 0, 0] # populate the width values defaultWidthX = _roundInt( getAttrWithFallback(info, "postscriptDefaultWidthX")) if defaultWidthX: private.rawDict["defaultWidthX"] = defaultWidthX nominalWidthX = _roundInt( getAttrWithFallback(info, "postscriptNominalWidthX")) if nominalWidthX: private.rawDict["nominalWidthX"] = nominalWidthX # populate hint data blueFuzz = _roundInt(getAttrWithFallback(info, "postscriptBlueFuzz")) blueShift = _roundInt(getAttrWithFallback(info, "postscriptBlueShift")) blueScale = getAttrWithFallback(info, "postscriptBlueScale") forceBold = getAttrWithFallback(info, "postscriptForceBold") blueValues = getAttrWithFallback(info, "postscriptBlueValues") if isinstance(blueValues, list): blueValues = [_roundInt(i) for i in blueValues] otherBlues = getAttrWithFallback(info, "postscriptOtherBlues") if isinstance(otherBlues, list): otherBlues = [_roundInt(i) for i in otherBlues] familyBlues = getAttrWithFallback(info, "postscriptFamilyBlues") if isinstance(familyBlues, list): familyBlues = [_roundInt(i) for i in familyBlues] familyOtherBlues = getAttrWithFallback(info, "postscriptFamilyOtherBlues") if isinstance(familyOtherBlues, list): familyOtherBlues = [_roundInt(i) for i in familyOtherBlues] stemSnapH = getAttrWithFallback(info, "postscriptStemSnapH") if isinstance(stemSnapH, list): stemSnapH = [_roundInt(i) for i in stemSnapH] stemSnapV = getAttrWithFallback(info, "postscriptStemSnapV") if isinstance(stemSnapV, list): stemSnapV = [_roundInt(i) for i in stemSnapV] # only write the blues data if some blues are defined. if (blueValues or otherBlues): private.rawDict["BlueFuzz"] = blueFuzz private.rawDict["BlueShift"] = blueShift private.rawDict["BlueScale"] = blueScale private.rawDict["ForceBold"] = forceBold private.rawDict["BlueValues"] = blueValues private.rawDict["OtherBlues"] = otherBlues private.rawDict["FamilyBlues"] = familyBlues private.rawDict["FamilyOtherBlues"] = familyOtherBlues # only write the stems if both are defined. if (stemSnapH and stemSnapV): private.rawDict["StemSnapH"] = stemSnapH private.rawDict["StdHW"] = stemSnapH[0] private.rawDict["StemSnapV"] = stemSnapV private.rawDict["StdVW"] = stemSnapV[0] # populate glyphs for glyphName in self.glyphOrder: glyph = self.allGlyphs[glyphName] unicodes = glyph.unicodes charString = self.getCharStringForGlyph(glyph, private, globalSubrs) # add to the font exists = charStrings.has_key(glyphName) if exists: # XXX a glyph already has this name. should we choke? glyphID = charStrings.charStrings[glyphName] charStringsIndex.items[glyphID] = charString else: charStringsIndex.append(charString) glyphID = len(topDict.charset) charStrings.charStrings[glyphName] = glyphID topDict.charset.append(glyphName) topDict.FontBBox = self.fontBoundingBox # write the glyph order self.otf.setGlyphOrder(self.glyphOrder)
def setupTable_CFF(self): """ Make the CFF table. **This should not be called externally.** Subclasses may override or supplement this method to handle the table creation in a different way if desired. """ self.otf["CFF "] = cff = newTable("CFF ") cff = cff.cff # set up the basics cff.major = 1 cff.minor = 0 cff.hdrSize = 4 cff.offSize = 4 cff.fontNames = [] strings = IndexedStrings() cff.strings = strings private = PrivateDict(strings=strings) private.rawDict.update(private.defaults) globalSubrs = GlobalSubrsIndex(private=private) topDict = TopDict(GlobalSubrs=globalSubrs, strings=strings) topDict.Private = private charStrings = topDict.CharStrings = CharStrings(file=None, charset=None, globalSubrs=globalSubrs, private=private, fdSelect=None, fdArray=None) charStrings.charStringsAreIndexed = True topDict.charset = [] charStringsIndex = charStrings.charStringsIndex = SubrsIndex(private=private, globalSubrs=globalSubrs) cff.topDictIndex = topDictIndex = TopDictIndex() topDictIndex.append(topDict) topDictIndex.strings = strings cff.GlobalSubrs = globalSubrs # populate naming data info = self.ufo.info psName = getAttrWithFallback(info, "postscriptFontName") cff.fontNames.append(psName) topDict = cff.topDictIndex[0] topDict.version = "%d.%d" % (getAttrWithFallback(info, "versionMajor"), getAttrWithFallback(info, "versionMinor")) trademark = getAttrWithFallback(info, "trademark") if trademark: trademark = normalizeStringForPostscript(trademark.replace(u"\u00A9", "Copyright")) if trademark != self.ufo.info.trademark: self.log.append("[Warning] The trademark was normalized for storage in the CFF table and consequently some characters were dropped: '%s'" % trademark) if trademark is None: trademark = "" topDict.Notice = trademark copyright = getAttrWithFallback(info, "copyright") if copyright: copyright = normalizeStringForPostscript(copyright.replace(u"\u00A9", "Copyright")) if copyright != self.ufo.info.copyright: self.log.append("[Warning] The copyright was normalized for storage in the CFF table and consequently some characters were dropped: '%s'" % copyright) if copyright is None: copyright = "" topDict.Copyright = copyright topDict.FullName = getAttrWithFallback(info, "postscriptFullName") topDict.FamilyName = getAttrWithFallback(info, "openTypeNamePreferredFamilyName") topDict.Weight = getAttrWithFallback(info, "postscriptWeightName") topDict.FontName = getAttrWithFallback(info, "postscriptFontName") # populate various numbers topDict.isFixedPitch = getAttrWithFallback(info, "postscriptIsFixedPitch") topDict.ItalicAngle = getAttrWithFallback(info, "italicAngle") underlinePosition = getAttrWithFallback(info, "postscriptUnderlinePosition") if underlinePosition is None: underlinePosition = 0 topDict.UnderlinePosition = _roundInt(underlinePosition) underlineThickness = getAttrWithFallback(info, "postscriptUnderlineThickness") if underlineThickness is None: underlineThickness = 0 topDict.UnderlineThickness = _roundInt(underlineThickness) # populate font matrix unitsPerEm = _roundInt(getAttrWithFallback(info, "unitsPerEm")) topDict.FontMatrix = [1.0 / unitsPerEm, 0, 0, 1.0 / unitsPerEm, 0, 0] # populate the width values defaultWidthX = _roundInt(getAttrWithFallback(info, "postscriptDefaultWidthX")) if defaultWidthX: private.rawDict["defaultWidthX"] = defaultWidthX nominalWidthX = _roundInt(getAttrWithFallback(info, "postscriptNominalWidthX")) if nominalWidthX: private.rawDict["nominalWidthX"] = nominalWidthX # populate hint data blueFuzz = _roundInt(getAttrWithFallback(info, "postscriptBlueFuzz")) blueShift = _roundInt(getAttrWithFallback(info, "postscriptBlueShift")) blueScale = getAttrWithFallback(info, "postscriptBlueScale") forceBold = getAttrWithFallback(info, "postscriptForceBold") blueValues = getAttrWithFallback(info, "postscriptBlueValues") if isinstance(blueValues, list): blueValues = [_roundInt(i) for i in blueValues] otherBlues = getAttrWithFallback(info, "postscriptOtherBlues") if isinstance(otherBlues, list): otherBlues = [_roundInt(i) for i in otherBlues] familyBlues = getAttrWithFallback(info, "postscriptFamilyBlues") if isinstance(familyBlues, list): familyBlues = [_roundInt(i) for i in familyBlues] familyOtherBlues = getAttrWithFallback(info, "postscriptFamilyOtherBlues") if isinstance(familyOtherBlues, list): familyOtherBlues = [_roundInt(i) for i in familyOtherBlues] stemSnapH = getAttrWithFallback(info, "postscriptStemSnapH") if isinstance(stemSnapH, list): stemSnapH = [_roundInt(i) for i in stemSnapH] stemSnapV = getAttrWithFallback(info, "postscriptStemSnapV") if isinstance(stemSnapV, list): stemSnapV = [_roundInt(i) for i in stemSnapV] # only write the blues data if some blues are defined. if (blueValues or otherBlues): private.rawDict["BlueFuzz"] = blueFuzz private.rawDict["BlueShift"] = blueShift private.rawDict["BlueScale"] = blueScale private.rawDict["ForceBold"] = forceBold private.rawDict["BlueValues"] = blueValues private.rawDict["OtherBlues"] = otherBlues private.rawDict["FamilyBlues"] = familyBlues private.rawDict["FamilyOtherBlues"] = familyOtherBlues # only write the stems if both are defined. if (stemSnapH and stemSnapV): private.rawDict["StemSnapH"] = stemSnapH private.rawDict["StdHW"] = stemSnapH[0] private.rawDict["StemSnapV"] = stemSnapV private.rawDict["StdVW"] = stemSnapV[0] # populate glyphs for glyphName in self.glyphOrder: glyph = self.allGlyphs[glyphName] unicodes = glyph.unicodes charString = self.getCharStringForGlyph(glyph, private, globalSubrs) # add to the font exists = charStrings.has_key(glyphName) if exists: # XXX a glyph already has this name. should we choke? glyphID = charStrings.charStrings[glyphName] charStringsIndex.items[glyphID] = charString else: charStringsIndex.append(charString) glyphID = len(topDict.charset) charStrings.charStrings[glyphName] = glyphID topDict.charset.append(glyphName) topDict.FontBBox = self.fontBoundingBox # write the glyph order self.otf.setGlyphOrder(self.glyphOrder)