/*
 * 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.awt.Font;

/* Remind: need to enhance to extend component list with a fallback
 * list, which is not used in metrics or queries on the composite, but
 * is used in drawing primitives and queries which supply an actual string.
 * ie for a codepoint that is only in a fallback, font-wide queries such
 * as FontMetrics.getHeight() will not take it into account.
 * But getStringBounds(..) would take it into account.
 * Its fuzzier for queries such as "canDisplay". If this does not include
 * the fallback, then we probably want to add "canDisplayFallback()"
 * But its probably OK to include it so long as only composites include
 * fallbacks. If physicals do then it would be really confusing ..
 */
public final class CompositeFont extends Font2D {

    private boolean[] deferredInitialisation;
    String[] componentFileNames;
    String[] componentNames;
    /* because components can be lazily initialised the components field is
     * private, to ensure all clients call getSlotFont()
     */
    private PhysicalFont[] components;
    int numSlots;
    int numMetricsSlots;
    int[] exclusionRanges;
    int[] maxIndices;
    int numGlyphs = 0;
    int localeSlot = -1; // primary slot for this locale.

    /* See isStdComposite() for when/how this is used */
    boolean isStdComposite = true;

    public CompositeFont(String name, String[] compFileNames,
                         String[] compNames, int metricsSlotCnt,
                         int[] exclRanges, int[] maxIndexes,
                         boolean defer, SunFontManager fm) {

        handle = new Font2DHandle(this);
        fullName = name;
        componentFileNames = compFileNames;
        componentNames = compNames;
        if (compNames == null) {
            numSlots = componentFileNames.length;
        } else {
            numSlots = componentNames.length;
        }
        /* We will limit the number of slots to 254.
         * We store the slot for a glyph id in a byte and we may use one slot
         * for an EUDC font, and we may also create a composite
         * using this composite as a backup for a physical font.
         * So we want to leave space for the two additional slots.
         */
         numSlots = (numSlots <= 254) ? numSlots : 254;

        /* Only the first "numMetricsSlots" slots are used for font metrics.
         * the rest are considered "fallback" slots".
         */
        numMetricsSlots = metricsSlotCnt;
        exclusionRanges = exclRanges;
        maxIndices = maxIndexes;

        /*
         * See if this is a windows locale which has a system EUDC font.
         * If so add it as the final fallback component of the composite.
         * The caller could be responsible for this, but for now it seems
         * better that it is handled internally to the CompositeFont class.
         */
        if (fm.getEUDCFont() != null) {
            numSlots++;
            if (componentNames != null) {
                componentNames = new String[numSlots];
                System.arraycopy(compNames, 0, componentNames, 0, numSlots-1);
                componentNames[numSlots-1] =
                    fm.getEUDCFont().getFontName(null);
            }
            if (componentFileNames != null) {
                componentFileNames = new String[numSlots];
                System.arraycopy(compFileNames, 0,
                                  componentFileNames, 0, numSlots-1);
            }
            components = new PhysicalFont[numSlots];
            components[numSlots-1] = fm.getEUDCFont();
            deferredInitialisation = new boolean[numSlots];
            if (defer) {
                for (int i=0; i<numSlots-1; i++) {
                    deferredInitialisation[i] = true;
                }
            }
        } else {
            components = new PhysicalFont[numSlots];
            deferredInitialisation = new boolean[numSlots];
            if (defer) {
                for (int i=0; i<numSlots; i++) {
                    deferredInitialisation[i] = true;
                }
            }
        }

        fontRank = Font2D.FONT_CONFIG_RANK;

        int index = fullName.indexOf('.');
        if (index>0) {
            familyName = fullName.substring(0, index);
            /* composites don't call setStyle() as parsing the style
             * takes place at the same time as parsing the family name.
             * Do I really have to parse the style from the name?
             * Need to look into having the caller provide this. */
            if (index+1 < fullName.length()) {
                String styleStr = fullName.substring(index+1);
                if ("plain".equals(styleStr)) {
                    style = Font.PLAIN;
                } else if ("bold".equals(styleStr)) {
                    style = Font.BOLD;
                } else if ("italic".equals(styleStr)) {
                    style = Font.ITALIC;
                } else if ("bolditalic".equals(styleStr)) {
                    style = Font.BOLD | Font.ITALIC;
                }
            }
        } else {
            familyName = fullName;
        }
    }

    /* This method is currently intended to be called only from
     * FontManager.getCompositeFontUIResource(Font)
     * It creates a new CompositeFont with the contents of the Physical
     * one pre-pended as slot 0.
     */
    CompositeFont(PhysicalFont physFont, CompositeFont compFont) {

        isStdComposite = false;
        handle = new Font2DHandle(this);
        fullName = physFont.fullName;
        familyName = physFont.familyName;
        style = physFont.style;

        numMetricsSlots = 1; /* Only the physical Font */
        numSlots = compFont.numSlots+1;

        /* Ugly though it is, we synchronize here on the FontManager class
         * because it is the lock used to do deferred initialisation.
         * We need to ensure that the arrays have consistent information.
         * But it may be possible to dispense with the synchronisation if
         * it is harmless that we do not know a slot is already initialised
         * and just need to discover that and mark it so.
         */
        synchronized (FontManagerFactory.getInstance()) {
            components = new PhysicalFont[numSlots];
            components[0] = physFont;
            System.arraycopy(compFont.components, 0,
                             components, 1, compFont.numSlots);

            if (compFont.componentNames != null) {
                componentNames = new String[numSlots];
                componentNames[0] = physFont.fullName;
                System.arraycopy(compFont.componentNames, 0,
                                 componentNames, 1, compFont.numSlots);
            }
            if (compFont.componentFileNames != null) {
                componentFileNames = new String[numSlots];
                componentFileNames[0] = null;
                System.arraycopy(compFont.componentFileNames, 0,
                                  componentFileNames, 1, compFont.numSlots);
            }
            deferredInitialisation = new boolean[numSlots];
            deferredInitialisation[0] = false;
            System.arraycopy(compFont.deferredInitialisation, 0,
                             deferredInitialisation, 1, compFont.numSlots);
        }
    }

    /* This is used for deferred initialisation, so that the components of
     * a logical font are initialised only when the font is used.
     * This can have a positive impact on start-up of most UI applications.
     * Note that this technique cannot be used with a TTC font as it
     * doesn't know which font in the collection is needed. The solution to
     * this is that the initialisation checks if the returned font is
     * really the one it wants by comparing the name against the name that
     * was passed in (if none was passed in then you aren't using a TTC
     * as you would have to specify the name in such a case).
     * Assuming there's only two or three fonts in a collection then it
     * may be sufficient to verify the returned name is the expected one.
     * But half the time it won't be. However since initialisation of the
     * TTC will initialise all its components then just do a findFont2D call
     * to locate the right one.
     * This code allows for initialisation of each slot on demand.
     * There are two issues with this.
     * 1) All metrics slots probably may be initialised anyway as many
     * apps will query the overall font metrics. However this is not an
     * absolute requirement
     * 2) Some font configuration files on Solaris reference two versions
     * of a TT font: a Latin-1 version, then a Pan-European version.
     * One from /usr/openwin/lib/X11/fonts/TrueType, the other from
     * a euro_fonts directory which is symlinked from numerous locations.
     * This is difficult to avoid because the two do not share XLFDs so
     * both will be consequently mapped by separate XLFDs needed by AWT.
     * The difficulty this presents for lazy initialisation is that if
     * all the components are not mapped at once, the smaller version may
     * have been used only to be replaced later, and what is the consequence
     * for a client that displayed the contents of this font already.
     * After some thought I think this will not be a problem because when
     * client tries to display a glyph only in the Euro font, the composite
     * will ask all components of this font for that glyph and will get
     * the euro one. Subsequent uses will all come from the 100% compatible
     * euro one.
     */
    private void doDeferredInitialisation(int slot) {
        if (deferredInitialisation[slot] == false) {
            return;
        }

        /* Synchronize on FontManager so that is the global lock
         * to update its static set of deferred fonts.
         * This global lock is rarely likely to be an issue as there
         * are only going to be a few calls into this code.
         */
        SunFontManager fm = SunFontManager.getInstance();
        synchronized (fm) {
            if (componentNames == null) {
                componentNames = new String[numSlots];
            }
            if (components[slot] == null) {
                /* Warning: it is possible that the returned component is
                 * not derived from the file name argument, this can happen if:
                 * - the file can't be found
                 * - the file has a bad font
                 * - the font in the file is superseded by a more complete one
                 * This should not be a problem for composite font as it will
                 * make no further use of this file, but code debuggers/
                 * maintainers need to be conscious of this possibility.
                 */
                if (componentFileNames != null &&
                    componentFileNames[slot] != null) {
                    components[slot] =
                        fm.initialiseDeferredFont(componentFileNames[slot]);
                }

                if (components[slot] == null) {
                    components[slot] = fm.getDefaultPhysicalFont();
                }
                String name = components[slot].getFontName(null);
                if (componentNames[slot] == null) {
                    componentNames[slot] = name;
                } else if (!componentNames[slot].equalsIgnoreCase(name)) {
                    components[slot] =
                        (PhysicalFont) fm.findFont2D(componentNames[slot],
                                                     style,
                                                FontManager.PHYSICAL_FALLBACK);
                }
            }
            deferredInitialisation[slot] = false;
        }
    }

    /* To called only by FontManager.replaceFont */
    void replaceComponentFont(PhysicalFont oldFont, PhysicalFont newFont) {
        if (components == null) {
            return;
        }
        for (int slot=0; slot<numSlots; slot++) {
            if (components[slot] == oldFont) {
                components[slot] = newFont;
                if (componentNames != null) {
                    componentNames[slot] = newFont.getFontName(null);
                }
            }
        }
    }

    public boolean isExcludedChar(int slot, int charcode) {

        if (exclusionRanges == null || maxIndices == null ||
            slot >= numMetricsSlots) {
            return false;
        }

        int minIndex = 0;
        int maxIndex = maxIndices[slot];
        if (slot > 0) {
            minIndex = maxIndices[slot - 1];
        }
        int curIndex = minIndex;
        while (maxIndex > curIndex) {
            if ((charcode >= exclusionRanges[curIndex])
                && (charcode <= exclusionRanges[curIndex+1])) {
                return true;      // excluded
            }
            curIndex += 2;
        }
        return false;
    }

    public void getStyleMetrics(float pointSize, float[] metrics, int offset) {
        PhysicalFont font = getSlotFont(0);
        if (font == null) { // possible?
            super.getStyleMetrics(pointSize, metrics, offset);
        } else {
            font.getStyleMetrics(pointSize, metrics, offset);
        }
    }

    public int getNumSlots() {
        return numSlots;
    }

    public PhysicalFont getSlotFont(int slot) {
        /* This is essentially the runtime overhead for deferred font
         * initialisation: a boolean test on obtaining a slot font,
         * which will happen per slot, on initialisation of a strike
         * (as that is the only frequent call site of this method.
         */
        if (deferredInitialisation[slot]) {
            doDeferredInitialisation(slot);
        }
        SunFontManager fm = SunFontManager.getInstance();
        try {
            PhysicalFont font = components[slot];
            if (font == null) {
                try {
                    font = (PhysicalFont) fm.
                        findFont2D(componentNames[slot], style,
                                   FontManager.PHYSICAL_FALLBACK);
                    components[slot] = font;
                } catch (ClassCastException cce) {
                    font = fm.getDefaultPhysicalFont();
                }
            }
            return font;
        } catch (Exception e) {
            return fm.getDefaultPhysicalFont();
        }
    }

    FontStrike createStrike(FontStrikeDesc desc) {
        return new CompositeStrike(this, desc);
    }

    /* This is set false when the composite is created using a specified
     * physical font as the first slot and called by code which
     * selects composites by locale preferences to know that this
     * isn't a font which should be adjusted.
     */
    public boolean isStdComposite() {
        return isStdComposite;
    }

    /* This isn't very efficient but its infrequently used.
     * StandardGlyphVector uses it when the client assigns the glyph codes.
     * These may not be valid. This validates them substituting the missing
     * glyph elsewhere.
     */
    protected int getValidatedGlyphCode(int glyphCode) {
        int slot = glyphCode >>> 24;
        if (slot >= numSlots) {
            return getMapper().getMissingGlyphCode();
        }

        int slotglyphCode = glyphCode & CompositeStrike.SLOTMASK;
        PhysicalFont slotFont = getSlotFont(slot);
        if (slotFont.getValidatedGlyphCode(slotglyphCode) ==
            slotFont.getMissingGlyphCode()) {
            return getMapper().getMissingGlyphCode();
        } else {
            return glyphCode;
        }
    }

    public CharToGlyphMapper getMapper() {
        if (mapper == null) {
            mapper = new CompositeGlyphMapper(this);
        }
        return mapper;
    }

    public boolean hasSupplementaryChars() {
        for (int i=0; i<numSlots; i++) {
            if (getSlotFont(i).hasSupplementaryChars()) {
                return true;
            }
        }
        return false;
    }

    public int getNumGlyphs() {
        if (numGlyphs == 0) {
            numGlyphs = getMapper().getNumGlyphs();
        }
        return numGlyphs;
    }

    public int getMissingGlyphCode() {
        return getMapper().getMissingGlyphCode();
    }

    public boolean canDisplay(char c) {
        return getMapper().canDisplay(c);
    }

    public boolean useAAForPtSize(int ptsize) {
        /* Find the first slot that supports the default encoding and use
         * that to decide the "gasp" behaviour of the composite font.
         * REMIND "default encoding" isn't applicable to a Unicode locale
         * and we need to replace this with a better mechanism for deciding
         * if a font "supports" the user's language. See TrueTypeFont.java
         */
        if (localeSlot == -1) {
            /* Ordinarily check numMetricsSlots, but non-standard composites
             * set that to "1" whilst not necessarily supporting the default
             * encoding with that first slot. In such a case check all slots.
             */
            int numCoreSlots = numMetricsSlots;
            if (numCoreSlots == 1 && !isStdComposite()) {
                numCoreSlots = numSlots;
            }
            for (int slot=0; slot<numCoreSlots; slot++) {
                 if (getSlotFont(slot).supportsEncoding(null)) {
                     localeSlot = slot;
                     break;
                 }
            }
            if (localeSlot == -1) {
                localeSlot = 0;
            }
        }
        return getSlotFont(localeSlot).useAAForPtSize(ptsize);
    }

    public String toString() {
        String ls = (String)java.security.AccessController.doPrivileged(
                new sun.security.action.GetPropertyAction("line.separator"));
        String componentsStr = "";
        for (int i=0; i<numSlots; i++) {
            componentsStr += "    Slot["+i+"]="+getSlotFont(i)+ls;
        }
        return "** Composite Font: Family=" + familyName +
            " Name=" + fullName + " style=" + style + ls + componentsStr;
    }
}
