のねのBlog

パソコンの問題や、ソフトウェアの開発で起きた問題など書いていきます。よろしくお願いします^^。

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);
            }

}
}
|