def setupTable_OS2(self):
        """
        Make the OS/2 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["OS/2"] = os2 = newTable("OS/2")
        font = self.ufo
        os2.version = 0x0004
        # average glyph width
        widths = [
            glyph.width for glyph in self.allGlyphs.values() if glyph.width > 0
        ]
        os2.xAvgCharWidth = _roundInt(sum(widths) / len(widths))
        # weight and width classes
        os2.usWeightClass = getAttrWithFallback(font.info,
                                                "openTypeOS2WeightClass")
        os2.usWidthClass = getAttrWithFallback(font.info,
                                               "openTypeOS2WidthClass")
        # embedding
        os2.fsType = intListToNum(
            getAttrWithFallback(font.info, "openTypeOS2Type"), 0, 16)

        # subscript, superscript, strikeout values, taken from AFDKO:
        # FDK/Tools/Programs/makeotf/makeotf_lib/source/hotconv/hot.c
        unitsPerEm = getAttrWithFallback(font.info, "unitsPerEm")
        italicAngle = getAttrWithFallback(font.info, "italicAngle")
        xHeight = getAttrWithFallback(font.info, "xHeight")

        def adjustOffset(offset, angle):
            """Adjust Y offset based on italic angle, to get X offset."""
            return offset * math.tan(math.radians(-angle)) if angle else 0

        v = getAttrWithFallback(font.info, "openTypeOS2SubscriptXSize")
        if v is None:
            v = unitsPerEm * 0.65
        os2.ySubscriptXSize = _roundInt(v)
        v = getAttrWithFallback(font.info, "openTypeOS2SubscriptYSize")
        if v is None:
            v = unitsPerEm * 0.6
        os2.ySubscriptYSize = _roundInt(v)
        v = getAttrWithFallback(font.info, "openTypeOS2SubscriptYOffset")
        if v is None:
            v = unitsPerEm * 0.075
        os2.ySubscriptYOffset = _roundInt(v)
        v = getAttrWithFallback(font.info, "openTypeOS2SubscriptXOffset")
        if v is None:
            v = adjustOffset(-os2.ySubscriptYOffset, italicAngle)
        os2.ySubscriptXOffset = _roundInt(v)

        v = getAttrWithFallback(font.info, "openTypeOS2SuperscriptXSize")
        if v is None:
            v = os2.ySubscriptXSize
        os2.ySuperscriptXSize = _roundInt(v)
        v = getAttrWithFallback(font.info, "openTypeOS2SuperscriptYSize")
        if v is None:
            v = os2.ySubscriptYSize
        os2.ySuperscriptYSize = _roundInt(v)
        v = getAttrWithFallback(font.info, "openTypeOS2SuperscriptYOffset")
        if v is None:
            v = unitsPerEm * 0.35
        os2.ySuperscriptYOffset = _roundInt(v)
        v = getAttrWithFallback(font.info, "openTypeOS2SuperscriptXOffset")
        if v is None:
            v = adjustOffset(os2.ySuperscriptYOffset, italicAngle)
        os2.ySuperscriptXOffset = _roundInt(v)

        v = getAttrWithFallback(font.info, "openTypeOS2StrikeoutSize")
        if v is None:
            v = getAttrWithFallback(font.info, "postscriptUnderlineThickness")
        os2.yStrikeoutSize = _roundInt(v)
        v = getAttrWithFallback(font.info, "openTypeOS2StrikeoutPosition")
        if v is None:
            v = xHeight * 0.6 if xHeight else unitsPerEm * 0.22
        os2.yStrikeoutPosition = _roundInt(v)

        # family class
        ibmFontClass, ibmFontSubclass = getAttrWithFallback(
            font.info, "openTypeOS2FamilyClass")
        os2.sFamilyClass = (ibmFontClass << 8) + ibmFontSubclass
        # panose
        data = getAttrWithFallback(font.info, "openTypeOS2Panose")
        panose = Panose()
        panose.bFamilyType = data[0]
        panose.bSerifStyle = data[1]
        panose.bWeight = data[2]
        panose.bProportion = data[3]
        panose.bContrast = data[4]
        panose.bStrokeVariation = data[5]
        panose.bArmStyle = data[6]
        panose.bLetterForm = data[7]
        panose.bMidline = data[8]
        panose.bXHeight = data[9]
        os2.panose = panose
        # Unicode ranges
        uniRanges = getAttrWithFallback(font.info, "openTypeOS2UnicodeRanges")
        os2.ulUnicodeRange1 = intListToNum(uniRanges, 0, 32)
        os2.ulUnicodeRange2 = intListToNum(uniRanges, 32, 32)
        os2.ulUnicodeRange3 = intListToNum(uniRanges, 64, 32)
        os2.ulUnicodeRange4 = intListToNum(uniRanges, 96, 32)
        # codepage ranges
        codepageRanges = getAttrWithFallback(font.info,
                                             "openTypeOS2CodePageRanges")
        os2.ulCodePageRange1 = intListToNum(codepageRanges, 0, 32)
        os2.ulCodePageRange2 = intListToNum(codepageRanges, 32, 32)
        # vendor id
        os2.achVendID = tounicode(getAttrWithFallback(font.info,
                                                      "openTypeOS2VendorID"),
                                  encoding="ascii",
                                  errors="ignore")
        # vertical metrics
        os2.sxHeight = _roundInt(getAttrWithFallback(font.info, "xHeight"))
        os2.sCapHeight = _roundInt(getAttrWithFallback(font.info, "capHeight"))
        os2.sTypoAscender = _roundInt(
            getAttrWithFallback(font.info, "openTypeOS2TypoAscender"))
        os2.sTypoDescender = _roundInt(
            getAttrWithFallback(font.info, "openTypeOS2TypoDescender"))
        os2.sTypoLineGap = _roundInt(
            getAttrWithFallback(font.info, "openTypeOS2TypoLineGap"))
        os2.usWinAscent = _roundInt(
            getAttrWithFallback(font.info, "openTypeOS2WinAscent"))
        os2.usWinDescent = _roundInt(
            getAttrWithFallback(font.info, "openTypeOS2WinDescent"))
        # style mapping
        selection = list(getAttrWithFallback(font.info,
                                             "openTypeOS2Selection"))
        styleMapStyleName = getAttrWithFallback(font.info, "styleMapStyleName")
        if styleMapStyleName == "regular":
            selection.append(6)
        elif styleMapStyleName == "bold":
            selection.append(5)
        elif styleMapStyleName == "italic":
            selection.append(0)
        elif styleMapStyleName == "bold italic":
            selection += [0, 5]
        os2.fsSelection = intListToNum(selection, 0, 16)
        # characetr indexes
        unicodes = [
            i for i in self.unicodeToGlyphNameMapping.keys() if i is not None
        ]
        if unicodes:
            minIndex = min(unicodes)
            maxIndex = max(unicodes)
        else:
            # the font may have *no* unicode values (it really happens!) so
            # there needs to be a fallback. use 0xFFFF, as AFDKO does:
            # FDK/Tools/Programs/makeotf/makeotf_lib/source/hotconv/map.c
            minIndex = 0xFFFF
            maxIndex = 0xFFFF
        if maxIndex > 0xFFFF:
            # the spec says that 0xFFFF should be used
            # as the max if the max exceeds 0xFFFF
            maxIndex = 0xFFFF
        os2.fsFirstCharIndex = minIndex
        os2.fsLastCharIndex = maxIndex
        os2.usBreakChar = 32
        os2.usDefaultChar = 0
        # maximum contextual lookup length
        os2.usMaxContex = 0
Exemplo n.º 2
0
    def setupTable_OS2(self):
        """
        Make the OS/2 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["OS/2"] = os2 = newTable("OS/2")
        font = self.ufo
        os2.version = 0x0004
        # average glyph width
        widths = [glyph.width for glyph in self.allGlyphs.values() if glyph.width > 0]
        os2.xAvgCharWidth = _roundInt(sum(widths) / len(widths))
        # weight and width classes
        os2.usWeightClass = getAttrWithFallback(font.info, "openTypeOS2WeightClass")
        os2.usWidthClass = getAttrWithFallback(font.info, "openTypeOS2WidthClass")
        # embedding
        os2.fsType = intListToNum(getAttrWithFallback(font.info, "openTypeOS2Type"), 0, 16)
        # subscript
        v = getAttrWithFallback(font.info, "openTypeOS2SubscriptXSize")
        if v is None:
            v = 0
        os2.ySubscriptXSize = _roundInt(v)
        v = getAttrWithFallback(font.info, "openTypeOS2SubscriptYSize")
        if v is None:
            v = 0
        os2.ySubscriptYSize = _roundInt(v)
        v = getAttrWithFallback(font.info, "openTypeOS2SubscriptXOffset")
        if v is None:
            v = 0
        os2.ySubscriptXOffset = _roundInt(v)
        v = getAttrWithFallback(font.info, "openTypeOS2SubscriptYOffset")
        if v is None:
            v = 0
        os2.ySubscriptYOffset = _roundInt(v)
        # superscript
        v = getAttrWithFallback(font.info, "openTypeOS2SuperscriptXSize")
        if v is None:
            v = 0
        os2.ySuperscriptXSize = _roundInt(v)
        v = getAttrWithFallback(font.info, "openTypeOS2SuperscriptYSize")
        if v is None:
            v = 0
        os2.ySuperscriptYSize = _roundInt(v)
        v = getAttrWithFallback(font.info, "openTypeOS2SuperscriptXOffset")
        if v is None:
            v = 0
        os2.ySuperscriptXOffset = _roundInt(v)
        v = getAttrWithFallback(font.info, "openTypeOS2SuperscriptYOffset")
        if v is None:
            v = 0
        os2.ySuperscriptYOffset = _roundInt(v)
        # strikeout
        v = getAttrWithFallback(font.info, "openTypeOS2StrikeoutSize")
        if v is None:
            v = 0
        os2.yStrikeoutSize = _roundInt(v)
        v = getAttrWithFallback(font.info, "openTypeOS2StrikeoutPosition")
        if v is None:
            v = 0
        os2.yStrikeoutPosition = _roundInt(v)
        # family class
        ibmFontClass, ibmFontSubclass = getAttrWithFallback(
            font.info, "openTypeOS2FamilyClass")
        os2.sFamilyClass = (ibmFontClass << 8) + ibmFontSubclass
        # panose
        data = getAttrWithFallback(font.info, "openTypeOS2Panose")
        panose = Panose()
        panose.bFamilyType = data[0]
        panose.bSerifStyle = data[1]
        panose.bWeight = data[2]
        panose.bProportion = data[3]
        panose.bContrast = data[4]
        panose.bStrokeVariation = data[5]
        panose.bArmStyle = data[6]
        panose.bLetterForm = data[7]
        panose.bMidline = data[8]
        panose.bXHeight = data[9]
        os2.panose = panose
        # Unicode ranges
        uniRanges = getAttrWithFallback(font.info, "openTypeOS2UnicodeRanges")
        os2.ulUnicodeRange1 = intListToNum(uniRanges, 0, 32)
        os2.ulUnicodeRange2 = intListToNum(uniRanges, 32, 32)
        os2.ulUnicodeRange3 = intListToNum(uniRanges, 64, 32)
        os2.ulUnicodeRange4 = intListToNum(uniRanges, 96, 32)
        # codepage ranges
        codepageRanges = getAttrWithFallback(font.info, "openTypeOS2CodePageRanges")
        os2.ulCodePageRange1 = intListToNum(codepageRanges, 0, 32)
        os2.ulCodePageRange2 = intListToNum(codepageRanges, 32, 32)
        # vendor id
        os2.achVendID = tounicode(
            getAttrWithFallback(font.info, "openTypeOS2VendorID"),
            encoding="ascii", errors="ignore")
        # vertical metrics
        os2.sxHeight = _roundInt(getAttrWithFallback(font.info, "xHeight"))
        os2.sCapHeight = _roundInt(getAttrWithFallback(font.info, "capHeight"))
        os2.sTypoAscender = _roundInt(getAttrWithFallback(font.info, "openTypeOS2TypoAscender"))
        os2.sTypoDescender = _roundInt(getAttrWithFallback(font.info, "openTypeOS2TypoDescender"))
        os2.sTypoLineGap = _roundInt(getAttrWithFallback(font.info, "openTypeOS2TypoLineGap"))
        os2.usWinAscent = _roundInt(getAttrWithFallback(font.info, "openTypeOS2WinAscent"))
        os2.usWinDescent = _roundInt(getAttrWithFallback(font.info, "openTypeOS2WinDescent"))
        # style mapping
        selection = list(getAttrWithFallback(font.info, "openTypeOS2Selection"))
        styleMapStyleName = getAttrWithFallback(font.info, "styleMapStyleName")
        if styleMapStyleName == "regular":
            selection.append(6)
        elif styleMapStyleName == "bold":
            selection.append(5)
        elif styleMapStyleName == "italic":
            selection.append(0)
        elif styleMapStyleName == "bold italic":
            selection += [0, 5]
        os2.fsSelection = intListToNum(selection, 0, 16)
        # characetr indexes
        unicodes = [i for i in self.unicodeToGlyphNameMapping.keys() if i is not None]
        if unicodes:
            minIndex = min(unicodes)
            maxIndex = max(unicodes)
        else:
            # the font may have *no* unicode values
            # (it really happens!) so there needs
            # to be a fallback. use space for this.
            minIndex = 0x0020
            maxIndex = 0x0020
        if maxIndex > 0xFFFF:
            # the spec says that 0xFFFF should be used
            # as the max if the max exceeds 0xFFFF
            maxIndex = 0xFFFF
        os2.fsFirstCharIndex = minIndex
        os2.fsLastCharIndex = maxIndex
        os2.usBreakChar = 32
        os2.usDefaultChar = 0
        # maximum contextual lookup length
        os2.usMaxContex = 0
Exemplo n.º 3
0
def makeTable_OS2(ttf, pixelSize, descentPixels, minUnicode, maxUnicode):
    size = 8 * pixelSize
    descent = pixelSize * descentPixels

    os_2 = newTable("OS/2")
    
    os_2.version = 4
    os_2.xAvgCharWidth = size
    os_2.usWeightClass = 400      # Meaning "Normal (Regular)"
    os_2.usWidthClass = 5         # Meaing "Medium (normal)"
    os_2.fsType = 0               # Windows-only licensing bits...
    os_2.ySubscriptXSize = size
    os_2.ySubscriptYSize = size / 2
    os_2.ySubscriptXOffset = 0
    os_2.ySubscriptYOffset = descent
    os_2.ySuperscriptXSize = size / 2
    os_2.ySuperscriptYSize = size / 2
    os_2.ySuperscriptXOffset = 0
    os_2.ySuperscriptYOffset = size / 2
    os_2.yStrikeoutSize = pixelSize
    os_2.yStrikeoutPosition = size / 2 - descent
    os_2.sFamilyClass = 0x080a    # Class ID = 8 (Sans Serif), Subclass ID = 10 (Matrix)
    panose = Panose()
    panose.bFamilyType = 2        # Text and Display
    panose.bSerifStyle = 1        # No Fit
    panose.bWeight = 6            # Medium
    panose.bProportion = 9        # Monospaced
    panose.bContrast = 6          # Medium
    panose.bStrokeVariation = 2   # Gradual/Diagonal
    panose.bArmStyle = 2          # Straight Arms/Horizontal
    panose.bLetterForm = 8        # Normal/Square
    panose.bMidline = 1           # No Fit
    panose.bXHeight = 1           # No Fit
    os_2.panose = panose
    os_2.ulUnicodeRange1 = 0b10000000000000000000000010000011 # Basic Latin + Latin-1 supplement + Greek and Coptic + General punctuation
    os_2.ulUnicodeRange2 = 0b00010000000000001111100001100000 # Arrows + Mathematical operators + Box drawing + Block elements + Geometric shapes + Misc. symbols + Dingbats + Private use area
    os_2.ulUnicodeRange3 = 0b00000000000000000000000000000000 # n/a
    os_2.ulUnicodeRange4 = 0b00000000000000000000000000000000 # n/a
    os_2.achVendID = "C=64"       # :-)
    os_2.fsSelection = 64         # Regular
    os_2.fsFirstCharIndex = minUnicode
    os_2.fsLastCharIndex = maxUnicode
    os_2.sTypoAscender = size - descent
    os_2.sTypoDescender = 0 - descent
    os_2.sTypoLineGap = 0
    os_2.usWinAscent = size - descent
    os_2.usWinDescent = descent
    os_2.ulCodePageRange1 = 0b00000000000000000000000000000001 # Latin 1 (Code page 1252)
    os_2.ulCodePageRange2 = 0b11000000000000000000000000000000 # WE/Latin 1 (Code page 850) + US (Code page 437)
    os_2.sxHeight = 6 * pixelSize - descent                    # Guess (we don't always have a lower-case "x" at 0x78 to measure (as the standard suggests))
    os_2.sCapHeight = size - descent
    os_2.usDefaultChar = 0
    os_2.usBreakChar = 32
    os_2.usMaxContex = 0

    ttf["OS/2"] = os_2
Exemplo n.º 4
0
    def build_OS2(self):
        ctx = self.ctx
        data = self.metadataProvider
        self.otf["OS/2"] = os2 = ttLib.newTable("OS/2")
        os2.version = 0x0004
        os2.xAvgCharWidth = FontProc.average_char_width(ctx, self.otf)

        os2.usWeightClass = data.OS2_weightClass(ctx)
        os2.usWidthClass = data.OS2_widthClass(ctx)

        os2.fsType = data.OS2_fsType(ctx)

        os2.ySubscriptXSize = otRound(data.OS2_subscriptXSize(ctx))
        os2.ySubscriptYSize = otRound(data.OS2_subscriptYSize(ctx))
        os2.ySubscriptXOffset = otRound(data.OS2_subscriptXOffset(ctx))
        os2.ySubscriptYOffset = otRound(data.OS2_subscriptYOffset(ctx))

        os2.ySuperscriptXSize = otRound(data.OS2_superscriptXSize(ctx))
        os2.ySuperscriptYSize = otRound(data.OS2_superscriptYSize(ctx))
        os2.ySuperscriptXOffset = otRound(data.OS2_superscriptXOffset(ctx))
        os2.ySuperscriptYOffset = otRound(data.OS2_superscriptYOffset(ctx))

        os2.yStrikeoutSize = otRound(data.OS2_strikeoutSize(ctx))
        os2.yStrikeoutPosition = otRound(data.OS2_strikeoutPosition(ctx))

        os2.sFamilyClass = data.OS2_familyClass(ctx)

        panose = Panose()
        panose.bFamilyType, \
        panose.bSerifStyle, \
        panose.bWeight, \
        panose.bProportion, \
        panose.bContrast, \
        panose.bStrokeVariation, \
        panose.bArmStyle, \
        panose.bLetterForm, \
        panose.bMidline, \
        panose.bXHeight = data.OS2_panose(ctx)
        os2.panose = panose

        unicodeRanges = data.OS2_unicodeRanges(ctx)
        if unicodeRanges is not None:
            os2.ulUnicodeRange1 = conversion.to_bitflags(unicodeRanges, 0, 32)
            os2.ulUnicodeRange2 = conversion.to_bitflags(unicodeRanges, 32, 32)
            os2.ulUnicodeRange3 = conversion.to_bitflags(unicodeRanges, 64, 32)
            os2.ulUnicodeRange4 = conversion.to_bitflags(unicodeRanges, 96, 32)
        else:
            os2.recalcUnicodeRanges(self.otf)

        codepageRanges = data.OS2_codepageRanges(ctx)
        if codepageRanges is None:
            codepageRanges = FontProc.codepage_ranges(
                ctx, self.unicodeToGlyphNameMap.keys())
        os2.ulCodePageRange1 = conversion.to_bitflags(codepageRanges, 0, 32)
        os2.ulCodePageRange2 = conversion.to_bitflags(codepageRanges, 32, 32)

        os2.achVendID = data.OS2_vendorID(ctx)

        os2.sxHeight = otRound(data.xHeight(ctx))
        os2.sCapHeight = otRound(data.capHeight(ctx))
        os2.sTypoAscender, \
        os2.sTypoDescender, \
        os2.sTypoLineGap = otRoundSequence(data.OS2_typoMetrics(ctx))
        os2.usWinAscent, \
        os2.usWinDescent = otRoundSequence(data.OS2_winMetrics(ctx, self.fontBounds))

        os2.fsSelection = data.OS2_fsSelection(ctx)

        os2.fsFirstCharIndex, \
        os2.fsLastCharIndex = FontProc.minmax_cids(ctx, self.unicodeToGlyphNameMap.keys())
        os2.usBreakChar = 32
        os2.usDefaultChar = 0
        # maximum contextual lookup length
        os2.usMaxContext = 0
Exemplo n.º 5
0
    def setupTable_OS2(self):
        """
        Make the OS/2 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["OS/2"] = os2 = newTable("OS/2")
        font = self.ufo
        os2.version = 0x0004
        # average glyph width
        widths = [
            glyph.width for glyph in self.allGlyphs.values() if glyph.width > 0
        ]
        os2.xAvgCharWidth = _roundInt(sum(widths) / len(widths))
        # weight and width classes
        os2.usWeightClass = getAttrWithFallback(font.info,
                                                "openTypeOS2WeightClass")
        os2.usWidthClass = getAttrWithFallback(font.info,
                                               "openTypeOS2WidthClass")
        # embedding
        os2.fsType = intListToNum(
            getAttrWithFallback(font.info, "openTypeOS2Type"), 0, 16)
        # subscript
        v = getAttrWithFallback(font.info, "openTypeOS2SubscriptXSize")
        if v is None:
            v = 0
        os2.ySubscriptXSize = _roundInt(v)
        v = getAttrWithFallback(font.info, "openTypeOS2SubscriptYSize")
        if v is None:
            v = 0
        os2.ySubscriptYSize = _roundInt(v)
        v = getAttrWithFallback(font.info, "openTypeOS2SubscriptXOffset")
        if v is None:
            v = 0
        os2.ySubscriptXOffset = _roundInt(v)
        v = getAttrWithFallback(font.info, "openTypeOS2SubscriptYOffset")
        if v is None:
            v = 0
        os2.ySubscriptYOffset = _roundInt(v)
        # superscript
        v = getAttrWithFallback(font.info, "openTypeOS2SuperscriptXSize")
        if v is None:
            v = 0
        os2.ySuperscriptXSize = _roundInt(v)
        v = getAttrWithFallback(font.info, "openTypeOS2SuperscriptYSize")
        if v is None:
            v = 0
        os2.ySuperscriptYSize = _roundInt(v)
        v = getAttrWithFallback(font.info, "openTypeOS2SuperscriptXOffset")
        if v is None:
            v = 0
        os2.ySuperscriptXOffset = _roundInt(v)
        v = getAttrWithFallback(font.info, "openTypeOS2SuperscriptYOffset")
        if v is None:
            v = 0
        os2.ySuperscriptYOffset = _roundInt(v)
        # strikeout
        v = getAttrWithFallback(font.info, "openTypeOS2StrikeoutSize")
        if v is None:
            v = 0
        os2.yStrikeoutSize = _roundInt(v)
        v = getAttrWithFallback(font.info, "openTypeOS2StrikeoutPosition")
        if v is None:
            v = 0
        os2.yStrikeoutPosition = _roundInt(v)
        # family class
        os2.sFamilyClass = 0  # XXX not sure how to create the appropriate value
        # panose
        data = getAttrWithFallback(font.info, "openTypeOS2Panose")
        panose = Panose()
        panose.bFamilyType = data[0]
        panose.bSerifStyle = data[1]
        panose.bWeight = data[2]
        panose.bProportion = data[3]
        panose.bContrast = data[4]
        panose.bStrokeVariation = data[5]
        panose.bArmStyle = data[6]
        panose.bLetterForm = data[7]
        panose.bMidline = data[8]
        panose.bXHeight = data[9]
        os2.panose = panose
        # Unicode ranges
        uniRanges = getAttrWithFallback(font.info, "openTypeOS2UnicodeRanges")
        os2.ulUnicodeRange1 = intListToNum(uniRanges, 0, 32)
        os2.ulUnicodeRange2 = intListToNum(uniRanges, 32, 32)
        os2.ulUnicodeRange3 = intListToNum(uniRanges, 64, 32)
        os2.ulUnicodeRange4 = intListToNum(uniRanges, 96, 32)
        # codepage ranges
        codepageRanges = getAttrWithFallback(font.info,
                                             "openTypeOS2CodePageRanges")
        os2.ulCodePageRange1 = intListToNum(codepageRanges, 0, 32)
        os2.ulCodePageRange2 = intListToNum(codepageRanges, 32, 32)
        # vendor id
        os2.achVendID = str(
            getAttrWithFallback(font.info, "openTypeOS2VendorID").decode(
                "ascii", "ignore"))
        # vertical metrics
        os2.sxHeight = _roundInt(getAttrWithFallback(font.info, "xHeight"))
        os2.sCapHeight = _roundInt(getAttrWithFallback(font.info, "capHeight"))
        os2.sTypoAscender = _roundInt(
            getAttrWithFallback(font.info, "openTypeOS2TypoAscender"))
        os2.sTypoDescender = _roundInt(
            getAttrWithFallback(font.info, "openTypeOS2TypoDescender"))
        os2.sTypoLineGap = _roundInt(
            getAttrWithFallback(font.info, "openTypeOS2TypoLineGap"))
        os2.usWinAscent = _roundInt(
            getAttrWithFallback(font.info, "openTypeOS2WinAscent"))
        os2.usWinDescent = _roundInt(
            getAttrWithFallback(font.info, "openTypeOS2WinDescent"))
        # style mapping
        selection = list(getAttrWithFallback(font.info,
                                             "openTypeOS2Selection"))
        styleMapStyleName = getAttrWithFallback(font.info, "styleMapStyleName")
        if styleMapStyleName == "regular":
            selection.append(6)
        elif styleMapStyleName == "bold":
            selection.append(5)
        elif styleMapStyleName == "italic":
            selection.append(0)
        elif styleMapStyleName == "bold italic":
            selection += [0, 5]
        os2.fsSelection = intListToNum(selection, 0, 16)
        # characetr indexes
        unicodes = [
            i for i in self.unicodeToGlyphNameMapping.keys() if i is not None
        ]
        if unicodes:
            minIndex = min(unicodes)
            maxIndex = max(unicodes)
        else:
            # the font may have *no* unicode values
            # (it really happens!) so there needs
            # to be a fallback. use space for this.
            minIndex = 0x0020
            maxIndex = 0x0020
        if maxIndex > 0xFFFF:
            # the spec says that 0xFFFF should be used
            # as the max if the max exceeds 0xFFFF
            maxIndex = 0xFFFF
        os2.fsFirstCharIndex = minIndex
        os2.fsLastCharIndex = maxIndex
        os2.usBreakChar = 32
        os2.usDefaultChar = 0
        # maximum contextual lookup length
        os2.usMaxContex = 0