/*
 * Copyright (c) 2003, 2006, 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.util.Locale;

public class TrueTypeGlyphMapper extends CharToGlyphMapper {

    static final char REVERSE_SOLIDUS = 0x005c; // the backslash char.
    static final char JA_YEN = 0x00a5;
    static final char JA_FULLWIDTH_TILDE_CHAR = 0xff5e;
    static final char JA_WAVE_DASH_CHAR = 0x301c;

    /* if running on Solaris and default Locale is ja_JP then
     * we map need to remap reverse solidus (backslash) to Yen as
     * apparently expected there.
     */
    static final boolean isJAlocale = Locale.JAPAN.equals(Locale.getDefault());
    private final boolean needsJAremapping;
    private boolean remapJAWaveDash;

    TrueTypeFont font;
    CMap cmap;
    int numGlyphs;

    public TrueTypeGlyphMapper(TrueTypeFont font) {
        this.font = font;
        try {
            cmap = CMap.initialize(font);
        } catch (Exception e) {
            cmap = null;
        }
        if (cmap == null) {
            handleBadCMAP();
        }
        missingGlyph = 0; /* standard for TrueType fonts */
        ByteBuffer buffer = font.getTableBuffer(TrueTypeFont.maxpTag);
        numGlyphs = buffer.getChar(4); // offset 4 bytes in MAXP table.
        if (FontUtilities.isSolaris && isJAlocale && font.supportsJA()) {
            needsJAremapping = true;
            if (FontUtilities.isSolaris8 &&
                getGlyphFromCMAP(JA_WAVE_DASH_CHAR) == missingGlyph) {
                remapJAWaveDash = true;
            }
        } else {
            needsJAremapping = false;
        }
    }

    public int getNumGlyphs() {
        return numGlyphs;
    }

    private char getGlyphFromCMAP(int charCode) {
        try {
            char glyphCode = cmap.getGlyph(charCode);
            if (glyphCode < numGlyphs ||
                glyphCode >= FileFontStrike.INVISIBLE_GLYPHS) {
                return glyphCode;
            } else {
                if (FontUtilities.isLogging()) {
                    FontUtilities.getLogger().warning
                        (font + " out of range glyph id=" +
                         Integer.toHexString((int)glyphCode) +
                         " for char " + Integer.toHexString(charCode));
                }
                return (char)missingGlyph;
            }
        } catch(Exception e) {
            handleBadCMAP();
            return (char) missingGlyph;
        }
    }

    private void handleBadCMAP() {
        if (FontUtilities.isLogging()) {
            FontUtilities.getLogger().severe("Null Cmap for " + font +
                                      "substituting for this font");
        }
        SunFontManager.getInstance().deRegisterBadFont(font);
        /* The next line is not really a solution, but might
         * reduce the exceptions until references to this font2D
         * are gone.
         */
        cmap = CMap.theNullCmap;
    }

    private final char remapJAChar(char unicode) {
        switch (unicode) {
        case REVERSE_SOLIDUS:
            return JA_YEN;
            /* This is a workaround for bug 4533422.
             * Japanese wave dash missing from Solaris JA TrueType fonts.
             */
        case JA_WAVE_DASH_CHAR:
            if (remapJAWaveDash) {
                return JA_FULLWIDTH_TILDE_CHAR;
            }
        default: return unicode;
        }
    }
    private final int remapJAIntChar(int unicode) {
        switch (unicode) {
        case REVERSE_SOLIDUS:
            return JA_YEN;
            /* This is a workaround for bug 4533422.
             * Japanese wave dash missing from Solaris JA TrueType fonts.
             */
        case JA_WAVE_DASH_CHAR:
            if (remapJAWaveDash) {
                return JA_FULLWIDTH_TILDE_CHAR;
            }
        default: return unicode;
        }
    }

    public int charToGlyph(char unicode) {
        if (needsJAremapping) {
            unicode = remapJAChar(unicode);
        }
        int glyph = getGlyphFromCMAP(unicode);
        if (font.checkUseNatives() && glyph < font.glyphToCharMap.length) {
            font.glyphToCharMap[glyph] = unicode;
        }
        return glyph;
    }

    public int charToGlyph(int unicode) {
        if (needsJAremapping) {
            unicode = remapJAIntChar(unicode);
        }
        int glyph = getGlyphFromCMAP(unicode);
        if (font.checkUseNatives() && glyph < font.glyphToCharMap.length) {
            font.glyphToCharMap[glyph] = (char)unicode;
        }
        return glyph;
    }

    public void charsToGlyphs(int count, int[] unicodes, int[] glyphs) {
        for (int i=0;i<count;i++) {
            if (needsJAremapping) {
                glyphs[i] = getGlyphFromCMAP(remapJAIntChar(unicodes[i]));
            } else {
                glyphs[i] = getGlyphFromCMAP(unicodes[i]);
            }
            if (font.checkUseNatives() &&
                glyphs[i] < font.glyphToCharMap.length) {
                font.glyphToCharMap[glyphs[i]] = (char)unicodes[i];
            }
        }
    }

    public void charsToGlyphs(int count, char[] unicodes, int[] glyphs) {

        for (int i=0; i<count; i++) {
            int code;
            if (needsJAremapping) {
                code = remapJAChar(unicodes[i]);
            } else {
                code = unicodes[i]; // char is unsigned.
            }

            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] = getGlyphFromCMAP(code);
                    i += 1; // Empty glyph slot after surrogate
                    glyphs[i] = INVISIBLE_GLYPH_ID;
                    continue;
                }
            }
            glyphs[i] = getGlyphFromCMAP(code);

            if (font.checkUseNatives() &&
                glyphs[i] < font.glyphToCharMap.length) {
                font.glyphToCharMap[glyphs[i]] = (char)code;
            }

        }
    }

    /* This variant checks if shaping is needed and immediately
     * returns true if it does. A caller of this method should be expecting
     * to check the return type because it needs to know how to handle
     * the character data for display.
     */
    public boolean charsToGlyphsNS(int count, char[] unicodes, int[] glyphs) {

        for (int i=0; i<count; i++) {
            int code;
            if (needsJAremapping) {
                code = remapJAChar(unicodes[i]);
            } else {
                code = unicodes[i]; // char is unsigned.
            }

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

            glyphs[i] = getGlyphFromCMAP(code);
            if (font.checkUseNatives() &&
                glyphs[i] < font.glyphToCharMap.length) {
                font.glyphToCharMap[glyphs[i]] = (char)code;
            }

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

    /* A pretty good heuristic is that the cmap we are using
     * supports 32 bit character codes.
     */
    boolean hasSupplementaryChars() {
        return
            cmap instanceof CMap.CMapFormat8 ||
            cmap instanceof CMap.CMapFormat10 ||
            cmap instanceof CMap.CMapFormat12;
    }
}
