/*
 * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.font;

import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.IntBuffer;
import java.util.Locale;
import java.nio.charset.*;

/*
 * A tt font has a CMAP table which is in turn made up of sub-tables which
 * describe the char to glyph mapping in (possibly) multiple ways.
 * CMAP subtables are described by 3 values.
 * 1. Platform ID (eg 3=Microsoft, which is the id we look for in JDK)
 * 2. Encoding (eg 0=symbol, 1=unicode)
 * 3. TrueType subtable format (how the char->glyph mapping for the encoding
 * is stored in the subtable). See the TrueType spec. Format 4 is required
 * by MS in fonts for windows. Its uses segmented mapping to delta values.
 * Most typically we see are (3,1,4) :
 * CMAP Platform ID=3 is what we use.
 * Encodings that are used in practice by JDK on Solaris are
 *  symbol (3,0)
 *  unicode (3,1)
 *  GBK (3,5) (note that solaris zh fonts report 3,4 but are really 3,5)
 * The format for almost all subtables is 4. However the solaris (3,5)
 * encodings are typically in format 2.
 */
abstract class CMap {

//     static char WingDings_b2c[] = {
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0x2702, 0x2701, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0x2706, 0x2709, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2707, 0x270d,
//         0xfffd, 0x270c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0x2708, 0xfffd, 0xfffd, 0x2744, 0xfffd, 0x271e, 0xfffd,
//         0x2720, 0x2721, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0x2751, 0x2752, 0xfffd, 0xfffd, 0x2756, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0x2740, 0x273f, 0x275d, 0x275e, 0xfffd,
//         0xfffd, 0x2780, 0x2781, 0x2782, 0x2783, 0x2784, 0x2785, 0x2786,
//         0x2787, 0x2788, 0x2789, 0xfffd, 0x278a, 0x278b, 0x278c, 0x278d,
//         0x278e, 0x278f, 0x2790, 0x2791, 0x2792, 0x2793, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x274d, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2736, 0x2734, 0xfffd, 0x2735,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x272a, 0x2730, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x27a5, 0xfffd, 0x27a6, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0x27a2, 0xfffd, 0xfffd, 0xfffd, 0x27b3, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0x27a1, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0x27a9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0x2717, 0x2713, 0xfffd, 0xfffd, 0xfffd,
//    };

//     static char Symbols_b2c[] = {
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0x2200, 0xfffd, 0x2203, 0xfffd, 0xfffd, 0x220d,
//         0xfffd, 0xfffd, 0x2217, 0xfffd, 0xfffd, 0x2212, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0x2245, 0x0391, 0x0392, 0x03a7, 0x0394, 0x0395, 0x03a6, 0x0393,
//         0x0397, 0x0399, 0x03d1, 0x039a, 0x039b, 0x039c, 0x039d, 0x039f,
//         0x03a0, 0x0398, 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03c2, 0x03a9,
//         0x039e, 0x03a8, 0x0396, 0xfffd, 0x2234, 0xfffd, 0x22a5, 0xfffd,
//         0xfffd, 0x03b1, 0x03b2, 0x03c7, 0x03b4, 0x03b5, 0x03c6, 0x03b3,
//         0x03b7, 0x03b9, 0x03d5, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03bf,
//         0x03c0, 0x03b8, 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03d6, 0x03c9,
//         0x03be, 0x03c8, 0x03b6, 0xfffd, 0xfffd, 0xfffd, 0x223c, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0x03d2, 0xfffd, 0x2264, 0x2215, 0x221e, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0x2218, 0xfffd, 0xfffd, 0x2265, 0xfffd, 0x221d, 0xfffd, 0x2219,
//         0xfffd, 0x2260, 0x2261, 0x2248, 0x22ef, 0x2223, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2297, 0x2295, 0x2205, 0x2229,
//         0x222a, 0x2283, 0x2287, 0x2284, 0x2282, 0x2286, 0x2208, 0x2209,
//         0xfffd, 0x2207, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x221a, 0x22c5,
//         0xfffd, 0x2227, 0x2228, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0x22c4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2211, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0x222b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//         0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd,
//     };

    static final short ShiftJISEncoding = 2;
    static final short GBKEncoding      = 3;
    static final short Big5Encoding     = 4;
    static final short WansungEncoding  = 5;
    static final short JohabEncoding    = 6;
    static final short MSUnicodeSurrogateEncoding = 10;

    static final char noSuchChar = (char)0xfffd;
    static final int SHORTMASK = 0x0000ffff;
    static final int INTMASK   = 0x7fffffff;

    static final char[][] converterMaps = new char[7][];

    /*
     * Unicode->other encoding translation array. A pre-computed look up
     * which can be shared across all fonts using that encoding.
     * Using this saves running character coverters repeatedly.
     */
    char[] xlat;
    UVS uvs = null;

    static CMap initialize(TrueTypeFont font) {

        CMap cmap = null;

        int offset, platformID, encodingID=-1;

        int three0=0, three1=0, three2=0, three3=0, three4=0, three5=0,
            three6=0, three10=0;
        int zero5 = 0; // for Unicode Variation Sequences
        boolean threeStar = false;

        ByteBuffer cmapBuffer = font.getTableBuffer(TrueTypeFont.cmapTag);
        int cmapTableOffset = font.getTableSize(TrueTypeFont.cmapTag);
        short numberSubTables = cmapBuffer.getShort(2);

        /* locate the offsets of all 3,*  (ie Microsoft platform) encodings */
        for (int i=0; i<numberSubTables; i++) {
            cmapBuffer.position(i * 8 + 4);
            platformID = cmapBuffer.getShort();
            if (platformID == 3) {
                threeStar = true;
                encodingID = cmapBuffer.getShort();
                offset     = cmapBuffer.getInt();
                switch (encodingID) {
                case 0:  three0  = offset; break; // MS Symbol encoding
                case 1:  three1  = offset; break; // MS Unicode cmap
                case 2:  three2  = offset; break; // ShiftJIS cmap.
                case 3:  three3  = offset; break; // GBK cmap
                case 4:  three4  = offset; break; // Big 5 cmap
                case 5:  three5  = offset; break; // Wansung
                case 6:  three6  = offset; break; // Johab
                case 10: three10 = offset; break; // MS Unicode surrogates
                }
            } else if (platformID == 0) {
                encodingID = cmapBuffer.getShort();
                offset     = cmapBuffer.getInt();
                if (encodingID == 5) {
                    zero5 = offset;
                }
            }
        }

        /* This defines the preference order for cmap subtables */
        if (threeStar) {
            if (three10 != 0) {
                cmap = createCMap(cmapBuffer, three10, null);
            }
            else if  (three0 != 0) {
                /* The special case treatment of these fonts leads to
                 * anomalies where a user can view "wingdings" and "wingdings2"
                 * and the latter shows all its code points in the unicode
                 * private use area at 0xF000->0XF0FF and the former shows
                 * a scattered subset of its glyphs that are known mappings to
                 * unicode code points.
                 * The primary purpose of these mappings was to facilitate
                 * display of symbol chars etc in composite fonts, however
                 * this is not needed as all these code points are covered
                 * by some other platform symbol font.
                 * Commenting this out reduces the role of these two files
                 * (assuming that they continue to be used in font.properties)
                 * to just one of contributing to the overall composite
                 * font metrics, and also AWT can still access the fonts.
                 * Clients which explicitly accessed these fonts as names
                 * "Symbol" and "Wingdings" (ie as physical fonts) and
                 * expected to see a scattering of these characters will
                 * see them now as missing. How much of a problem is this?
                 * Perhaps we could still support this mapping just for
                 * "Symbol.ttf" but I suspect some users would prefer it
                 * to be mapped in to the Latin range as that is how
                 * the "symbol" font is used in native apps.
                 */
//              String name = font.platName.toLowerCase(Locale.ENGLISH);
//              if (name.endsWith("symbol.ttf")) {
//                  cmap = createSymbolCMap(cmapBuffer, three0, Symbols_b2c);
//              } else if (name.endsWith("wingding.ttf")) {
//                  cmap = createSymbolCMap(cmapBuffer, three0, WingDings_b2c);
//              } else {
                    cmap = createCMap(cmapBuffer, three0, null);
//              }
            }
            else if (three1 != 0) {
                cmap = createCMap(cmapBuffer, three1, null);
            }
            else if (three2 != 0) {
                cmap = createCMap(cmapBuffer, three2,
                                  getConverterMap(ShiftJISEncoding));
            }
            else if (three3 != 0) {
                cmap = createCMap(cmapBuffer, three3,
                                  getConverterMap(GBKEncoding));
            }
            else if (three4 != 0) {
                cmap = createCMap(cmapBuffer, three4,
                                  getConverterMap(Big5Encoding));
            }
            else if (three5 != 0) {
                cmap = createCMap(cmapBuffer, three5,
                                  getConverterMap(WansungEncoding));
            }
            else if (three6 != 0) {
                cmap = createCMap(cmapBuffer, three6,
                                  getConverterMap(JohabEncoding));
            }
        } else {
            /* No 3,* subtable was found. Just use whatever is the first
             * table listed. Not very useful but maybe better than
             * rejecting the font entirely?
             */
            cmap = createCMap(cmapBuffer, cmapBuffer.getInt(8), null);
        }
        // For Unicode Variation Sequences
        if (cmap != null && zero5 != 0) {
            cmap.createUVS(cmapBuffer, zero5);
        }
        return cmap;
    }

    /* speed up the converting by setting the range for double
     * byte characters;
     */
    static char[] getConverter(short encodingID) {
        int dBegin = 0x8000;
        int dEnd   = 0xffff;
        String encoding;

        switch (encodingID) {
        case ShiftJISEncoding:
            dBegin = 0x8140;
            dEnd   = 0xfcfc;
            encoding = "SJIS";
            break;
        case GBKEncoding:
            dBegin = 0x8140;
            dEnd   = 0xfea0;
            encoding = "GBK";
            break;
        case Big5Encoding:
            dBegin = 0xa140;
            dEnd   = 0xfefe;
            encoding = "Big5";
            break;
        case WansungEncoding:
            dBegin = 0xa1a1;
            dEnd   = 0xfede;
            encoding = "EUC_KR";
            break;
        case JohabEncoding:
            dBegin = 0x8141;
            dEnd   = 0xfdfe;
            encoding = "Johab";
            break;
        default:
            return null;
        }

        try {
            char[] convertedChars = new char[65536];
            for (int i=0; i<65536; i++) {
                convertedChars[i] = noSuchChar;
            }

            byte[] inputBytes = new byte[(dEnd-dBegin+1)*2];
            char[] outputChars = new char[(dEnd-dBegin+1)];

            int j = 0;
            int firstByte;
            if (encodingID == ShiftJISEncoding) {
                for (int i = dBegin; i <= dEnd; i++) {
                    firstByte = (i >> 8 & 0xff);
                    if (firstByte >= 0xa1 && firstByte <= 0xdf) {
                        //sjis halfwidth katakana
                        inputBytes[j++] = (byte)0xff;
                        inputBytes[j++] = (byte)0xff;
                    } else {
                        inputBytes[j++] = (byte)firstByte;
                        inputBytes[j++] = (byte)(i & 0xff);
                    }
                }
            } else {
                for (int i = dBegin; i <= dEnd; i++) {
                    inputBytes[j++] = (byte)(i>>8 & 0xff);
                    inputBytes[j++] = (byte)(i & 0xff);
                }
            }

            Charset.forName(encoding).newDecoder()
            .onMalformedInput(CodingErrorAction.REPLACE)
            .onUnmappableCharacter(CodingErrorAction.REPLACE)
            .replaceWith("\u0000")
            .decode(ByteBuffer.wrap(inputBytes, 0, inputBytes.length),
                    CharBuffer.wrap(outputChars, 0, outputChars.length),
                    true);

            // ensure single byte ascii
            for (int i = 0x20; i <= 0x7e; i++) {
                convertedChars[i] = (char)i;
            }

            //sjis halfwidth katakana
            if (encodingID == ShiftJISEncoding) {
                for (int i = 0xa1; i <= 0xdf; i++) {
                    convertedChars[i] = (char)(i - 0xa1 + 0xff61);
                }
            }

            /* It would save heap space (approx 60Kbytes for each of these
             * converters) if stored only valid ranges (ie returned
             * outputChars directly. But this is tricky since want to
             * include the ASCII range too.
             */
//          System.err.println("oc.len="+outputChars.length);
//          System.err.println("cc.len="+convertedChars.length);
//          System.err.println("dbegin="+dBegin);
            System.arraycopy(outputChars, 0, convertedChars, dBegin,
                             outputChars.length);

            //return convertedChars;
            /* invert this map as now want it to map from Unicode
             * to other encoding.
             */
            char [] invertedChars = new char[65536];
            for (int i=0;i<65536;i++) {
                if (convertedChars[i] != noSuchChar) {
                    invertedChars[convertedChars[i]] = (char)i;
                }
            }
            return invertedChars;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /*
     * The returned array maps to unicode from some other 2 byte encoding
     * eg for a 2byte index which represents a SJIS char, the indexed
     * value is the corresponding unicode char.
     */
    static char[] getConverterMap(short encodingID) {
        if (converterMaps[encodingID] == null) {
           converterMaps[encodingID] = getConverter(encodingID);
        }
        return converterMaps[encodingID];
    }


    static CMap createCMap(ByteBuffer buffer, int offset, char[] xlat) {
        /* First do a sanity check that this cmap subtable is contained
         * within the cmap table.
         */
        int subtableFormat = buffer.getChar(offset);
        long subtableLength;
        if (subtableFormat < 8) {
            subtableLength = buffer.getChar(offset+2);
        } else {
            subtableLength = buffer.getInt(offset+4) & INTMASK;
        }
        if (FontUtilities.isLogging() && offset + subtableLength > buffer.capacity()) {
            FontUtilities.logWarning("Cmap subtable overflows buffer.");
        }
        switch (subtableFormat) {
        case 0:  return new CMapFormat0(buffer, offset);
        case 2:  return new CMapFormat2(buffer, offset, xlat);
        case 4:  return new CMapFormat4(buffer, offset, xlat);
        case 6:  return new CMapFormat6(buffer, offset, xlat);
        case 8:  return new CMapFormat8(buffer, offset, xlat);
        case 10: return new CMapFormat10(buffer, offset, xlat);
        case 12: return new CMapFormat12(buffer, offset, xlat);
        default: throw new RuntimeException("Cmap format unimplemented: " +
                                            (int)buffer.getChar(offset));
        }
    }

    private void createUVS(ByteBuffer buffer, int offset) {
        int subtableFormat = buffer.getChar(offset);
        if (subtableFormat == 14) {
            long subtableLength = buffer.getInt(offset + 2) & INTMASK;
            if (FontUtilities.isLogging() && offset + subtableLength > buffer.capacity()) {
                FontUtilities.logWarning("Cmap UVS subtable overflows buffer.");
            }
            try {
                this.uvs = new UVS(buffer, offset);
            } catch (Throwable t) {
            }
        }
        return;
    }

/*
    final char charVal(byte[] cmap, int index) {
        return (char)(((0xff & cmap[index]) << 8)+(0xff & cmap[index+1]));
    }

    final short shortVal(byte[] cmap, int index) {
        return (short)(((0xff & cmap[index]) << 8)+(0xff & cmap[index+1]));
    }
*/
    abstract char getGlyph(int charCode);

    /* Format 4 Header is
     * ushort format (off=0)
     * ushort length (off=2)
     * ushort language (off=4)
     * ushort segCountX2 (off=6)
     * ushort searchRange (off=8)
     * ushort entrySelector (off=10)
     * ushort rangeShift (off=12)
     * ushort endCount[segCount] (off=14)
     * ushort reservedPad
     * ushort startCount[segCount]
     * short idDelta[segCount]
     * idRangeOFfset[segCount]
     * ushort glyphIdArray[]
     */
    static class CMapFormat4 extends CMap {
        int segCount;
        int entrySelector;
        int rangeShift;
        char[] endCount;
        char[] startCount;
        short[] idDelta;
        char[] idRangeOffset;
        char[] glyphIds;

        CMapFormat4(ByteBuffer bbuffer, int offset, char[] xlat) {

            this.xlat = xlat;

            bbuffer.position(offset);
            CharBuffer buffer = bbuffer.asCharBuffer();
            buffer.get(); // skip, we already know format=4
            int subtableLength = buffer.get();
            /* Try to recover from some bad fonts which specify a subtable
             * length that would overflow the byte buffer holding the whole
             * cmap table. If this isn't a recoverable situation an exception
             * may be thrown which is caught higher up the call stack.
             * Whilst this may seem lenient, in practice, unless the "bad"
             * subtable we are using is the last one in the cmap table we
             * would have no way of knowing about this problem anyway.
             */
            if (offset+subtableLength > bbuffer.capacity()) {
                subtableLength = bbuffer.capacity() - offset;
            }
            buffer.get(); // skip language
            segCount = buffer.get()/2;
            int searchRange = buffer.get();
            entrySelector = buffer.get();
            rangeShift    = buffer.get()/2;
            startCount = new char[segCount];
            endCount = new char[segCount];
            idDelta = new short[segCount];
            idRangeOffset = new char[segCount];

            for (int i=0; i<segCount; i++) {
                endCount[i] = buffer.get();
            }
            buffer.get(); // 2 bytes for reserved pad
            for (int i=0; i<segCount; i++) {
                startCount[i] = buffer.get();
            }

            for (int i=0; i<segCount; i++) {
                idDelta[i] = (short)buffer.get();
            }

            for (int i=0; i<segCount; i++) {
                char ctmp = buffer.get();
                idRangeOffset[i] = (char)((ctmp>>1)&0xffff);
            }
            /* Can calculate the number of glyph IDs by subtracting
             * "pos" from the length of the cmap
             */
            int pos = (segCount*8+16)/2;
            buffer.position(pos);
            int numGlyphIds = (subtableLength/2 - pos);
            glyphIds = new char[numGlyphIds];
            for (int i=0;i<numGlyphIds;i++) {
                glyphIds[i] = buffer.get();
            }
/*
            System.err.println("segcount="+segCount);
            System.err.println("entrySelector="+entrySelector);
            System.err.println("rangeShift="+rangeShift);
            for (int j=0;j<segCount;j++) {
              System.err.println("j="+j+ " sc="+(int)(startCount[j]&0xffff)+
                                 " ec="+(int)(endCount[j]&0xffff)+
                                 " delta="+idDelta[j] +
                                 " ro="+(int)idRangeOffset[j]);
            }

            //System.err.println("numglyphs="+glyphIds.length);
            for (int i=0;i<numGlyphIds;i++) {
                  System.err.println("gid["+i+"]="+(int)glyphIds[i]);
            }
*/
        }

        char getGlyph(int charCode) {

            final int origCharCode = charCode;
            int index = 0;
            char glyphCode = 0;

            if (isSurrogate(charCode)) {
                return 0;
            }

            /* presence of translation array indicates that this
             * cmap is in some other (non-unicode encoding).
             * In order to look-up a char->glyph mapping we need to
             * translate the unicode code point to the encoding of
             * the cmap.
             * REMIND: VALID CHARCODES??
             */
            if (xlat != null) {
                charCode = xlat[charCode];
            }

            /*
             * Citation from the TrueType (and OpenType) spec:
             *   The segments are sorted in order of increasing endCode
             *   values, and the segment values are specified in four parallel
             *   arrays. You search for the first endCode that is greater than
             *   or equal to the character code you want to map. If the
             *   corresponding startCode is less than or equal to the
             *   character code, then you use the corresponding idDelta and
             *   idRangeOffset to map the character code to a glyph index
             *   (otherwise, the missingGlyph is returned).
             */

            /*
             * CMAP format4 defines several fields for optimized search of
             * the segment list (entrySelector, searchRange, rangeShift).
             * However, benefits are negligible and some fonts have incorrect
             * data - so we use straightforward binary search (see bug 6247425)
             */
            int left = 0, right = startCount.length;
            index = startCount.length >> 1;
            while (left < right) {
                if (endCount[index] < charCode) {
                    left = index + 1;
                } else {
                    right = index;
                }
                index = (left + right) >> 1;
            }

            if (charCode >= startCount[index] && charCode <= endCount[index]) {
                int rangeOffset = idRangeOffset[index];

                if (rangeOffset == 0) {
                    glyphCode = (char)(charCode + idDelta[index]);
                } else {
                    /* Calculate an index into the glyphIds array */

/*
                    System.err.println("rangeoffset="+rangeOffset+
                                       " charCode=" + charCode +
                                       " scnt["+index+"]="+(int)startCount[index] +
                                       " segCnt="+segCount);
*/

                    int glyphIDIndex = rangeOffset - segCount + index
                                         + (charCode - startCount[index]);
                    glyphCode = glyphIds[glyphIDIndex];
                    if (glyphCode != 0) {
                        glyphCode = (char)(glyphCode + idDelta[index]);
                    }
                }
            }
            return glyphCode;
        }
    }

    // Format 0: Byte Encoding table
    static class CMapFormat0 extends CMap {
        byte [] cmap;

        CMapFormat0(ByteBuffer buffer, int offset) {

            /* skip 6 bytes of format, length, and version */
            int len = buffer.getChar(offset+2);
            cmap = new byte[len-6];
            buffer.position(offset+6);
            buffer.get(cmap);
        }

        char getGlyph(int charCode) {
            if (charCode < 256) {
                return (char)(0xff & cmap[charCode]);
            } else {
                return 0;
            }
        }
    }

//     static CMap createSymbolCMap(ByteBuffer buffer, int offset, char[] syms) {

//      CMap cmap = createCMap(buffer, offset, null);
//      if (cmap == null) {
//          return null;
//      } else {
//          return new CMapFormatSymbol(cmap, syms);
//      }
//     }

//     static class CMapFormatSymbol extends CMap {

//      CMap cmap;
//      static final int NUM_BUCKETS = 128;
//      Bucket[] buckets = new Bucket[NUM_BUCKETS];

//      class Bucket {
//          char unicode;
//          char glyph;
//          Bucket next;

//          Bucket(char u, char g) {
//              unicode = u;
//              glyph = g;
//          }
//      }

//      CMapFormatSymbol(CMap cmap, char[] syms) {

//          this.cmap = cmap;

//          for (int i=0;i<syms.length;i++) {
//              char unicode = syms[i];
//              if (unicode != noSuchChar) {
//                  char glyph = cmap.getGlyph(i + 0xf000);
//                  int hash = unicode % NUM_BUCKETS;
//                  Bucket bucket = new Bucket(unicode, glyph);
//                  if (buckets[hash] == null) {
//                      buckets[hash] = bucket;
//                  } else {
//                      Bucket b = buckets[hash];
//                      while (b.next != null) {
//                          b = b.next;
//                      }
//                      b.next = bucket;
//                  }
//              }
//          }
//      }

//      char getGlyph(int unicode) {
//          if (unicode >= 0x1000) {
//              return 0;
//          }
//          else if (unicode >=0xf000 && unicode < 0xf100) {
//              return cmap.getGlyph(unicode);
//          } else {
//              Bucket b = buckets[unicode % NUM_BUCKETS];
//              while (b != null) {
//                  if (b.unicode == unicode) {
//                      return b.glyph;
//                  } else {
//                      b = b.next;
//                  }
//              }
//              return 0;
//          }
//      }
//     }

    // Format 2: High-byte mapping through table
    static class CMapFormat2 extends CMap {

        char[] subHeaderKey = new char[256];
         /* Store subheaders in individual arrays
          * A SubHeader entry theoretically looks like {
          *   char firstCode;
          *   char entryCount;
          *   short idDelta;
          *   char idRangeOffset;
          * }
          */
        char[] firstCodeArray;
        char[] entryCountArray;
        short[] idDeltaArray;
        char[] idRangeOffSetArray;

        char[] glyphIndexArray;

        CMapFormat2(ByteBuffer buffer, int offset, char[] xlat) {

            this.xlat = xlat;

            int tableLen = buffer.getChar(offset+2);
            buffer.position(offset+6);
            CharBuffer cBuffer = buffer.asCharBuffer();
            char maxSubHeader = 0;
            for (int i=0;i<256;i++) {
                subHeaderKey[i] = cBuffer.get();
                if (subHeaderKey[i] > maxSubHeader) {
                    maxSubHeader = subHeaderKey[i];
                }
            }
            /* The value of the subHeaderKey is 8 * the subHeader index,
             * so the number of subHeaders can be obtained by dividing
             * this value bv 8 and adding 1.
             */
            int numSubHeaders = (maxSubHeader >> 3) +1;
            firstCodeArray = new char[numSubHeaders];
            entryCountArray = new char[numSubHeaders];
            idDeltaArray  = new short[numSubHeaders];
            idRangeOffSetArray  = new char[numSubHeaders];
            for (int i=0; i<numSubHeaders; i++) {
                firstCodeArray[i] = cBuffer.get();
                entryCountArray[i] = cBuffer.get();
                idDeltaArray[i] = (short)cBuffer.get();
                idRangeOffSetArray[i] = cBuffer.get();
//              System.out.println("sh["+i+"]:fc="+(int)firstCodeArray[i]+
//                                 " ec="+(int)entryCountArray[i]+
//                                 " delta="+(int)idDeltaArray[i]+
//                                 " offset="+(int)idRangeOffSetArray[i]);
            }

            int glyphIndexArrSize = (tableLen-518-numSubHeaders*8)/2;
            glyphIndexArray = new char[glyphIndexArrSize];
            for (int i=0; i<glyphIndexArrSize;i++) {
                glyphIndexArray[i] = cBuffer.get();
            }
        }

        char getGlyph(int charCode) {
            if (isSurrogate(charCode)) {
                return 0;
            }

            if (xlat != null) {
                charCode = xlat[charCode];
            }

            char highByte = (char)(charCode >> 8);
            char lowByte = (char)(charCode & 0xff);
            int key = subHeaderKey[highByte]>>3; // index into subHeaders
            char mapMe;

            if (key != 0) {
                mapMe = lowByte;
            } else {
                mapMe = highByte;
                if (mapMe == 0) {
                    mapMe = lowByte;
                }
            }

//          System.err.println("charCode="+Integer.toHexString(charCode)+
//                             " key="+key+ " mapMe="+Integer.toHexString(mapMe));
            char firstCode = firstCodeArray[key];
            if (mapMe < firstCode) {
                return 0;
            } else {
                mapMe -= firstCode;
            }

            if (mapMe < entryCountArray[key]) {
                /* "address" arithmetic is needed to calculate the offset
                 * into glyphIndexArray. "idRangeOffSetArray[key]" specifies
                 * the number of bytes from that location in the table where
                 * the subarray of glyphIndexes starting at "firstCode" begins.
                 * Each entry in the subHeader table is 8 bytes, and the
                 * idRangeOffSetArray field is at offset 6 in the entry.
                 * The glyphIndexArray immediately follows the subHeaders.
                 * So if there are "N" entries then the number of bytes to the
                 * start of glyphIndexArray is (N-key)*8-6.
                 * Subtract this from the idRangeOffSetArray value to get
                 * the number of bytes into glyphIndexArray and divide by 2 to
                 * get the (char) array index.
                 */
                int glyphArrayOffset = ((idRangeOffSetArray.length-key)*8)-6;
                int glyphSubArrayStart =
                        (idRangeOffSetArray[key] - glyphArrayOffset)/2;
                char glyphCode = glyphIndexArray[glyphSubArrayStart+mapMe];
                if (glyphCode != 0) {
                    glyphCode += idDeltaArray[key]; //idDelta
                    return glyphCode;
                }
            }
            return 0;
        }
    }

    // Format 6: Trimmed table mapping
    static class CMapFormat6 extends CMap {

        char firstCode;
        char entryCount;
        char[] glyphIdArray;

        CMapFormat6(ByteBuffer bbuffer, int offset, char[] xlat) {

             bbuffer.position(offset+6);
             CharBuffer buffer = bbuffer.asCharBuffer();
             firstCode = buffer.get();
             entryCount = buffer.get();
             glyphIdArray = new char[entryCount];
             for (int i=0; i< entryCount; i++) {
                 glyphIdArray[i] = buffer.get();
             }
         }

         char getGlyph(int charCode) {
             if (isSurrogate(charCode)) {
                 return 0;
             }

             if (xlat != null) {
                 charCode = xlat[charCode];
             }

             charCode -= firstCode;
             if (charCode < 0 || charCode >= entryCount) {
                  return 0;
             } else {
                  return glyphIdArray[charCode];
             }
         }
    }

    // Format 8: mixed 16-bit and 32-bit coverage
    // Seems unlikely this code will ever get tested as we look for
    // MS platform Cmaps and MS states (in the Opentype spec on their website)
    // that MS doesn't support this format
    static class CMapFormat8 extends CMap {
         byte[] is32 = new byte[8192];
         int nGroups;
         int[] startCharCode;
         int[] endCharCode;
         int[] startGlyphID;

         CMapFormat8(ByteBuffer bbuffer, int offset, char[] xlat) {

             bbuffer.position(12);
             bbuffer.get(is32);
             nGroups = bbuffer.getInt() & INTMASK;
             // A map group record is three uint32's making for 12 bytes total
             if (bbuffer.remaining() < (12 * (long)nGroups)) {
                 throw new RuntimeException("Format 8 table exceeded");
             }
             startCharCode = new int[nGroups];
             endCharCode   = new int[nGroups];
             startGlyphID  = new int[nGroups];
         }

        char getGlyph(int charCode) {
            if (xlat != null) {
                throw new RuntimeException("xlat array for cmap fmt=8");
            }
            return 0;
        }

    }


    // Format 4-byte 10: Trimmed table mapping
    // Seems unlikely this code will ever get tested as we look for
    // MS platform Cmaps and MS states (in the Opentype spec on their website)
    // that MS doesn't support this format
    static class CMapFormat10 extends CMap {

         long firstCode;
         int entryCount;
         char[] glyphIdArray;

         CMapFormat10(ByteBuffer bbuffer, int offset, char[] xlat) {

             bbuffer.position(offset+12);
             firstCode = bbuffer.getInt() & INTMASK;
             entryCount = bbuffer.getInt() & INTMASK;
             // each glyph is a uint16, so 2 bytes per value.
             if (bbuffer.remaining() < (2 * (long)entryCount)) {
                 throw new RuntimeException("Format 10 table exceeded");
             }
             CharBuffer buffer = bbuffer.asCharBuffer();
             glyphIdArray = new char[entryCount];
             for (int i=0; i< entryCount; i++) {
                 glyphIdArray[i] = buffer.get();
             }
         }

         char getGlyph(int charCode) {

             if (xlat != null) {
                 throw new RuntimeException("xlat array for cmap fmt=10");
             }

             int code = (int)(charCode - firstCode);
             if (code < 0 || code >= entryCount) {
                 return 0;
             } else {
                 return glyphIdArray[code];
             }
         }
    }

    // Format 12: Segmented coverage for UCS-4 (fonts supporting
    // surrogate pairs)
    static class CMapFormat12 extends CMap {

        int numGroups;
        int highBit =0;
        int power;
        int extra;
        long[] startCharCode;
        long[] endCharCode;
        int[] startGlyphID;

        CMapFormat12(ByteBuffer buffer, int offset, char[] xlat) {
            if (xlat != null) {
                throw new RuntimeException("xlat array for cmap fmt=12");
            }

            buffer.position(offset+12);
            numGroups = buffer.getInt() & INTMASK;
            // A map group record is three uint32's making for 12 bytes total
            if (buffer.remaining() < (12 * (long)numGroups)) {
                throw new RuntimeException("Format 12 table exceeded");
            }
            startCharCode = new long[numGroups];
            endCharCode = new long[numGroups];
            startGlyphID = new int[numGroups];
            buffer = buffer.slice();
            IntBuffer ibuffer = buffer.asIntBuffer();
            for (int i=0; i<numGroups; i++) {
                startCharCode[i] = ibuffer.get() & INTMASK;
                endCharCode[i] = ibuffer.get() & INTMASK;
                startGlyphID[i] = ibuffer.get() & INTMASK;
            }

            /* Finds the high bit by binary searching through the bits */
            int value = numGroups;

            if (value >= 1 << 16) {
                value >>= 16;
                highBit += 16;
            }

            if (value >= 1 << 8) {
                value >>= 8;
                highBit += 8;
            }

            if (value >= 1 << 4) {
                value >>= 4;
                highBit += 4;
            }

            if (value >= 1 << 2) {
                value >>= 2;
                highBit += 2;
            }

            if (value >= 1 << 1) {
                value >>= 1;
                highBit += 1;
            }

            power = 1 << highBit;
            extra = numGroups - power;
        }

        char getGlyph(int charCode) {
            int probe = power;
            int range = 0;

            if (startCharCode[extra] <= charCode) {
                range = extra;
            }

            while (probe > 1) {
                probe >>= 1;

                if (startCharCode[range+probe] <= charCode) {
                    range += probe;
                }
            }

            if (startCharCode[range] <= charCode &&
                  endCharCode[range] >= charCode) {
                return (char)
                    (startGlyphID[range] + (charCode - startCharCode[range]));
            }

            return 0;
        }
    }

    /* Used to substitute for bad Cmaps. */
    static class NullCMapClass extends CMap {

        char getGlyph(int charCode) {
            return 0;
        }
    }

    public static final NullCMapClass theNullCmap = new NullCMapClass();

    private static boolean isSurrogate(int charCode) {
        return charCode >= 0xFFFF;
    }

    static class UVS {
        int numSelectors;
        int[] selector;

        //for Non-Default UVS Table
        int[] numUVSMapping;
        int[][] unicodeValue;
        char[][] glyphID;

        UVS(ByteBuffer buffer, int offset) {
            buffer.position(offset+6);
            numSelectors = buffer.getInt() & INTMASK;
            // A variation selector record is one 3 byte int + two int32's
            // making for 11 bytes per record.
            if (buffer.remaining() < (11 * (long)numSelectors)) {
                throw new RuntimeException("Variations exceed buffer");
            }
            selector = new int[numSelectors];
            numUVSMapping = new int[numSelectors];
            unicodeValue = new int[numSelectors][];
            glyphID = new char[numSelectors][];

            for (int i = 0; i < numSelectors; i++) {
                buffer.position(offset + 10 + i * 11);
                selector[i] = (buffer.get() & 0xff) << 16; //UINT24
                selector[i] += (buffer.get() & 0xff) << 8;
                selector[i] += buffer.get() & 0xff;

                //skip Default UVS Table

                //for Non-Default UVS Table
                int tableOffset = buffer.getInt(offset + 10 + i * 11 + 7);
                if (tableOffset == 0) {
                    numUVSMapping[i] = 0;
                } else if (tableOffset > 0) {
                    buffer.position(offset+tableOffset);
                    numUVSMapping[i] = buffer.getInt() & INTMASK;
                    // a UVS mapping record is one 3 byte int + uint16
                    // making for 5 bytes per record.
                    if (buffer.remaining() < (5 * (long)numUVSMapping[i])) {
                        throw new RuntimeException("Variations exceed buffer");
                    }
                    unicodeValue[i] = new int[numUVSMapping[i]];
                    glyphID[i] = new char[numUVSMapping[i]];

                    for (int j = 0; j < numUVSMapping[i]; j++) {
                        int temp = (buffer.get() & 0xff) << 16; //UINT24
                        temp += (buffer.get() & 0xff) << 8;
                        temp += buffer.get() & 0xff;
                        unicodeValue[i][j] = temp;
                        glyphID[i][j] = buffer.getChar();
                    }
                }
            }
        }

        static final int VS_NOGLYPH = 0;
        private int getGlyph(int charCode, int variationSelector) {
            int targetSelector = -1;
            for (int i = 0; i < numSelectors; i++) {
                if (selector[i] == variationSelector) {
                    targetSelector = i;
                    break;
                }
            }
            if (targetSelector == -1) {
                return VS_NOGLYPH;
            }
            if (numUVSMapping[targetSelector] > 0) {
                int index = java.util.Arrays.binarySearch(
                                unicodeValue[targetSelector], charCode);
                if (index >= 0) {
                    return glyphID[targetSelector][index];
                }
            }
            return VS_NOGLYPH;
        }
    }

    char getVariationGlyph(int charCode, int variationSelector) {
        char glyph = 0;
        if (uvs == null) {
            glyph = getGlyph(charCode);
        } else {
            int result = uvs.getGlyph(charCode, variationSelector);
            if (result > 0) {
                glyph = (char)(result & 0xFFFF);
            } else {
                glyph = getGlyph(charCode);
            }
        }
        return glyph;
    }
}
