/* GlyphLoader.java -- Helper for loading TrueType glyph outlines.
   Copyright (C) 2006 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package gnu.java.awt.font.opentype.truetype;

import java.awt.geom.AffineTransform;
import java.nio.ByteBuffer;


/**
 * A class for loading scaled and hinted glyph outlines.
 *
 * <p><b>Lack of Thread Safety:</b> Glyph loaders are intentionally
 * <i>not</i> safe to access from multiple concurrent
 * threads. Synchronization needs to be performed externally. Usually,
 * the font has already obtained a lock before calling the scaler,
 * which in turn calls the GlyphLoader. It would thus be wasteful to
 * acquire additional locks for the GlyphLoader.
 *
 * @author Sascha Brawer (brawer@dandelis.ch)
 */
final class GlyphLoader
{
  /**
   * A helper object for locating glyph data. GlyphLocator is an
   * abstract superclass, and there is a concretization for each glyph
   * location table ('loca') format.
   */
  private final GlyphLocator glyphLocator;


  /**
   * A helper object for measuring the advance width and height of a
   * glyph.
   */
  private final GlyphMeasurer glyphMeasurer;
  
  
  /**
   * The virtual machine for executing TrueType bytecodes.
   */
  private final VirtualMachine vm;


  /**
   * The number of font units in one em. A typical value is 2048,
   * but this depends on the font.
   */
  private final int unitsPerEm;

  private final int[] contourEndPoints;
  private final byte[] pointFlags;


  /**
   * Constructs a GlyphLoader.
   */
  GlyphLoader(GlyphLocator glyphLocator, VirtualMachine vm,
              int unitsPerEm, int maxContours, int maxPoints,
              GlyphMeasurer glyphMeasurer)
  {
    this.glyphLocator = glyphLocator;
    this.glyphMeasurer = glyphMeasurer;
    this.unitsPerEm = unitsPerEm;
    this.vm = vm;

    contourEndPoints = new int[maxContours];
    pointFlags = new byte[maxPoints];
  }


  /**
   * @param glyphIndex the number of the glyph whose outlines are to be
   * retrieved.
   */
  public void loadGlyph(int glyphIndex,
                        double pointSize,
                        AffineTransform transform,
                        boolean antialias,
                        Zone glyphZone)
  {
    glyphZone.setNumPoints(4);
    loadSubGlyph(glyphIndex, pointSize, transform, antialias, glyphZone,
                 0, 0);
  }


  private void loadSubGlyph(int glyphIndex,
                            double pointSize,
                            AffineTransform transform,
                            boolean antialias,
                            Zone glyphZone,
                            int preTranslateX,
                            int preTranslateY)
  {
    ByteBuffer glyph;
    int numContours;
    int xMin, yMin, xMax, yMax;
    byte flag;

    glyph = glyphLocator.getGlyphData(glyphIndex);

    if (glyph == null)
    {
      glyphZone.setNumPoints(4);
      setPhantomPoints(glyphIndex, 0, glyphZone);
      glyphZone.transform(pointSize, transform, unitsPerEm,
                          preTranslateX, preTranslateY);
      return;
    }

    numContours = glyph.getShort();
    xMin = glyph.getChar();
    yMin = glyph.getChar();
    xMax = glyph.getChar();
    yMax = glyph.getChar();
    

    if (numContours >= 0)
      loadSimpleGlyph(glyphIndex, pointSize, transform, antialias,
                      numContours, glyph, glyphZone,
                      preTranslateX, preTranslateY);
    else
      loadCompoundGlyph(glyphIndex, pointSize, transform, antialias,
                        glyph, glyphZone,
                        preTranslateX, preTranslateY);
  }


  private void loadSimpleGlyph(int glyphIndex,
                               double pointSize, AffineTransform transform,
                               boolean antialias,
                               int numContours, ByteBuffer glyph,
                               Zone glyphZone,
                               int preTranslateX, int preTranslateY)
  {
    int numPoints;
    int posInstructions, numInstructions;
    boolean execInstructions;

    execInstructions = vm.setup(pointSize, transform, antialias);

    /* Load the contour end points and determine the number of
     * points.
     */
    for (int i = 0; i < numContours; i++)
      contourEndPoints[i] = glyph.getChar();
    if (numContours > 0)
      numPoints = 1 + contourEndPoints[numContours - 1];
    else
      numPoints = 0;
    glyphZone.setNumPoints(numPoints + 4);

    numInstructions = glyph.getChar();
    posInstructions = glyph.position();
    glyph.position(posInstructions + numInstructions);
    loadFlags(numPoints, glyph);
    loadCoordinates(numPoints, glyph, glyphZone);
    for (int i = 0; i < numContours; i++)
      glyphZone.setContourEnd(contourEndPoints[i], true);

    setPhantomPoints(glyphIndex, numPoints, glyphZone);
    glyphZone.transform(pointSize, transform, unitsPerEm,
                        preTranslateX, preTranslateY);

    if (execInstructions)
    {
      // FIXME: Hint the glyph.
    }
  }


  private static final short ARGS_ARE_WORDS = 1;
  private static final short ARGS_ARE_XY_VALUES = 2;
  private static final short ROUND_XY_TO_GRID = 4;
  private static final short WE_HAVE_A_SCALE = 8;
  private static final short MORE_COMPONENTS = 32;
  private static final short WE_HAVE_AN_X_AND_Y_SCALE = 64;
  private static final short WE_HAVE_A_TWO_BY_TWO = 128;
  private static final short WE_HAVE_INSTRUCTIONS = 256;
  private static final short USE_MY_METRICS = 512;
  private static final short OVERLAP_COMPOUND = 1024;
  private static final short SCALED_COMPONENT_OFFSET = 2048;
  private static final short UNSCALED_COMPONENT_OFFSET = 4096;

  private void loadCompoundGlyph(int glyphIndex,
                                 double pointSize,
                                 AffineTransform transform,
                                 boolean antialias,
                                 ByteBuffer glyph,
                                 Zone glyphZone,
                                 int preTranslateX, int preTranslateY)
  {
    short flags;
    int subGlyphIndex;
    int metricsGlyphIndex;
    Zone subGlyphZone = new Zone(glyphZone.getCapacity());
    int arg1, arg2;
    double a, b, c, d, e, f;
    AffineTransform componentTransform = new AffineTransform();

    /* By default, use the metrics of the compound glyph. The default
     * is overridden if some component glyph has the USE_MY_METRICS
     * flag set.
     */
    metricsGlyphIndex = glyphIndex;

    do
    {
      flags = glyph.getShort();
      subGlyphIndex = glyph.getChar();

      if ((flags & USE_MY_METRICS) != 0)
        metricsGlyphIndex = subGlyphIndex;

      if ((flags & ARGS_ARE_WORDS) != 0)
      {
        arg1 = glyph.getShort();
        arg2 = glyph.getShort();
      }
      else
      {
        arg1 = glyph.get();
        arg2 = glyph.get();
      }

      if ((flags & WE_HAVE_A_SCALE) != 0)
      {
        a = d = getDouble214(glyph);
        b = c = 0.0; 
      }
      else if ((flags & WE_HAVE_AN_X_AND_Y_SCALE) != 0)
      {
        a = getDouble214(glyph);
        d = getDouble214(glyph);
        b = c = 0.0; 
      }
      else if ((flags & WE_HAVE_A_TWO_BY_TWO) != 0)
      {
        a = getDouble214(glyph);
        b = getDouble214(glyph);
        c = getDouble214(glyph);
        d = getDouble214(glyph);
      }
      else
      {
        a = d = 1.0;
        b = c = 0.0;
      }

      double m = Math.max(Math.abs(a), Math.abs(b));
      double n = Math.max(Math.abs(c), Math.abs(d));

      /* The Apple TrueType specification actually says that m is
       * multiplied by two if
       *
       *        abs(abs(a) - abs(c)) <= 33/65536,
       *
       * but this is probably a typo. On 2003-07-23, Sascha Brawer
       * wrote an e-mail message to applefonts@apple.com, asking
       * whether this might possibly be an error in the specification.
       */
      if (Math.abs(Math.abs(a) - Math.abs(b)) <= 33.0/65536.0)
        m = m * 2;

      if (Math.abs(Math.abs(c) - Math.abs(d)) <= 33.0/65536.0)
        n = n * 2;
      
      if ((flags & ARGS_ARE_XY_VALUES) != 0)
      {
        e = m * arg1;
        f = n * arg2;
      }
      else
        e = f = 0.0;

      componentTransform.setTransform(a, b, c, d, 0.0, 0.0);
      
      // System.out.println("componentTransform = " + componentTransform
      //   + ", e=" + e + ", f=" + f);
      componentTransform.concatenate(transform);

      int pos = glyph.position();
      int lim = glyph.limit();
      
      loadSubGlyph(subGlyphIndex, pointSize, componentTransform,
                   antialias, subGlyphZone,
                   Math.round((float) e + preTranslateX),
                   Math.round(-((float) f + preTranslateY)));
      glyphZone.combineWithSubGlyph(subGlyphZone, 4);
      glyph.limit(lim).position(pos);
    }
    while ((flags & MORE_COMPONENTS) != 0);

    setPhantomPoints(metricsGlyphIndex, glyphZone.getSize() - 4, glyphZone);
  }


  private double getDouble214(ByteBuffer buf)
  {
    return ((double) buf.getShort()) / (1 << 14);
  }


  /**
   * Loads the per-point flags of a glyph into the
   * <code>pointFlags</code> field.
   */
  private void loadFlags(int numPoints, ByteBuffer glyph)
  {
    byte flag;
    int numRepetitions;

    for (int i = 0; i < numPoints; i++)
    {
      pointFlags[i] = flag = glyph.get();
      if ((flag & 8) != 0)
      {
        numRepetitions = ((int) glyph.get()) & 0xff;
        while (numRepetitions > 0)
        {
          pointFlags[++i] = flag;
          --numRepetitions;
        }
      }
    }
  }


  private void loadCoordinates(int numPoints, ByteBuffer glyph,
                               Zone glyphZone)
  {
    int x, y;
    byte flag;

    x = 0;
    for (int i = 0; i < numPoints; i++)
    {
      flag = pointFlags[i];
      if ((flag & 2) == 0)
      {
        if ((flag & 16) == 0)
          x += glyph.getShort();
      }
      else
      {
        if ((flag & 16) != 0)
          x += (glyph.get() & 0xff);
        else
          x -= (glyph.get() & 0xff);
      }
      glyphZone.setOriginalX(i, x);
      glyphZone.setOnCurve(i, (flag & 1) == 1);
    }

    y = 0;
    for (int i = 0; i < numPoints; i++)
    {
      flag = pointFlags[i];
      if ((flag & 4) == 0)
      {
        if ((flag & 32) == 0)
          y += glyph.getShort();
      }
      else
      {
        if ((flag & 32) != 0)
          y += (glyph.get() & 0xff);
        else
          y -= (glyph.get() & 0xff);
      }
      glyphZone.setOriginalY(i, -y);
    }
  }


  private void setPhantomPoints(int glyphIndex, int numPoints,
                                Zone glyphZone)
  {
    /* Phantom point 0: Character origin. */
    glyphZone.setOriginalX(numPoints, 0);
    glyphZone.setOriginalY(numPoints, 0);

    /* Phantom point 1: Horizontal advance point. */
    glyphZone.setOriginalX(numPoints + 1,
                   glyphMeasurer.getAdvanceWidth(glyphIndex, true));
    glyphZone.setOriginalY(numPoints + 1,
                           glyphMeasurer.getAdvanceHeight(glyphIndex, true));
    
    /* Phantom point 2: Vertical origin. */
    int vertX = glyphMeasurer.getAscent(/* vertical */ false);
    int vertY = glyphMeasurer.getAscent(/* horizontal */ true);
    glyphZone.setOriginalX(numPoints + 2, vertX);
    glyphZone.setOriginalY(numPoints + 2, vertY);

    /* Phantom point 3: Vertical advance point. */
    glyphZone.setOriginalX(numPoints + 3,
                           vertX + glyphMeasurer.getAdvanceWidth(glyphIndex, false));
    glyphZone.setOriginalY(numPoints + 3,
                           vertY + glyphMeasurer.getAdvanceHeight(glyphIndex, false));
  }
}
