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

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