示例#1
0
    def setupTable_CFF(self):
        """Make the CFF table."""

        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("\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("\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
            if glyphName in charStrings:
                # 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."""

        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("\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("\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 = psName
        # populate various numbers
        topDict.isFixedPitch = getAttrWithFallback(info,
                                                   "postscriptIsFixedPitch")
        topDict.ItalicAngle = getAttrWithFallback(info, "italicAngle")
        underlinePosition = getAttrWithFallback(info,
                                                "postscriptUnderlinePosition")
        topDict.UnderlinePosition = _roundInt(underlinePosition)
        underlineThickness = getAttrWithFallback(
            info, "postscriptUnderlineThickness")
        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
            if glyphName in charStrings:
                # 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)
示例#3
0
    def build_CFF(self):
        ctx = self.ctx
        data = self.metadataProvider
        self.otf["CFF "] = cff = ttLib.newTable("CFF ")
        cff = cff.cff

        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

        cff.fontNames.append(data.name_postscriptFontName(ctx))
        topDict = cff.topDictIndex[0]
        topDict.version = data.version(ctx)
        topDict.Notice = conversion.to_postscript_string(
            data.name_trademark(ctx), lambda result: ctx.log.append(
                semlog.warning_attr_truncated(attr="trademark", result=result))
        )
        topDict.Copyright = conversion.to_postscript_string(
            data.copyright(ctx), lambda result: ctx.log.append(
                semlog.warning_attr_truncated(attr="copyright", result=result))
        )
        topDict.FullName = data.name_postscriptFullName(ctx)
        topDict.FamilyName = data.CFF_postscriptFamilyName(ctx)
        topDict.Weight = data.CFF_postscriptWeightName(ctx)

        topDict.isFixedPitch = data.post_isFixedPitch(ctx)
        topDict.ItalicAngle = data.italicAngle(ctx)
        topDict.UnderlinePosition = otRound(data.post_underlinePosition(ctx))
        topDict.UnderlineThickness = otRound(data.post_underlineThickness(ctx))

        scale = 1.0 / otRound(data.unitsPerEm(ctx))
        topDict.FontMatrix = [scale, 0, 0, scale, 0, 0]

        defaultWidthX, nominalWidthX = FontProc.postscript_width_stats(
            ctx, self.otf)
        if defaultWidthX:
            private.rawDict["defaultWidthX"] = defaultWidthX
        if nominalWidthX:
            private.rawDict["nominalWidthX"] = nominalWidthX

        blueFuzz = otRound(data.CFF_postscriptBlueFuzz(ctx))
        blueShift = otRound(data.CFF_postscriptBlueShift(ctx))
        blueScale = data.CFF_postscriptBlueScale(ctx)
        forceBold = data.CFF_postscriptForceBold(ctx)
        blueValues = otRoundSequence(data.CFF_postscriptBlueValues(ctx))
        otherBlues = otRoundSequence(data.CFF_postscriptOtherBlues(ctx))
        familyBlues = otRoundSequence(data.CFF_postscriptFamilyBlues(ctx))
        familyOtherBlues = otRoundSequence(
            data.CFF_postscriptFamilyOtherBlues(ctx))
        stemSnapH = otRoundSequence(data.CFF_postscriptStemSnapH(ctx))
        stemSnapV = otRoundSequence(data.CFF_postscriptStemSnapV(ctx))
        # only write the blues data if some blues are defined.
        if any((blueValues, otherBlues, familyBlues, familyOtherBlues)):
            private.rawDict["BlueFuzz"] = blueFuzz
            private.rawDict["BlueShift"] = blueShift
            private.rawDict["BlueScale"] = blueScale
            private.rawDict["ForceBold"] = forceBold
            if blueValues:
                private.rawDict["BlueValues"] = blueValues
            if otherBlues:
                private.rawDict["OtherBlues"] = otherBlues
            if familyBlues:
                private.rawDict["FamilyBlues"] = familyBlues
            if familyOtherBlues:
                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.glyphMap[glyphName]
            charString = self.draw_charstring(glyph, private, globalSubrs)

            # add to the font
            charStringsIndex.append(charString)
            glyphID = len(topDict.charset)
            charStrings.charStrings[glyphName] = glyphID
            topDict.charset.append(glyphName)
        bounds = self.fontBounds
        topDict.FontBBox = (bounds.left, bounds.bottom, bounds.right,
                            bounds.top)