truetype cmap format 2
/** * Read a format 2 subtable. * * @param data the data stream of the to be parsed ttf font * @param numGlyphs number of glyphs to be read * @throws IOException If there is an error parsing the true type font. */ protected void processSubtype2(TTFDataStream data, int numGlyphs) throws IOException {int[] subHeaderKeys = new int[256]; // ---- keep the Max Index of the SubHeader array to know its length int maxSubHeaderIndex = 0; for (int i = 0; i < 256; i++) { subHeaderKeys[i] = data.readUnsignedShort(); maxSubHeaderIndex = Math.max(maxSubHeaderIndex, subHeaderKeys[i] / 8); // maxSubHeaderIndexの最大値を求める // subHeaderKeys[i]は、インデックスの8倍の値なので8で割っている。 }// ---- Read all SubHeaders to avoid useless seek on DataSource SubHeader[] subHeaders = new SubHeader[maxSubHeaderIndex + 1]; for (int i = 0; i <= maxSubHeaderIndex; ++i) { int firstCode = data.readUnsignedShort(); int entryCount = data.readUnsignedShort(); short idDelta = data.readSignedShort(); int idRangeOffset = data.readUnsignedShort() - (maxSubHeaderIndex + 1 - i - 1) * 8 - 2; subHeaders[i] = new SubHeader(firstCode, entryCount, idDelta, idRangeOffset); }long startGlyphIndexOffset = data.getCurrentPosition(); glyphIdToCharacterCode = newGlyphIdToCharacterCode(numGlyphs); characterCodeToGlyphId = new HashMap<Integer, Integer>(numGlyphs);for (int i = 0; i <= maxSubHeaderIndex; ++i) { SubHeader sh = subHeaders[i]; int firstCode = sh.getFirstCode(); int idRangeOffset = sh.getIdRangeOffset(); int idDelta = sh.getIdDelta(); int entryCount = sh.getEntryCount(); data.seek(startGlyphIndexOffset + idRangeOffset);for (int j = 0; j < entryCount; ++j) { // ---- compute the Character Code int charCode = i; charCode = (charCode << 8) + (firstCode + j); // ---- Go to the CharacterCOde position in the Sub Array // of the glyphIndexArray // glyphIndexArray contains Unsigned Short so add (j * 2) bytes // at the index position int p = data.readUnsignedShort(); // ---- compute the glyphIndex if (p > 0) { p = (p + idDelta) % 65536; } if (p >= numGlyphs) { LOG.warn("glyphId " + p + " for charcode " + charCode + " ignored, numGlyphs is " + numGlyphs); continue; } glyphIdToCharacterCode[p] = charCode; characterCodeToGlyphId.put(charCode, p); }}
}
|