【问题标题】:Misaligned table error with OpenType fontOpenType 字体未对齐的表格错误
【发布时间】:2019-06-10 21:41:06
【问题描述】:

关于构建 OpenType 字体的这 3 个规范属性,我遇到了一个错误:

  • 搜索范围
  • rangeShift
  • entrySelector

this 页面上,它提到了它的工作原理:

  • searchRange 是小于等于表中项目数的 2 的最大幂,即可以轻松搜索到的最大项目数。
  • rangeShift 是项目数减去 searchRange;即仅查看 searchRange 项时不会查看的项数。
  • entrySelector 是 log2(searchRange)。

鉴于这些信息,我们有:

  • searchRange = maxPowerOf2 <= n,其中n 是表中的项目数。
  • rangeShift = n - searchRange
  • entrySelector = log2(searchRange)

但后来我们读得更远了。

请注意,searchRange、entrySelector 和 rangeShift 都乘以 16,表示目录条目的大小。

所以现在我们有:

  • searchRange = 16 * maxPowerOf2 <= n,其中n 是表中的项目数。
  • rangeShift = 16 * n - searchRange
  • entrySelector = 16 * log2(searchRange)

等等,下表显示了这一点:

  • 搜索范围(maximum power of 2 <= numTables)*16
  • entrySelectorlog2(maximum power of 2 <= numTables)
  • rangeShiftnumTables*16-searchRange

这意味着我们的 entrySelector 似乎没有 16 乘数:

  • searchRange = 16 * maxPowerOf2 <= n,其中n 是表中的项目数。
  • rangeShift = 16 * n - searchRange
  • entrySelector = log2(searchRange)

但是等等,there's more:

  • 搜索范围 (Maximum power of 2 <= numTables) x 16
  • entrySelector Log2(maximum power of 2 <= numTables)
  • rangeShift NumTables x 16-searchRange

这与我们的最后一个匹配。

检查一些任意的font source code,它也匹配最后一个。

我不明白的是唯一对我有用的是第一个:

let maxPowerOf2 = Math.pow(2, maxExponentFor2);
var searchRange = maxPowerOf2
var entrySelector = Math.log2(searchRange)
var rangeShift = numTables - searchRange

这是唯一让我克服错误的方法:

OTS parsing error: incorrect entrySelector for table directory

但后来我遇到了这个错误:

OTS parsing error: CFF : misaligned table

鉴于此输出:

4f54 544f 0009 0008 0003 0001 4346 4620
0000 0000 0000 00c2 9c00 0000 0563 6d61
7000 0000 0000 0000 c2a4 0000 0024 6865
6164 0000 0000 0000 00c3 8800 0000 3668
6865 6100 0000 0000 0001 0000 0000 2468
6d74 7800 0000 0000 0001 2400 0000 006d
6178 7000 0000 0000 0001 2400 0000 066e
616d 6500 0000 0000 0001 2c00 0000 064f
532f 3200 0000 0000 0001 3400 0000 6470
6f73 7400 0000 0000 0001 c298 0000 0020
0200 0400 0000 0000 0000 0001 0000 0006
0000 0010 0004 0010 0000 0002 0002 0000
0000 c3bf c3bf 0000 c3bf c3bf 0001 0000
0001 0000 0001 0000 0000 0000 5f0f 3cc3
b500 0303 c3a8 0000 0000 c398 6526 c388
0000 0000 c398 6526 c388 0000 0000 0000
0000 0000 0003 0002 0000 0000 0000 0001
0000 00c3 8800 6400 0000 0000 0000 0000
0000 0100 0000 0000 0000 0000 0000 0000
0000 0000 0050 0000 0000 0000 0000 0000
0600 0000 0500 0000 0000 0000 0002 c28a
02c2 bb00 0000 c28c 02c2 8a02 c2bb 0000
01c3 9f00 3101 0200 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0058 5858 5800 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0300
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 00

尝试大多数人这样做的方式(两个文档引用和源代码),但这给了我第一个错误,是这样的:

4f54 544f 0009 00c2 8000 0700 1043 4646
2000 0000 0000 0000 c29c 0000 0005 636d
6170 0000 0000 0000 00c2 a400 0000 2468
6561 6400 0000 0000 0000 c388 0000 0036
6868 6561 0000 0000 0000 0100 0000 0024
686d 7478 0000 0000 0000 0124 0000 0000
6d61 7870 0000 0000 0000 0124 0000 0006
6e61 6d65 0000 0000 0000 012c 0000 0006
4f53 2f32 0000 0000 0000 0134 0000 0064
706f 7374 0000 0000 0000 01c2 9800 0000
2002 0004 0000 0000 0000 0000 0100 0000
0600 0000 1000 0400 1000 0000 0200 0200
0000 00c3 bfc3 bf00 00c3 bfc3 bf00 0100
0000 0100 0000 0100 0000 0000 005f 0f3c
c3b5 0003 03c3 a800 0000 00c3 9865 271d
0000 0000 c398 6527 1d00 0000 0000 0000
0000 0000 0300 0200 0000 0000 0000 0100
0000 c388 0064 0000 0000 0000 0000 0000
0001 0000 0000 0000 0000 0000 0000 0000
0000 0000 5000 0000 0000 0000 0000 0006
0000 0005 0000 0000 0000 0000 02c2 8a02
c2bb 0000 00c2 8c02 c28a 02c2 bb00 0001
c39f 0031 0102 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 5858 5858 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0003 0000
0000 0000 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 

目前还没有字形,只有最低限度。想知道我缺少什么才能让这个工作。

如果这有帮助的话,这是生成二进制文件的基本数据:

{
  "name": "sfnt",
  "fields": {
    "scalar": {
      "type": "TAG",
      "value": "OTTO"
    },
    "numTables": {
      "type": "USHORT",
      "value": 9
    },
    "searchRange": {
      "type": "USHORT",
      "value": 128
    },
    "entrySelector": {
      "type": "USHORT",
      "value": 7
    },
    "rangeShift": {
      "type": "USHORT",
      "value": 16
    },
    "CFF  Table Record": {
      "type": "RECORD",
      "value": {
        "name": "Table Record",
        "fields": {
          "tag": {
            "type": "TAG",
            "value": "CFF "
          },
          "checkSum": {
            "type": "ULONG",
            "value": 0
          },
          "offset": {
            "type": "ULONG",
            "value": 156
          },
          "length": {
            "type": "ULONG",
            "value": 5
          }
        }
      }
    },
    "cmap Table Record": {
      "type": "RECORD",
      "value": {
        "name": "Table Record",
        "fields": {
          "tag": {
            "type": "TAG",
            "value": "cmap"
          },
          "checkSum": {
            "type": "ULONG",
            "value": 0
          },
          "offset": {
            "type": "ULONG",
            "value": 164
          },
          "length": {
            "type": "ULONG",
            "value": 36
          }
        }
      }
    },
    "head Table Record": {
      "type": "RECORD",
      "value": {
        "name": "Table Record",
        "fields": {
          "tag": {
            "type": "TAG",
            "value": "head"
          },
          "checkSum": {
            "type": "ULONG",
            "value": 0
          },
          "offset": {
            "type": "ULONG",
            "value": 200
          },
          "length": {
            "type": "ULONG",
            "value": 54
          }
        }
      }
    },
    "hhea Table Record": {
      "type": "RECORD",
      "value": {
        "name": "Table Record",
        "fields": {
          "tag": {
            "type": "TAG",
            "value": "hhea"
          },
          "checkSum": {
            "type": "ULONG",
            "value": 0
          },
          "offset": {
            "type": "ULONG",
            "value": 256
          },
          "length": {
            "type": "ULONG",
            "value": 36
          }
        }
      }
    },
    "hmtx Table Record": {
      "type": "RECORD",
      "value": {
        "name": "Table Record",
        "fields": {
          "tag": {
            "type": "TAG",
            "value": "hmtx"
          },
          "checkSum": {
            "type": "ULONG",
            "value": 0
          },
          "offset": {
            "type": "ULONG",
            "value": 292
          },
          "length": {
            "type": "ULONG",
            "value": 0
          }
        }
      }
    },
    "maxp Table Record": {
      "type": "RECORD",
      "value": {
        "name": "Table Record",
        "fields": {
          "tag": {
            "type": "TAG",
            "value": "maxp"
          },
          "checkSum": {
            "type": "ULONG",
            "value": 0
          },
          "offset": {
            "type": "ULONG",
            "value": 292
          },
          "length": {
            "type": "ULONG",
            "value": 6
          }
        }
      }
    },
    "name Table Record": {
      "type": "RECORD",
      "value": {
        "name": "Table Record",
        "fields": {
          "tag": {
            "type": "TAG",
            "value": "name"
          },
          "checkSum": {
            "type": "ULONG",
            "value": 0
          },
          "offset": {
            "type": "ULONG",
            "value": 300
          },
          "length": {
            "type": "ULONG",
            "value": 6
          }
        }
      }
    },
    "OS/2 Table Record": {
      "type": "RECORD",
      "value": {
        "name": "Table Record",
        "fields": {
          "tag": {
            "type": "TAG",
            "value": "OS/2"
          },
          "checkSum": {
            "type": "ULONG",
            "value": 0
          },
          "offset": {
            "type": "ULONG",
            "value": 308
          },
          "length": {
            "type": "ULONG",
            "value": 100
          }
        }
      }
    },
    "post Table Record": {
      "type": "RECORD",
      "value": {
        "name": "Table Record",
        "fields": {
          "tag": {
            "type": "TAG",
            "value": "post"
          },
          "checkSum": {
            "type": "ULONG",
            "value": 0
          },
          "offset": {
            "type": "ULONG",
            "value": 408
          },
          "length": {
            "type": "ULONG",
            "value": 32
          }
        }
      }
    },
    "CFF  table": {
      "type": "RECORD",
      "value": {
        "name": "CFF ",
        "fields": {
          "header": {
            "type": "RECORD",
            "value": {
              "name": "Header",
              "fields": {
                "major": {
                  "type": "BYTE",
                  "value": 2
                },
                "minor": {
                  "type": "BYTE",
                  "value": 0
                },
                "hdrSize": {
                  "type": "BYTE",
                  "value": 4
                },
                "topDictLength": {
                  "type": "USHORT",
                  "value": 0
                }
              }
            }
          }
        }
      }
    },
    "padding_0": {
      "type": "BYTE",
      "value": 0
    },
    "padding_1": {
      "type": "BYTE",
      "value": 0
    },
    "padding_2": {
      "type": "BYTE",
      "value": 0
    },
    "cmap table": {
      "type": "RECORD",
      "value": {
        "name": "cmap",
        "fields": {
          "version": {
            "type": "USHORT",
            "value": 0
          },
          "numTables": {
            "type": "USHORT",
            "value": 1
          },
          "platformID": {
            "type": "USHORT",
            "value": 0
          },
          "encodingID": {
            "type": "USHORT",
            "value": 6
          },
          "offset": {
            "type": "ULONG",
            "value": 16
          },
          "format": {
            "type": "USHORT",
            "value": 4
          },
          "cmap4Length": {
            "type": "USHORT",
            "value": 16
          },
          "language": {
            "type": "USHORT",
            "value": 0
          },
          "segCountX2": {
            "type": "USHORT",
            "value": 2
          },
          "searchRange": {
            "type": "USHORT",
            "value": 2
          },
          "entrySelector": {
            "type": "USHORT",
            "value": 0
          },
          "rangeShift": {
            "type": "USHORT",
            "value": 0
          },
          "end_0": {
            "type": "USHORT",
            "value": 65535
          },
          "reservedPad": {
            "type": "USHORT",
            "value": 0
          },
          "start_0": {
            "type": "USHORT",
            "value": 65535
          },
          "idDelta_0": {
            "type": "SHORT",
            "value": 1
          },
          "idRangeOffset_0": {
            "type": "USHORT",
            "value": 0
          }
        }
      }
    },
    "head table": {
      "type": "RECORD",
      "value": {
        "name": "head",
        "fields": {
          "version": {
            "type": "FIXED",
            "value": 65536
          },
          "fontRevision": {
            "type": "FIXED",
            "value": 65536
          },
          "checkSumAdjustment": {
            "type": "ULONG",
            "value": 0
          },
          "magicNumber": {
            "type": "ULONG",
            "value": 1594834165
          },
          "flags": {
            "type": "USHORT",
            "value": 3
          },
          "unitsPerEm": {
            "type": "USHORT",
            "value": 1000
          },
          "created": {
            "type": "LONGDATETIME",
            "value": 3630507805
          },
          "modified": {
            "type": "LONGDATETIME",
            "value": 3630507805
          },
          "xMin": {
            "type": "SHORT",
            "value": null
          },
          "yMin": {
            "type": "SHORT",
            "value": null
          },
          "xMax": {
            "type": "SHORT",
            "value": null
          },
          "yMax": {
            "type": "SHORT",
            "value": null
          },
          "macStyle": {
            "type": "USHORT",
            "value": 0
          },
          "lowestRecPPEM": {
            "type": "USHORT",
            "value": 3
          },
          "fontDirectionHint": {
            "type": "SHORT",
            "value": 2
          },
          "indexToLocFormat": {
            "type": "SHORT",
            "value": 0
          },
          "glyphDataFormat": {
            "type": "SHORT",
            "value": 0
          }
        }
      }
    },
    "padding_3": {
      "type": "BYTE",
      "value": 0
    },
    "padding_4": {
      "type": "BYTE",
      "value": 0
    },
    "hhea table": {
      "type": "RECORD",
      "value": {
        "name": "hhea",
        "fields": {
          "version": {
            "type": "FIXED",
            "value": 65536
          },
          "ascender": {
            "type": "FWORD",
            "value": 200
          },
          "descender": {
            "type": "FWORD",
            "value": 100
          },
          "lineGap": {
            "type": "FWORD",
            "value": 0
          },
          "advanceWidthMax": {
            "type": "UFWORD",
            "value": null
          },
          "minLeftSideBearing": {
            "type": "FWORD",
            "value": null
          },
          "minRightSideBearing": {
            "type": "FWORD",
            "value": null
          },
          "xMaxExtent": {
            "type": "FWORD",
            "value": null
          },
          "caretSlopeRise": {
            "type": "SHORT",
            "value": 1
          },
          "caretSlopeRun": {
            "type": "SHORT",
            "value": 0
          },
          "caretOffset": {
            "type": "SHORT",
            "value": 0
          },
          "reserved1": {
            "type": "SHORT",
            "value": 0
          },
          "reserved2": {
            "type": "SHORT",
            "value": 0
          },
          "reserved3": {
            "type": "SHORT",
            "value": 0
          },
          "reserved4": {
            "type": "SHORT",
            "value": 0
          },
          "metricDataFormat": {
            "type": "SHORT",
            "value": 0
          },
          "numberOfHMetrics": {
            "type": "USHORT",
            "value": 0
          }
        }
      }
    },
    "hmtx table": {
      "type": "RECORD",
      "value": {
        "name": "hmtx",
        "fields": {}
      }
    },
    "maxp table": {
      "type": "RECORD",
      "value": {
        "name": "maxp",
        "fields": {
          "version": {
            "type": "FIXED",
            "value": 20480
          },
          "numGlyphs": {
            "type": "USHORT",
            "value": 0
          }
        }
      }
    },
    "padding_5": {
      "type": "BYTE",
      "value": 0
    },
    "padding_6": {
      "type": "BYTE",
      "value": 0
    },
    "name table": {
      "type": "RECORD",
      "value": {
        "name": "name",
        "fields": {
          "format": {
            "type": "USHORT",
            "value": 0
          },
          "count": {
            "type": "USHORT",
            "value": 0
          },
          "stringOffset": {
            "type": "USHORT",
            "value": 6
          },
          "strings": {
            "type": "LITERAL",
            "value": []
          }
        }
      }
    },
    "padding_7": {
      "type": "BYTE",
      "value": 0
    },
    "padding_8": {
      "type": "BYTE",
      "value": 0
    },
    "OS/2 table": {
      "type": "RECORD",
      "value": {
        "name": "OS/2",
        "fields": {
          "version": {
            "type": "USHORT",
            "value": 5
          },
          "xAvgCharWidth": {
            "type": "SHORT",
            "value": 0
          },
          "usWeightClass": {
            "type": "USHORT",
            "value": 0
          },
          "usWidthClass": {
            "type": "USHORT",
            "value": 0
          },
          "fsType": {
            "type": "USHORT",
            "value": 0
          },
          "ySubscriptXSize": {
            "type": "SHORT",
            "value": 650
          },
          "ySubscriptYSize": {
            "type": "SHORT",
            "value": 699
          },
          "ySubscriptXOffset": {
            "type": "SHORT",
            "value": 0
          },
          "ySubscriptYOffset": {
            "type": "SHORT",
            "value": 140
          },
          "ySuperscriptXSize": {
            "type": "SHORT",
            "value": 650
          },
          "ySuperscriptYSize": {
            "type": "SHORT",
            "value": 699
          },
          "ySuperscriptXOffset": {
            "type": "SHORT",
            "value": 0
          },
          "ySuperscriptYOffset": {
            "type": "SHORT",
            "value": 479
          },
          "yStrikeoutSize": {
            "type": "SHORT",
            "value": 49
          },
          "yStrikeoutPosition": {
            "type": "SHORT",
            "value": 258
          },
          "sFamilyClass": {
            "type": "SHORT",
            "value": 0
          },
          "bFamilyType": {
            "type": "BYTE",
            "value": 0
          },
          "bSerifStyle": {
            "type": "BYTE",
            "value": 0
          },
          "bWeight": {
            "type": "BYTE",
            "value": 0
          },
          "bProportion": {
            "type": "BYTE",
            "value": 0
          },
          "bContrast": {
            "type": "BYTE",
            "value": 0
          },
          "bStrokeVariation": {
            "type": "BYTE",
            "value": 0
          },
          "bArmStyle": {
            "type": "BYTE",
            "value": 0
          },
          "bLetterform": {
            "type": "BYTE",
            "value": 0
          },
          "bMidline": {
            "type": "BYTE",
            "value": 0
          },
          "bXHeight": {
            "type": "BYTE",
            "value": 0
          },
          "ulUnicodeRange1": {
            "type": "ULONG",
            "value": 0
          },
          "ulUnicodeRange2": {
            "type": "ULONG",
            "value": 0
          },
          "ulUnicodeRange3": {
            "type": "ULONG",
            "value": 0
          },
          "ulUnicodeRange4": {
            "type": "ULONG",
            "value": 0
          },
          "achVendID": {
            "type": "CHARARRAY",
            "value": "XXXX"
          },
          "fsSelection": {
            "type": "USHORT",
            "value": 0
          },
          "usFirstCharIndex": {
            "type": "USHORT",
            "value": 0
          },
          "usLastCharIndex": {
            "type": "USHORT",
            "value": 0
          },
          "sTypoAscender": {
            "type": "SHORT",
            "value": 0
          },
          "sTypoDescender": {
            "type": "SHORT",
            "value": 0
          },
          "sTypoLineGap": {
            "type": "SHORT",
            "value": 0
          },
          "usWinAscent": {
            "type": "USHORT",
            "value": 0
          },
          "usWinDescent": {
            "type": "USHORT",
            "value": 0
          },
          "ulCodePageRange1": {
            "type": "ULONG",
            "value": 0
          },
          "ulCodePageRange2": {
            "type": "ULONG",
            "value": 0
          },
          "sxHeight": {
            "type": "SHORT",
            "value": 0
          },
          "sCapHeight": {
            "type": "SHORT",
            "value": 0
          },
          "usDefaultChar": {
            "type": "USHORT",
            "value": 0
          },
          "usBreakChar": {
            "type": "USHORT",
            "value": 0
          },
          "usMaxContext": {
            "type": "USHORT",
            "value": 0
          },
          "usLowerOpticalPointSize": {
            "type": "USHORT",
            "value": 0
          },
          "usUpperOpticalPointSize": {
            "type": "USHORT",
            "value": 0
          }
        }
      }
    },
    "post table": {
      "type": "RECORD",
      "value": {
        "name": "post",
        "fields": {
          "version": {
            "type": "FIXED",
            "value": 196608
          },
          "italicAngle": {
            "type": "FIXED",
            "value": 0
          },
          "underlinePosition": {
            "type": "FWORD",
            "value": 0
          },
          "underlineThickness": {
            "type": "FWORD",
            "value": 0
          },
          "isFixedPitch": {
            "type": "ULONG",
            "value": 0
          },
          "minMemType42": {
            "type": "ULONG",
            "value": 0
          },
          "maxMemType42": {
            "type": "ULONG",
            "value": 0
          },
          "minMemType1": {
            "type": "ULONG",
            "value": 0
          },
          "maxMemType1": {
            "type": "ULONG",
            "value": 0
          }
        }
      }
    }
  }
}

这些是用于为细微变化之一创建输出字节的十进制值:

79 84 84 79 
0 9 0 8 
0 3 0 1 
67 70 70 32 (1)
0 0 0 0 
0 0 0 156 
0 0 0 5 
99 109 97 112 (2)
0 0 0 0 
0 0 0 164 
0 0 0 36 
104 101 97 100 (3)
0 0 0 0 
0 0 0 200 
0 0 0 54 
104 104 101 97 (4)
0 0 0 0 
0 0 1 0 
0 0 0 36 
104 109 116 120 (5)
0 0 0 0 
0 0 1 36 
0 0 0 0 
109 97 120 112 (6)
0 0 0 0 
0 0 1 36 
0 0 0 6 
110 97 109 101 (7)
0 0 0 0 
0 0 1 44 
0 0 0 6 
79 83 47 50 (8)
0 0 0 0 
0 0 1 52 
0 0 0 100 
112 111 115 116 (9)
0 0 0 0 
0 0 1 152 
0 0 0 32 
2 0 4 0 (CFF start)
0 0 0 0 (4-align with three 0's)
0 0 0 1 (cmap start)
0 0 0 6 
0 0 0 16 
0 4 0 16 
0 0 0 2 0 2 0 0 0 0 255 255 0 0 255 255 0 1 0 0 0 1 0 0 0 1 0 0 0 0 0 0 95 15 60 245 0 3 3 232 0 0 0 0 216 101 49 90 0 0 0 0 216 101 49 90 0 0 0 0 0 0 0 0 0 0 0 3 0 2 0 0 0 0 0 0 0 1 0 0 0 200 0 100 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 80 0 0 0 0 0 0 0 0 0 0 6 0 0 0 5 0 0 0 0 0 0 0 0 2 138 2 187 0 0 0 140 2 138 2 187 0 0 1 223 0 49 1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 88 88 88 88 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

好像显示是对齐的,所以没看懂。希望得到一些帮助。

【问题讨论】:

    标签: debugging fonts binary byte opentype


    【解决方案1】:

    在调试输出时,您可能会发现使用十六进制转储格式会很有帮助,该格式在右列中显示字节的 ASCII 表示。我为此使用xxd,并建议您也这样做。特别是对于 OpenType 字体,这种转储格式对于发现对齐问题非常方便,尤其是在字体标题中。

    明白我的意思:这是你的一个转储的第一部分:

    00000000: 4f54 544f 0009 0008 0003 0001 4346 4620  OTTO........CFF 
    00000010: 0000 0000 0000 00c2 9c00 0000 0563 6d61  .............cma
    00000020: 7000 0000 0000 0000 c2a4 0000 0024 6865  p............$he
    00000030: 6164 0000 0000 0000 00c3 8800 0000 3668  ad............6h
    00000040: 6865 6100 0000 0000 0001 0000 0000 2468  hea...........$h
    00000050: 6d74 7800 0000 0000 0001 2400 0000 006d  mtx.......$....m
    00000060: 6178 7000 0000 0000 0001 2400 0000 066e  axp.......$....n
    00000070: 616d 6500 0000 0000 0001 2c00 0000 064f  ame.......,....O
    00000080: 532f 3200 0000 0000 0001 3400 0000 6470  S/2.......4...dp
    00000090: 6f73 7400 0000 0000 0001 c298 0000 0020  ost............ 
    

    您可以看到第一个 tableDirectory 条目,对于 CFF 表,标签 ('CFF') 从第一行的最后 4 个字节开始(4346 4620 是 ASCII 中的 'CFF'),并且那是正确的对齐方式。因为 hexdump 行长度正好是 16 个字节,并且因为每个 tableDirectory 条目是 16 个字节,所以正确对齐的 tableDirectory 将每个表的标记作为该行的最后 4 个字节。但是正如你所看到的,你有一些错位......'cmap'的'c'(0x63)向右太远了一个字节,随后的tableDirectory条目也被移动了。它应该看起来更像这样:

    00000000: 4f54 544f 0009 0008 0003 0001 4346 4620  OTTO........CFF 
    00000010: ???? ???? ???? ???? ???? ???? 636d 6170  ............cmap
    00000020: ???? ???? ???? ???? ???? ???? 6865 6164  ............head
    00000030: ???? ???? ???? ???? ???? ???? 6868 6561  ............hhea
    [...]
    

    所以看起来对于您的 一些 tableDirectory 条目,最后添加了一个额外的字节。因此,您需要备份并检查该代码并首先使其正常工作,然后担心 searchRange、rangeShift 和 entrySelector(假设您的字体包含广告中的 9 个表,应该是:0080 0003 0010(十六进制))。

    【讨论】:

      猜你喜欢
      • 2019-06-10
      • 2022-01-24
      • 2020-07-29
      • 2011-06-03
      • 2018-12-03
      • 2013-11-18
      • 1970-01-01
      • 2019-06-10
      • 1970-01-01
      相关资源
      最近更新 更多