private void writeCMAP()

in src/java/org/apache/fop/render/pdf/pdfbox/MergeTTFonts.java [444:515]


    private void writeCMAP(List<Cmap> cmaps) {
        mergeUniCmap(cmaps);

        int checksum = currentPos;
        pad4();
        int cmapPos = currentPos;
        writeUShort(0); //version
        writeUShort(cmaps.size()); //number of tables

        int tablesSize = 8 * cmaps.size();
        for (int i = 0; i < cmaps.size(); i++) {
            Cmap cmap = cmaps.get(i);
            writeUShort(cmap.platformId); //platformid
            writeUShort(cmap.platformEncodingId); //platformEncodingId
            writeULong(currentPos, 4 + tablesSize + getCmapOffset(cmaps, i)); //subTableOffset
            currentPos += 4;
        }

        for (Cmap cmap : cmaps) {
            if (cmap.platformId != 0) {
                writeUShort(4); //subtableFormat
                int segCount = cmap.getGlyphIdToCharacterCode().size() + 1;
                writeUShort(16 + (segCount * 8)); //length
                writeUShort(0); //lang
                writeUShort(segCount * 2); //segCountX2
                double searchRange = Math.pow(2, Math.floor(logBase2(segCount))) * 2;
                writeUShort((int) searchRange); //searchRange
                double entrySelector = Math.floor(logBase2(segCount));
                writeUShort((int) entrySelector); //entrySelector
                double rangeShift = (segCount * 2) - searchRange;
                writeUShort((int) rangeShift); //rangeShift
                for (int c : cmap.getGlyphIdToCharacterCode().keySet()) {
                    writeUShort(c); //endCode
                }
                writeUShort(0xFFFF);
                writeUShort(0); //reservedPad
                for (int c : cmap.getGlyphIdToCharacterCode().keySet()) {
                    writeUShort(c); //startCode
                }
                writeUShort(0xFFFF);
                for (Map.Entry<Integer, Integer> entry : cmap.getGlyphIdToCharacterCode().entrySet()) {
                    writeUShort(entry.getValue() - entry.getKey()); //idDelta
                }
                writeUShort(0);
                for (int g : cmap.getGlyphIdToCharacterCode().keySet()) {
                    writeUShort(0); //idRangeOffsets
                }
                writeUShort(0);
            } else {
                writeUShort(12); //subtableFormat
                writeUShort(0);
                writeULong(currentPos, (cmap.getGlyphIdToCharacterCode().size() * 12) + 16);
                currentPos += 4;
                writeULong(currentPos, 0);
                currentPos += 4;
                writeULong(currentPos, cmap.getGlyphIdToCharacterCode().size());
                currentPos += 4;

                for (Map.Entry<Integer, Integer> g : cmap.getGlyphIdToCharacterCode().entrySet()) {
                    writeULong(currentPos, g.getKey());
                    currentPos += 4;
                    writeULong(currentPos, g.getKey());
                    currentPos += 4;
                    writeULong(currentPos, g.getValue());
                    currentPos += 4;
                }
            }
        }

        updateCheckSum(checksum, currentPos - cmapPos, OFTableName.CMAP);
        realSize += currentPos - cmapPos;
    }