/*
 * Copyright (c) 2000, 2011, 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.java2d.pipe;

import java.awt.Font;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.TextLayout;

import sun.awt.SunHints;
import sun.java2d.SunGraphics2D;
import sun.java2d.SurfaceData;
import sun.font.GlyphList;
import sun.java2d.loops.FontInfo;

/**
 * A delegate pipe of SG2D for drawing text.
 */

public abstract class GlyphListPipe implements TextPipe {

    public void drawString(SunGraphics2D sg2d, String s,
                           double x, double y)
    {
        FontInfo info = sg2d.getFontInfo();
        if (info.pixelHeight > OutlineTextRenderer.THRESHHOLD) {
            SurfaceData.outlineTextRenderer.drawString(sg2d, s, x, y);
            return;
        }

        float devx, devy;
        if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
            double origin[] = {x + info.originX, y + info.originY};
            sg2d.transform.transform(origin, 0, origin, 0, 1);
            devx = (float)origin[0];
            devy = (float)origin[1];
        } else {
            devx = (float)(x + info.originX + sg2d.transX);
            devy = (float)(y + info.originY + sg2d.transY);
        }
        /* setFromString returns false if shaping is needed, and we then back
         * off to a TextLayout. Such text may benefit slightly from a lower
         * overhead in this approach over the approach in previous releases.
         */
        GlyphList gl = GlyphList.getInstance();
        if (gl.setFromString(info, s, devx, devy)) {
            drawGlyphList(sg2d, gl);
            gl.dispose();
        } else {
            gl.dispose(); // release this asap.
            TextLayout tl = new TextLayout(s, sg2d.getFont(),
                                           sg2d.getFontRenderContext());
            tl.draw(sg2d, (float)x, (float)y);
        }
    }

    public void drawChars(SunGraphics2D sg2d,
                          char data[], int offset, int length,
                          int ix, int iy)
    {
        FontInfo info = sg2d.getFontInfo();
        float x, y;
        if (info.pixelHeight > OutlineTextRenderer.THRESHHOLD) {
            SurfaceData.outlineTextRenderer.drawChars(
                                        sg2d, data, offset, length, ix, iy);
            return;
        }
        if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
            double origin[] = {ix + info.originX, iy + info.originY};
            sg2d.transform.transform(origin, 0, origin, 0, 1);
            x = (float) origin[0];
            y = (float) origin[1];
        } else {
            x = ix + info.originX + sg2d.transX;
            y = iy + info.originY + sg2d.transY;
        }
        GlyphList gl = GlyphList.getInstance();
        if (gl.setFromChars(info, data, offset, length, x, y)) {
            drawGlyphList(sg2d, gl);
            gl.dispose();
        } else {
            gl.dispose(); // release this asap.
            TextLayout tl = new TextLayout(new String(data, offset, length),
                                           sg2d.getFont(),
                                           sg2d.getFontRenderContext());
            tl.draw(sg2d, ix, iy);

        }
    }

    public void drawGlyphVector(SunGraphics2D sg2d, GlyphVector gv,
                                float x, float y)
    {
        FontRenderContext frc = gv.getFontRenderContext();
        FontInfo info = sg2d.getGVFontInfo(gv.getFont(), frc);
        if (info.pixelHeight > OutlineTextRenderer.THRESHHOLD) {
            SurfaceData.outlineTextRenderer.drawGlyphVector(sg2d, gv, x, y);
            return;
        }
        if (sg2d.transformState >= SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
            double origin[] = {x, y};
            sg2d.transform.transform(origin, 0, origin, 0, 1);
            x = (float) origin[0];
            y = (float) origin[1];
        } else {
            x += sg2d.transX; // don't use the glyph info origin, already in gv.
            y += sg2d.transY;
        }

        GlyphList gl = GlyphList.getInstance();
        gl.setFromGlyphVector(info, gv, x, y);
        drawGlyphList(sg2d, gl, info.aaHint);
        gl.dispose();
    }

    protected abstract void drawGlyphList(SunGraphics2D sg2d, GlyphList gl);

    protected void drawGlyphList(SunGraphics2D sg2d, GlyphList gl,
                                 int aaHint) {
        drawGlyphList(sg2d, gl);
    }
}
