/*
 * Copyright 2000-2006 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package sun.font;

import java.awt.Font;
import java.awt.font.GlyphVector;
import java.awt.font.FontRenderContext;
import sun.java2d.loops.FontInfo;

/*
 * This class represents a list of actual renderable glyphs.
 * It can be constructed from a number of text sources, representing
 * the various ways in which a programmer can ask a Graphics2D object
 * to render some text.  Once constructed, it provides a way of iterating
 * through the device metrics and graybits of the individual glyphs that
 * need to be rendered to the screen.
 *
 * Note that this class holds pointers to native data which must be
 * disposed.  It is not marked as finalizable since it is intended
 * to be very lightweight and finalization is a comparitively expensive
 * procedure.  The caller must specifically use try{} finally{} to
 * manually ensure that the object is disposed after use, otherwise
 * native data structures might be leaked.
 *
 * Here is a code sample for using this class:
 *
 * public void drawString(String str, FontInfo info, float x, float y) {
 *     GlyphList gl = GlyphList.getInstance();
 *     try {
 *         gl.setFromString(info, str, x, y);
 *         int strbounds[] = gl.getBounds();
 *         int numglyphs = gl.getNumGlyphs();
 *         for (int i = 0; i < numglyphs; i++) {
 *             gl.setGlyphIndex(i);
 *             int metrics[] = gl.getMetrics();
 *             byte bits[] = gl.getGrayBits();
 *             int glyphx = metrics[0];
 *             int glyphy = metrics[1];
 *             int glyphw = metrics[2];
 *             int glyphh = metrics[3];
 *             int off = 0;
 *             for (int j = 0; j < glyphh; j++) {
 *                 for (int i = 0; i < glyphw; i++) {
 *                     int dx = glyphx + i;
 *                     int dy = glyphy + j;
 *                     int alpha = bits[off++];
 *                     drawPixel(alpha, dx, dy);
 *                 }
 *             }
 *         }
 *     } finally {
 *         gl.dispose();
 *     }
 * }
 */
public final class GlyphList {
    private static final int MINGRAYLENGTH = 1024;
    private static final int MAXGRAYLENGTH = 8192;
    private static final int DEFAULT_LENGTH = 32;

    int glyphindex;
    int metrics[];
    byte graybits[];

    /* A reference to the strike is needed for the case when the GlyphList
     * may be added to a queue for batch processing, (e.g. OpenGL) and we need
     * to be completely certain that the strike is still valid when the glyphs
     * images are later referenced.  This does mean that if such code discards
     * GlyphList and places only the data it contains on the queue, that the
     * strike needs to be part of that data held by a strong reference.
     * In the cases of drawString() and drawChars(), this is a single strike,
     * although it may be a composite strike.  In the case of
     * drawGlyphVector() it may be a single strike, or a list of strikes.
     */
    Object strikelist; // hold multiple strikes during rendering of complex gv

    /* In normal usage, the same GlyphList will get recycled, so
     * it makes sense to allocate arrays that will get reused along with
     * it, rather than generating garbage. Garbage will be generated only
     * in MP envts where multiple threads are executing. Throughput should
     * still be higher in those cases.
     */
    int len = 0;
    int maxLen = 0;
    int maxPosLen = 0;
    int glyphData[];
    char chData[];
    long images[];
    float positions[];
    float x, y;
    float gposx, gposy;
    boolean usePositions;

    /* lcdRGBOrder is used only by LCD text rendering. Its here because
     * the Graphics may have a different hint value than the one used
     * by a GlyphVector, so it has to be stored here - and is obtained
     * from the right FontInfo. Another approach would have been to have
     * install a separate pipe for that case but that's a lot of extra
     * code when a simple boolean will suffice. The overhead to non-LCD
     * text is a redundant boolean assign per call.
     */
    boolean lcdRGBOrder;

    /*
     * lcdSubPixPos is used only by LCD text rendering. Its here because
     * the Graphics may have a different hint value than the one used
     * by a GlyphVector, so it has to be stored here - and is obtained
     * from the right FontInfo. Its also needed by the code which
     * calculates glyph positions which already needs to access this
     * GlyphList and would otherwise need the FontInfo.
     * This is true only if LCD text and fractional metrics hints
     * are selected on the graphics.
     * When this is true and the glyph positions as determined by the
     * advances are non-integral, it requests adjustment of the positions.
     * Setting this for surfaces which do not support it through accelerated
     * loops may cause a slow-down as software loops are invoked instead.
     */
    boolean lcdSubPixPos;

    /* This scheme creates a singleton GlyphList which is checked out
     * for use. Callers who find its checked out create one that after use
     * is discarded. This means that in a MT-rendering environment,
     * there's no need to synchronise except for that one instance.
     * Fewer threads will then need to synchronise, perhaps helping
     * throughput on a MP system. If for some reason the reusable
     * GlyphList is checked out for a long time (or never returned?) then
     * we would end up always creating new ones. That situation should not
     * occur and if if did, it would just lead to some extra garbage being
     * created.
     */
    private static GlyphList reusableGL = new GlyphList();
    private static boolean inUse;


    void ensureCapacity(int len) {
      /* Note len must not be -ve! only setFromChars should be capable
       * of passing down a -ve len, and this guards against it.
       */
        if (len < 0) {
          len = 0;
        }
        if (usePositions && len > maxPosLen) {
            positions = new float[len * 2 + 2];
            maxPosLen = len;
        }

        if (maxLen == 0 || len > maxLen) {
            glyphData = new int[len];
            chData = new char[len];
            images = new long[len];
            maxLen = len;
        }
    }

    private GlyphList() {
//         ensureCapacity(DEFAULT_LENGTH);
    }

//     private GlyphList(int arraylen) {
//          ensureCapacity(arraylen);
//     }

    public static GlyphList getInstance() {
        /* The following heuristic is that if the reusable instance is
         * in use, it probably still will be in a micro-second, so avoid
         * synchronising on the class and just allocate a new instance.
         * The cost is one extra boolean test for the normal case, and some
         * small number of cases where we allocate an extra object when
         * in fact the reusable one would be freed very soon.
         */
        if (inUse) {
            return new GlyphList();
        } else {
            synchronized(GlyphList.class) {
                if (inUse) {
                    return new GlyphList();
                } else {
                    inUse = true;
                    return reusableGL;
                }
            }
        }
    }

    /* In some cases the caller may be able to estimate the size of
     * array needed, and it will usually be long enough. This avoids
     * the unnecessary reallocation that occurs if our default
     * values are too small. This is useful because this object
     * will be discarded so the re-allocation overhead is high.
     */
//     public static GlyphList getInstance(int sz) {
//      if (inUse) {
//          return new GlyphList(sz);
//      } else {
//          synchronized(GlyphList.class) {
//              if (inUse) {
//                  return new GlyphList();
//              } else {
//                  inUse = true;
//                  return reusableGL;
//              }
//          }
//      }
//     }

    /* GlyphList is in an invalid state until setFrom* method is called.
     * After obtaining a new GlyphList it is the caller's responsibility
     * that one of these methods is executed before handing off the
     * GlyphList
     */

    public boolean setFromString(FontInfo info, String str, float x, float y) {
        this.x = x;
        this.y = y;
        this.strikelist = info.fontStrike;
        this.lcdRGBOrder = info.lcdRGBOrder;
        this.lcdSubPixPos = info.lcdSubPixPos;
        len = str.length();
        ensureCapacity(len);
        str.getChars(0, len, chData, 0);
        return mapChars(info, len);
    }

    public boolean setFromChars(FontInfo info, char[] chars, int off, int alen,
                                float x, float y) {
        this.x = x;
        this.y = y;
        this.strikelist = info.fontStrike;
        this.lcdRGBOrder = info.lcdRGBOrder;
        this.lcdSubPixPos = info.lcdSubPixPos;
        len = alen;
        if (alen < 0) {
            len = 0;
        } else {
            len = alen;
        }
        ensureCapacity(len);
        System.arraycopy(chars, off, chData, 0, len);
        return mapChars(info, len);
    }

    private final boolean mapChars(FontInfo info, int len) {
        /* REMIND.Is it worthwhile for the iteration to convert
         * chars to glyph ids to directly map to images?
         */
        if (info.font2D.getMapper().charsToGlyphsNS(len, chData, glyphData)) {
            return false;
        }
        info.fontStrike.getGlyphImagePtrs(glyphData, images, len);
        glyphindex = -1;
        return true;
    }


    public void setFromGlyphVector(FontInfo info, GlyphVector gv,
                                   float x, float y) {
        this.x = x;
        this.y = y;
        this.lcdRGBOrder = info.lcdRGBOrder;
        this.lcdSubPixPos = info.lcdSubPixPos;
        /* A GV may be rendered in different Graphics. It is possible it is
         * used for one case where LCD text is available, and another where
         * it is not. Pass in the "info". to ensure get a suitable one.
         */
        StandardGlyphVector sgv = StandardGlyphVector.getStandardGV(gv, info);
        // call before ensureCapacity :-
        usePositions = sgv.needsPositions(info.devTx);
        len = sgv.getNumGlyphs();
        ensureCapacity(len);
        strikelist = sgv.setupGlyphImages(images,
                                          usePositions ? positions : null,
                                          info.devTx);
        glyphindex = -1;
    }

    public int[] getBounds() {
        /* We co-opt the 5 element array that holds per glyph metrics in order
         * to return the bounds. So a caller must copy the data out of the
         * array before calling any other methods on this GlyphList
         */
        if (glyphindex >= 0) {
            throw new InternalError("calling getBounds after setGlyphIndex");
        }
        if (metrics == null) {
            metrics = new int[5];
        }
        /* gposx and gposy are used to accumulate the advance.
         * Add 0.5f for consistent rounding to pixel position. */
        gposx = x + 0.5f;
        gposy = y + 0.5f;
        fillBounds(metrics);
        return metrics;
    }

    /* This method now assumes "state", so must be called 0->len
     * The metrics it returns are accumulated on the fly
     * So it could be renamed "nextGlyph()".
     * Note that a laid out GlyphVector which has assigned glyph positions
     * doesn't have this stricture..
     */
    public void setGlyphIndex(int i) {
        glyphindex = i;
        float gx =
            StrikeCache.unsafe.getFloat(images[i]+StrikeCache.topLeftXOffset);
        float gy =
            StrikeCache.unsafe.getFloat(images[i]+StrikeCache.topLeftYOffset);

        if (usePositions) {
            metrics[0] = (int)Math.floor(positions[(i<<1)]   + gposx + gx);
            metrics[1] = (int)Math.floor(positions[(i<<1)+1] + gposy + gy);
        } else {
            metrics[0] = (int)Math.floor(gposx + gx);
            metrics[1] = (int)Math.floor(gposy + gy);
            /* gposx and gposy are used to accumulate the advance */
            gposx += StrikeCache.unsafe.getFloat
                (images[i]+StrikeCache.xAdvanceOffset);
            gposy += StrikeCache.unsafe.getFloat
                (images[i]+StrikeCache.yAdvanceOffset);
        }
        metrics[2] =
            StrikeCache.unsafe.getChar(images[i]+StrikeCache.widthOffset);
        metrics[3] =
            StrikeCache.unsafe.getChar(images[i]+StrikeCache.heightOffset);
        metrics[4] =
            StrikeCache.unsafe.getChar(images[i]+StrikeCache.rowBytesOffset);
    }

    public int[] getMetrics() {
        return metrics;
    }

    public byte[] getGrayBits() {
        int len = metrics[4] * metrics[3];
        if (graybits == null) {
            graybits = new byte[Math.max(len, MINGRAYLENGTH)];
        } else {
            if (len > graybits.length) {
                graybits = new byte[len];
            }
        }
        long pixelDataAddress;
        if (StrikeCache.nativeAddressSize == 4) {
            pixelDataAddress = 0xffffffff &
                StrikeCache.unsafe.getInt(images[glyphindex] +
                                          StrikeCache.pixelDataOffset);
        } else {
            pixelDataAddress =
            StrikeCache.unsafe.getLong(images[glyphindex] +
                                       StrikeCache.pixelDataOffset);
        }
        if (pixelDataAddress == 0L) {
            return graybits;
        }
        /* unsafe is supposed to be fast, but I doubt if this loop can beat
         * a native call which does a getPrimitiveArrayCritical and a
         * memcpy for the typical amount of image data (30-150 bytes)
         * Consider a native method if there is a performance problem (which
         * I haven't seen so far).
         */
        for (int i=0; i<len; i++) {
            graybits[i] = StrikeCache.unsafe.getByte(pixelDataAddress+i);
        }
        return graybits;
    }

    public long[] getImages() {
        return images;
    }

    public boolean usePositions() {
        return usePositions;
    }

    public float[] getPositions() {
        return positions;
    }

    public float getX() {
        return x;
    }

    public float getY() {
        return y;
    }

    public Object getStrike() {
        return strikelist;
    }

    public boolean isSubPixPos() {
        return lcdSubPixPos;
    }

    public boolean isRGBOrder() {
        return lcdRGBOrder;
    }

    /* There's a reference equality test overhead here, but it allows us
     * to avoid synchronizing for GL's that will just be GC'd. This
     * helps MP throughput.
     */
    public void dispose() {
        if (this == reusableGL) {
            if (graybits != null && graybits.length > MAXGRAYLENGTH) {
                graybits = null;
            }
            usePositions = false;
            strikelist = null; // remove reference to the strike list
            inUse = false;
        }
    }

    /* The value here is for use by the rendering engine as it reflects
     * the number of glyphs in the array to be blitted. Surrogates pairs
     * may have two slots (the second of these being a dummy entry of the
     * invisible glyph), whereas an application client would expect only
     * one glyph. In other words don't propagate this value up to client code.
     *
     * {dlf} an application client should have _no_ expectations about the
     * number of glyphs per char.  This ultimately depends on the font
     * technology and layout process used, which in general clients will
     * know nothing about.
     */
    public int getNumGlyphs() {
        return len;
    }

    /* We re-do all this work as we iterate through the glyphs
     * but it seems unavoidable without re-working the Java TextRenderers.
     */
    private void fillBounds(int[] bounds) {
        /* Faster to access local variables in the for loop? */
        int xOffset = StrikeCache.topLeftXOffset;
        int yOffset = StrikeCache.topLeftYOffset;
        int wOffset = StrikeCache.widthOffset;
        int hOffset = StrikeCache.heightOffset;
        int xAdvOffset = StrikeCache.xAdvanceOffset;
        int yAdvOffset = StrikeCache.yAdvanceOffset;

        if (len == 0) {
            bounds[0] = bounds[1] = bounds[2] = bounds[3] = 0;
            return;
        }
        float bx0, by0, bx1, by1;
        bx0 = by0 = Float.POSITIVE_INFINITY;
        bx1 = by1 = Float.NEGATIVE_INFINITY;

        int posIndex = 0;
        float glx = x + 0.5f;
        float gly = y + 0.5f;
        char gw, gh;
        float gx, gy, gx0, gy0, gx1, gy1;
        for (int i=0; i<len; i++) {
            gx = StrikeCache.unsafe.getFloat(images[i]+xOffset);
            gy = StrikeCache.unsafe.getFloat(images[i]+yOffset);
            gw = StrikeCache.unsafe.getChar(images[i]+wOffset);
            gh = StrikeCache.unsafe.getChar(images[i]+hOffset);

            if (usePositions) {
                gx0 = positions[posIndex++] + gx + glx;
                gy0 = positions[posIndex++] + gy + gly;
            } else {
                gx0 = glx + gx;
                gy0 = gly + gy;
                glx += StrikeCache.unsafe.getFloat(images[i]+xAdvOffset);
                gly += StrikeCache.unsafe.getFloat(images[i]+yAdvOffset);
            }
            gx1 = gx0 + gw;
            gy1 = gy0 + gh;
            if (bx0 > gx0) bx0 = gx0;
            if (by0 > gy0) by0 = gy0;
            if (bx1 < gx1) bx1 = gx1;
            if (by1 < gy1) by1 = gy1;
        }
        /* floor is safe and correct because all glyph widths, heights
         * and offsets are integers
         */
        bounds[0] = (int)Math.floor(bx0);
        bounds[1] = (int)Math.floor(by0);
        bounds[2] = (int)Math.floor(bx1);
        bounds[3] = (int)Math.floor(by1);
    }
}
