/* GdkGlyphVector.java -- Glyph vector object
   Copyright (C) 2003, 2004, 2005  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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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.peer.gtk;

import java.awt.Font;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphJustificationInfo;
import java.awt.font.GlyphMetrics;
import java.awt.font.GlyphVector;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

public class GdkGlyphVector extends GlyphVector
{

  /* We use a simple representation for glyph vectors here. Glyph i
   * consumes 8 doubles:
   *
   *      logical x: extents[ 10*i     ]
   *      logical y: extents[ 10*i + 1 ]
   *  logical width: extents[ 10*i + 2 ]
   * logical height: extents[ 10*i + 3 ]
   *
   *       visual x: extents[ 10*i + 4 ]
   *       visual y: extents[ 10*i + 5 ]
   *   visual width: extents[ 10*i + 6 ]
   *  visual height: extents[ 10*i + 7 ]
   *
   *   origin pos x: extents[ 10*i + 8 ]
   *   origin pos y: extents[ 10*i + 9 ]
   * 
   * as well as one int, code[i], representing the glyph code in the font.
   */

  double [] extents;
  int [] codes;

  Font font;
  FontRenderContext fontRenderContext;

  Rectangle2D allLogical;
  Rectangle2D allVisual;

  public GdkGlyphVector(double[] extents, int[] codes, Font font, FontRenderContext frc)
  {
    this.extents = extents;
    this.codes = codes;
    this.font = font;
    this.fontRenderContext = frc;

    allLogical = new Rectangle2D.Double();
    allVisual = new Rectangle2D.Double();
    
    for (int i = 0; i < codes.length; ++i)
      {
        allLogical.add (new Rectangle2D.Double(extents[10*i    ] + extents[10*i + 8],
                                               extents[10*i + 1] + extents[10*i + 9],
                                               extents[10*i + 2],
                                               extents[10*i + 3]));

        allVisual.add (new Rectangle2D.Double(extents[10*i + 4] + extents[10*i + 8],
                                              extents[10*i + 5] + extents[10*i + 9],
                                              extents[10*i + 6],
                                              extents[10*i + 7]));
      }
  }

  /* 
     geometric notes:

     the FRC contains a mapping from points -> pixels.

     typographics points are typically 1/72 of an inch.

     pixel displays are often around 72 dpi.

     so the FRC can get away with using an identity transform on a screen,
     often. behavior is documented by sun to fall back to an identity
     transform if the internal transformation is null.

     coordinates coming up from pango are expressed as floats -- in device
     space, so basically pixels-with-fractional-bits -- derived from their
     storage format in pango (1024ths of pixels). 

     it is not clear from the javadocs whether the results of methods like
     getGlyphPositions ought to return coordinates in device space, or
     "point" space, or what. for now I'm returning them in device space.
     
   */

  public double[] getExtents() 
  {
    return extents;
  }

  public int[] getCodes()
  {
    return codes;
  }

  public Font getFont () 
  { 
    return font; 
  }

  public FontRenderContext getFontRenderContext () 
  { 
    return fontRenderContext; 
  }

  public int getGlyphCharIndex (int glyphIndex) 
  { 
    // FIXME: currently pango does not provide glyph-by-glyph
    // reverse mapping information, so we assume a broken 1:1
    // glyph model here. This is plainly wrong.
    return glyphIndex;
  }

  public int[] getGlyphCharIndices (int beginGlyphIndex, 
                                    int numEntries,
                                    int[] codeReturn)
  {
    int ix[] = codeReturn;
    if (ix == null)
      ix = new int[numEntries];

    for (int i = 0; i < numEntries; i++)
      ix[i] = getGlyphCharIndex (beginGlyphIndex + i);
    return ix;
  }

  public int getGlyphCode (int glyphIndex) 
  { 
    return codes[glyphIndex];
  }

  public int[] getGlyphCodes (int beginGlyphIndex, int numEntries,
                              int[] codeReturn)
  {
    if (codeReturn == null)
      codeReturn = new int[numEntries];

    System.arraycopy(codes, beginGlyphIndex, codeReturn, 0, numEntries);
    return codeReturn;
  }

  public Shape getGlyphLogicalBounds (int i)
  {
    return new Rectangle2D.Double (extents[8*i], extents[8*i + 1],
                                   extents[8*i + 2], extents[8*i + 3]);
  }
    
  public GlyphMetrics getGlyphMetrics (int i)
  {
    // FIXME: pango does not yield vertical layout information at the
    // moment.

    boolean is_horizontal = true;
    double advanceX = extents[8*i + 2]; // "logical width" == advanceX 
    double advanceY = 0; 
   
    return new GlyphMetrics (is_horizontal, 
                             (float) advanceX, (float) advanceY, 
                             (Rectangle2D) getGlyphVisualBounds(i), 
                             GlyphMetrics.STANDARD);
  }

  public Shape getGlyphOutline (int glyphIndex)
  {
    throw new UnsupportedOperationException ();      
  }

  public Shape getGlyphOutline (int glyphIndex, float x, float y)
  {
    throw new UnsupportedOperationException ();
  }

  public Rectangle getGlyphPixelBounds (int i, 
                                        FontRenderContext renderFRC,
                                        float x, float y)
  {
    return new Rectangle((int) x, (int) y,
                         (int) extents[8*i + 6], (int) extents[8*i + 7]);
  }
    
  public Point2D getGlyphPosition (int i)
  {
    return new Point2D.Double (extents[10*i + 8], 
                               extents[10*i + 9]);
  }

  public float[] getGlyphPositions (int beginGlyphIndex,
                                    int numEntries,
                                    float[] positionReturn)
  {
    float fx[] = positionReturn;
    if (fx == null)
      fx = new float[numEntries * 2];

    for (int i = 0; i < numEntries; ++i)
      {
        fx[2*i    ] = (float) extents[10*i + 8];
        fx[2*i + 1] = (float) extents[10*i + 9];
      }
    return fx;
  }

  public AffineTransform getGlyphTransform (int glyphIndex)
  {
    // Glyphs don't have independent transforms in these simple glyph
    // vectors; docs specify null is an ok return here.
    return null;  
  }
    
  public Shape getGlyphVisualBounds (int i)
  {
    return new Rectangle2D.Double(extents[8*i + 4], extents[8*i + 5],
                                  extents[8*i + 6], extents[8*i + 7]);
  }
    
  public int getLayoutFlags ()
  {
    return 0;
  }

  public Rectangle2D getLogicalBounds ()
  {
    return allLogical;
  }

  public int getNumGlyphs ()
  {
    return codes.length;
  }

  public Shape getOutline ()
  {
    throw new UnsupportedOperationException ();      
  }

  public Rectangle getPixelBounds (FontRenderContext renderFRC,
                                   float x, float y)
  {
    return new Rectangle((int)x, 
                         (int)y, 
                         (int) allVisual.getWidth(),
                         (int) allVisual.getHeight());
  }
    
  public Rectangle2D getVisualBounds ()
  {
    return allVisual;
  }

  public void performDefaultLayout ()
  {
  }
    
  public void setGlyphPosition (int i, Point2D newPos)
  {
    extents[8*i    ] = newPos.getX();
    extents[8*i + 1] = newPos.getY();

    extents[8*i + 4] = newPos.getX();
    extents[8*i + 5] = newPos.getY();
  }

  public void setGlyphTransform (int glyphIndex,
                                 AffineTransform newTX)
  {
    // not yet.. maybe not ever?
    throw new UnsupportedOperationException ();      
  }

  public boolean equals(GlyphVector gv)
  {
    if (gv == null)
      return false;

    if (! (gv instanceof GdkGlyphVector))
      return false;

    GdkGlyphVector ggv = (GdkGlyphVector) gv;

    if ((ggv.codes.length != this.codes.length)
        || (ggv.extents.length != this.extents.length))
      return false;
    
    if ((ggv.font == null && this.font != null)
        || (ggv.font != null && this.font == null)
        || (!ggv.font.equals(this.font)))
      return false;

    if ((ggv.fontRenderContext == null && this.fontRenderContext != null)
        || (ggv.fontRenderContext != null && this.fontRenderContext == null)
        || (!ggv.fontRenderContext.equals(this.fontRenderContext)))
      return false;

    for (int i = 0; i < ggv.codes.length; ++i)
      if (ggv.codes[i] != this.codes[i])
        return false;

    for (int i = 0; i < ggv.extents.length; ++i)
      if (ggv.extents[i] != this.extents[i])
        return false;

    return true;
  }

  public GlyphJustificationInfo getGlyphJustificationInfo(int idx)
  {
    throw new UnsupportedOperationException ();      
  }

  public Shape getOutline(float x, float y)    
  {
    throw new UnsupportedOperationException ();      
  }

}
