/*
 * Copyright (c) 2011, 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.util.HashMap;

import static sun.font.FontUtilities.isDefaultIgnorable;
import static sun.font.FontUtilities.isIgnorableWhitespace;

public class CCharToGlyphMapper extends CharToGlyphMapper {
    private static native int countGlyphs(final long nativeFontPtr);

    private Cache cache = new Cache();
    CFont fFont;
    int numGlyphs = -1;

    public CCharToGlyphMapper(CFont font) {
        fFont = font;
        missingGlyph = 0; // for getMissingGlyphCode()
    }

    public int getNumGlyphs() {
        if (numGlyphs == -1) {
            numGlyphs = countGlyphs(fFont.getNativeFontPtr());
        }
        return numGlyphs;
    }

    public boolean canDisplay(char ch) {
        int glyph = charToGlyph(ch, false);
        return glyph != missingGlyph;
    }

    public boolean canDisplay(int cp) {
        int glyph = charToGlyph(cp, false);
        return glyph != missingGlyph;
    }

    public synchronized boolean charsToGlyphsNS(int count,
                                                char[] unicodes, int[] glyphs)
    {
        charsToGlyphs(count, unicodes, glyphs);

        // The following shaping checks are from either
        // TrueTypeGlyphMapper or Type1GlyphMapper
        for (int i = 0; i < count; i++) {
            int code = unicodes[i];

            if (code >= HI_SURROGATE_START && code <= HI_SURROGATE_END && i < count - 1) {
                char low = unicodes[i + 1];

                if (low >= LO_SURROGATE_START && low <= LO_SURROGATE_END) {
                    code = (code - HI_SURROGATE_START) * 0x400 + low - LO_SURROGATE_START + 0x10000;
                    glyphs[i + 1] = INVISIBLE_GLYPH_ID;
                }
            }

            if (code < FontUtilities.MIN_LAYOUT_CHARCODE) {
                continue;
            } else if (FontUtilities.isComplexCharCode(code)) {
                return true;
            } else if (code >= 0x10000) {
                i += 1; // Empty glyph slot after surrogate
                continue;
            }
        }

        return false;
    }

    public synchronized int charToGlyph(char unicode) {
        return charToGlyph(unicode, false);
    }

    private int charToGlyph(char unicode, boolean raw) {
        int glyph = cache.get(unicode, raw);
        if (glyph != 0) return glyph;

        final char[] unicodeArray = new char[] { unicode };
        final int[] glyphArray = new int[1];
        nativeCharsToGlyphs(fFont.getNativeFontPtr(), 1, unicodeArray, glyphArray);
        glyph = glyphArray[0];

        cache.put(unicode, glyph);

        return glyph;
    }

    public synchronized int charToGlyph(int unicode) {
        return charToGlyph(unicode, false);
    }

    public synchronized int charToGlyphRaw(int unicode) {
        return charToGlyph(unicode, true);
    }

    private int charToGlyph(int unicode, boolean raw) {
        if (unicode >= 0x10000) {
            int[] glyphs = new int[2];
            char[] surrogates = new char[2];
            int base = unicode - 0x10000;
            surrogates[0] = (char)((base >>> 10) + HI_SURROGATE_START);
            surrogates[1] = (char)((base % 0x400) + LO_SURROGATE_START);
            cache.get(2, surrogates, glyphs, raw);
            return glyphs[0];
         } else {
             return charToGlyph((char) unicode, raw);
         }
    }

    public synchronized void charsToGlyphs(int count, char[] unicodes, int[] glyphs) {
        cache.get(count, unicodes, glyphs, false);
    }

    public synchronized void charsToGlyphs(int count, int[] unicodes, int[] glyphs) {
        for (int i = 0; i < count; i++) {
            glyphs[i] = charToGlyph(unicodes[i], false);
        }
    }

    // This mapper returns either the glyph code, or if the character can be
    // replaced on-the-fly using CoreText substitution; the negative unicode
    // value. If this "glyph code int" is treated as an opaque code, it will
    // strike and measure exactly as a real glyph code - whether the character
    // is present or not. Missing characters for any font on the system will
    // be returned as 0, as the getMissingGlyphCode() function above indicates.
    private static native void nativeCharsToGlyphs(final long nativeFontPtr,
                                                   int count, char[] unicodes,
                                                   int[] glyphs);

    private class Cache {
        private static final int FIRST_LAYER_SIZE = 256;
        private static final int SECOND_LAYER_SIZE = 16384; // 16384 = 128x128

        private final int[] firstLayerCache = new int[FIRST_LAYER_SIZE];
        private SparseBitShiftingTwoLayerArray secondLayerCache;
        private HashMap<Integer, Integer> generalCache;

        Cache() {
            // <rdar://problem/5331678> need to prevent getting '-1' stuck in the cache
            firstLayerCache[1] = 1;
        }

        public synchronized int get(final int index, final boolean raw) {
            if (isIgnorableWhitespace(index) || (isDefaultIgnorable(index) && !raw)) {
                return INVISIBLE_GLYPH_ID;
            }

            if (index < FIRST_LAYER_SIZE) {
                // catch common glyphcodes
                return firstLayerCache[index];
            }

            if (index < SECOND_LAYER_SIZE) {
                // catch common unicodes
                if (secondLayerCache == null) return 0;
                return secondLayerCache.get(index);
            }

            if (generalCache == null) return 0;
            final Integer value = generalCache.get(index);
            if (value == null) return 0;
            return value.intValue();
        }

        public synchronized void put(final int index, final int value) {
            if (index < FIRST_LAYER_SIZE) {
                // catch common glyphcodes
                firstLayerCache[index] = value;
                return;
            }

            if (index < SECOND_LAYER_SIZE) {
                // catch common unicodes
                if (secondLayerCache == null) {
                    secondLayerCache = new SparseBitShiftingTwoLayerArray(SECOND_LAYER_SIZE, 7); // 128x128
                }
                secondLayerCache.put(index, value);
                return;
            }

            if (generalCache == null) {
                generalCache = new HashMap<Integer, Integer>();
            }

            generalCache.put(index, value);
        }

        private class SparseBitShiftingTwoLayerArray {
            final int[][] cache;
            final int shift;
            final int secondLayerLength;

            public SparseBitShiftingTwoLayerArray(final int size,
                                                  final int shift)
            {
                this.shift = shift;
                this.cache = new int[1 << shift][];
                this.secondLayerLength = size >> shift;
            }

            public int get(final int index) {
                final int firstIndex = index >> shift;
                final int[] firstLayerRow = cache[firstIndex];
                if (firstLayerRow == null) return 0;
                return firstLayerRow[index - (firstIndex * (1 << shift))];
            }

            public void put(final int index, final int value) {
                final int firstIndex = index >> shift;
                int[] firstLayerRow = cache[firstIndex];
                if (firstLayerRow == null) {
                    cache[firstIndex] = firstLayerRow = new int[secondLayerLength];
                }
                firstLayerRow[index - (firstIndex * (1 << shift))] = value;
            }
        }

        public synchronized void get(int count, char[] indices, int[] values, boolean raw)
        {
            // "missed" is the count of 'char' that are not mapped.
            // Surrogates count for 2.
            // unmappedChars is the unique list of these chars.
            // unmappedCharIndices is the location in the original array
            int missed = 0;
            char[] unmappedChars = null;
            int [] unmappedCharIndices = null;

            for (int i = 0; i < count; i++){
                int code = indices[i];
                if (code >= HI_SURROGATE_START &&
                    code <= HI_SURROGATE_END && i < count - 1)
                {
                    char low = indices[i + 1];
                    if (low >= LO_SURROGATE_START && low <= LO_SURROGATE_END) {
                        code = (code - HI_SURROGATE_START) * 0x400 +
                            low - LO_SURROGATE_START + 0x10000;
                    }
                }

                final int value = get(code, raw);
                if (value != 0 && value != -1) {
                    values[i] = value;
                    if (code >= 0x10000) {
                        values[i+1] = INVISIBLE_GLYPH_ID;
                        i++;
                    }
                } else {
                    values[i] = 0;
                    put(code, -1);
                    if (unmappedChars == null) {
                        // This is likely to be longer than we need,
                        // but is the simplest and cheapest option.
                        unmappedChars = new char[indices.length];
                        unmappedCharIndices = new int[indices.length];
                    }
                    unmappedChars[missed] = indices[i];
                    unmappedCharIndices[missed] = i;
                    if (code >= 0x10000) { // was a surrogate pair
                        unmappedChars[++missed] = indices[++i];
                    }
                    missed++;
                }
            }

            if (missed == 0) {
                return;
            }

            final int[] glyphCodes = new int[missed];

            // bulk call to fill in the unmapped code points.
            nativeCharsToGlyphs(fFont.getNativeFontPtr(),
                                missed, unmappedChars, glyphCodes);

            for (int m = 0; m < missed; m++){
                int i = unmappedCharIndices[m];
                int code = unmappedChars[m];
                if (code >= HI_SURROGATE_START &&
                    code <= HI_SURROGATE_END && m < missed - 1)
                {
                    char low = unmappedChars[m + 1];
                    if (low >= LO_SURROGATE_START && low <= LO_SURROGATE_END) {
                        code = (code - HI_SURROGATE_START) * 0x400 +
                            low - LO_SURROGATE_START + 0x10000;
                    }
                }
               values[i] = glyphCodes[m];
               put(code, values[i]);
               if (code >= 0x10000) {
                   m++;
                   values[i + 1] = INVISIBLE_GLYPH_ID;
                }
            }
        }
    }
}
