2003-11-17 Graydon Hoare <graydon@redhat.com>
authorgraydon <graydon@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 20 Nov 2003 22:44:01 +0000 (22:44 +0000)
committergraydon <graydon@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 20 Nov 2003 22:44:01 +0000 (22:44 +0000)
* gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.java: New file.
* gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java
(GdkFontLineMetrics): New inner class.
(getLineMetrics): Return new GdkFontLineMetrics.
(getFontMetrics): Return new GdkClasspathFontPeerMetrics.
(layoutGlyphVector): Create GdkGlyphVector.
* gnu/java/awt/peer/gtk/GdkGraphics2D.java (stateStack): New member.
(GdkGraphics2D): Initialize state via mathod calls.
(cairoSetMatrix, cairoShowGlyphs): Simplify native calls.
(cairoTranslate, cairoScale, cairoRotate): Remove.
(various methods): use setTransform for special transform cases.
(DrawState): New inner class.
(stateSave): New method.
(stateRestore): New method.
(various methods): use stateSave, stateRestore.
(getClipInDevSpace): New method.
(clip, clipRect, setClip, getClip, getClipBounds):
Follow spec more closely.
(getTransform): Return clone of transform.
(setStroke): Set linewidth to passed width / 2.0.
(setPaintMode): Set SrcOver rather than Xor.
(setColor): Set paint to passed color.
(drawRaster, drawImage, PainterThread, drawPixels): Take affine
transform from image to user space.
(drawRenderedImage, drawRenderableImage): Implement.
(getFontRenderContext, getFontMetrics, drawString, getFont):
Implement
(drawArc, drawOval, drawRoundRect, fillArc, fillOval, fillRoundRect):
Implement.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c:
Match changes to java side.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c:
Release resources.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c:
Don't use pango for metrics.
* jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c:
New file.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@73776 138bc75d-0d04-0410-961f-82ee72b054a4

libjava/ChangeLog
libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java
libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.java [new file with mode: 0644]
libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java
libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c
libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c [new file with mode: 0644]
libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c
libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c

index 98cc75e..7bbf92b 100644 (file)
@@ -1,3 +1,43 @@
+2003-11-17  Graydon Hoare  <graydon@redhat.com>
+
+       * gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.java: New file.
+       * gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java 
+       (GdkFontLineMetrics): New inner class.
+       (getLineMetrics): Return new GdkFontLineMetrics.
+       (getFontMetrics): Return new GdkClasspathFontPeerMetrics.
+       (layoutGlyphVector): Create GdkGlyphVector.
+       * gnu/java/awt/peer/gtk/GdkGraphics2D.java (stateStack): New member.
+       (GdkGraphics2D): Initialize state via mathod calls.
+       (cairoSetMatrix, cairoShowGlyphs): Simplify native calls.
+       (cairoTranslate, cairoScale, cairoRotate): Remove.
+       (various methods): use setTransform for special transform cases.
+       (DrawState): New inner class.
+       (stateSave): New method.
+       (stateRestore): New method.
+       (various methods): use stateSave, stateRestore.
+       (getClipInDevSpace): New method.
+       (clip, clipRect, setClip, getClip, getClipBounds): 
+       Follow spec more closely.
+       (getTransform): Return clone of transform.
+       (setStroke): Set linewidth to passed width / 2.0.
+       (setPaintMode): Set SrcOver rather than Xor.
+       (setColor): Set paint to passed color.
+       (drawRaster, drawImage, PainterThread, drawPixels): Take affine
+       transform from image to user space.
+       (drawRenderedImage, drawRenderableImage): Implement.
+       (getFontRenderContext, getFontMetrics, drawString, getFont): 
+       Implement
+       (drawArc, drawOval, drawRoundRect, fillArc, fillOval, fillRoundRect): 
+       Implement.
+       * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c: 
+       Match changes to java side.
+       * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c: 
+       Release resources.
+       * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c: 
+       Don't use pango for metrics.
+       * jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c: 
+       New file.
+
 2003-11-19  Guilhem Lavaux <guilhem@kaffe.org>
            Jim Pick  <jim@kaffe.org>
 
index 7e31700..ca26289 100644 (file)
@@ -49,6 +49,7 @@ import java.util.Map;
 import java.util.StringTokenizer;
 import java.text.CharacterIterator;
 import java.text.AttributedCharacterIterator;
+import java.text.StringCharacterIterator;
 import java.awt.font.TextAttribute;
 import gnu.classpath.Configuration;
 import gnu.java.awt.peer.ClasspathFontPeer;
@@ -180,10 +181,56 @@ public class GdkClasspathFontPeer extends ClasspathFontPeer
     throw new UnsupportedOperationException ();
   }
 
+  protected class GdkFontLineMetrics extends LineMetrics
+  {
+    FontMetrics fm;
+    int nchars; 
+
+    public GdkFontLineMetrics (FontMetrics m, int n)
+    {
+      fm = m;
+      nchars = n;
+    }
+
+    public float getAscent()
+    {
+      return (float) fm.getAscent ();
+    }
+  
+    public int getBaselineIndex()
+    {
+      return Font.ROMAN_BASELINE;
+    }
+    
+    public float[] getBaselineOffsets()
+    {
+      return new float[3];
+    }
+    
+    public float getDescent()
+    {
+      return (float) fm.getDescent ();
+    }
+    
+    public float getHeight()
+    {
+      return (float) fm.getHeight ();
+    }
+    
+    public float getLeading() { return 0.f; }    
+    public int getNumChars() { return nchars; }
+    public float getStrikethroughOffset() { return 0.f; }    
+    public float getStrikethroughThickness() { return 0.f; }  
+    public float getUnderlineOffset() { return 0.f; }
+    public float getUnderlineThickness() { return 0.f; }
+
+  }
+
+
   public LineMetrics getLineMetrics (Font font, CharacterIterator ci, 
                                      int begin, int limit, FontRenderContext rc)
   {
-    throw new UnsupportedOperationException ();
+    return new GdkFontLineMetrics (getFontMetrics (font), limit - begin);
   }
 
   public Rectangle2D getMaxCharBounds (Font font, FontRenderContext rc)
@@ -214,25 +261,32 @@ public class GdkClasspathFontPeer extends ClasspathFontPeer
 
   public boolean hasUniformLineMetrics (Font font)
   {
-    throw new UnsupportedOperationException ();
+    return true;
   }
 
   public GlyphVector layoutGlyphVector (Font font, FontRenderContext frc, 
                                         char[] chars, int start, int limit, 
                                         int flags)
   {
-    throw new UnsupportedOperationException ();  
+    int nchars = (limit - start) + 1;
+    char[] nc = new char[nchars];
+
+    for (int i = 0; i < nchars; ++i)
+      nc[i] = chars[start + i];
+
+    return createGlyphVector (font, frc, 
+                              new StringCharacterIterator (new String (nc)));
   }
 
   public LineMetrics getLineMetrics (Font font, String str, 
                                      FontRenderContext frc)
   {
-    throw new UnsupportedOperationException();
+    return new GdkFontLineMetrics (getFontMetrics (font), str.length ());
   }
 
   public FontMetrics getFontMetrics (Font font)
   {
-    throw new UnsupportedOperationException();
+    return new GdkClasspathFontPeerMetrics (font);
   }
 
 }
diff --git a/libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.java b/libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.java
new file mode 100644 (file)
index 0000000..2f019e4
--- /dev/null
@@ -0,0 +1,116 @@
+/* GdkClasspathFontPeerMetrics.java
+   Copyright (C) 1999, 2002 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.*;
+import java.awt.font.*;
+import java.awt.geom.*;
+
+public class GdkClasspathFontPeerMetrics extends FontMetrics
+{
+  private final int native_state = GtkGenericPeer.getUniqueInteger();
+
+  private static final int ASCENT = 0, MAX_ASCENT = 1, 
+                       DESCENT = 2, MAX_DESCENT = 3, 
+                       MAX_ADVANCE = 4;
+
+  private int[] metrics;
+  private native int[] initState (Object font);
+
+  public GdkClasspathFontPeerMetrics (Font font)
+  {
+    super (font);
+    metrics = initState (font.getPeer());
+  }
+
+  public int stringWidth (String str)
+  {
+    GlyphVector gv = font.createGlyphVector 
+      (new FontRenderContext 
+       (new AffineTransform (), false, false), str);
+    Rectangle2D r = gv.getVisualBounds ();
+    return (int) r.getWidth ();
+  }
+
+  public int charWidth (char ch)
+  {
+    return stringWidth (new String (new char[] { ch }));
+  }
+
+  public int charsWidth (char data[], int off, int len)
+  {
+    return stringWidth (new String (data, off, len));
+  }
+
+  /* 
+     Sun's Motif implementation always returns 0 or 1 here (???), but
+     going by the X11 man pages, it seems as though we should return
+     font.ascent + font.descent.
+  */
+  public int getLeading ()
+  {
+    return 1;
+//      return metrics[ASCENT] + metrics[DESCENT];
+  }
+
+  public int getAscent ()
+  {
+    return metrics[ASCENT];
+  }
+
+  public int getMaxAscent ()
+  {
+    return metrics[MAX_ASCENT];
+  }
+
+  public int getDescent ()
+  {
+    return metrics[DESCENT];
+  }
+
+  public int getMaxDescent ()
+  {
+    return metrics[MAX_DESCENT];
+  }
+
+  public int getMaxAdvance ()
+  {
+    return metrics[MAX_ADVANCE];
+  }
+}
index 7adb307..036e40f 100644 (file)
@@ -47,6 +47,7 @@ import java.awt.image.renderable.*;
 
 import java.text.AttributedCharacterIterator;
 import java.util.Map;
+import java.util.Stack;
 import java.lang.Integer;
 import gnu.java.awt.ClasspathToolkit;
 import gnu.java.awt.peer.ClasspathFontPeer;
@@ -78,6 +79,8 @@ public class GdkGraphics2D extends Graphics2D
   private AffineTransform transform;
   private GtkComponentPeer component;
   private Font font;  
+
+  private Stack stateStack;
   
   native private int[] initState (GtkComponentPeer component);
   native private void initState (int width, int height);
@@ -122,33 +125,50 @@ public class GdkGraphics2D extends Graphics2D
       clip = new Rectangle (g.getClipBounds ());
 
     if (g.transform == null)
-      transform = null;
+      transform = AffineTransform.getTranslateInstance (0.5, 0.5);
     else
       transform = new AffineTransform (g.transform);
 
+    font = g.font;
     component = g.component;
     copyState (g);
 
     setColor (fg);
+    setBackground (bg);
+    setPaint (paint);
+    setStroke (stroke);
     setClip (clip);
     setTransform (transform);
+    stateStack = new Stack();
   }
 
   GdkGraphics2D (int width, int height)
   {
     initState (width, height);
-    bg = Color.black;
-    fg = Color.black;
-    transform = new AffineTransform ();
+
+    setColor(Color.black);
+    setBackground (Color.black);
+    setPaint (getColor());
+    setFont (new Font("SansSerif", Font.PLAIN, 12));
+    setTransform (AffineTransform.getTranslateInstance (0.5, 0.5));
+    setStroke (new BasicStroke ());
+
+    stateStack = new Stack();
   }
 
   GdkGraphics2D (GtkComponentPeer component)
   {
     this.component = component;
     int rgb[] = initState (component);
-    fg = new Color (rgb[0], rgb[1], rgb[2]);
-    bg = new Color (rgb[3], rgb[4], rgb[5]);
-    transform = new AffineTransform ();
+
+    setColor (new Color (rgb[0], rgb[1], rgb[2]));
+    setBackground (new Color (rgb[3], rgb[4], rgb[5]));
+    setPaint (getColor());
+    setFont (new Font("SansSerif", Font.PLAIN, 12));
+    setTransform (AffineTransform.getTranslateInstance (0.5, 0.5));
+    setStroke (new BasicStroke ());
+
+    stateStack = new Stack ();
   }
 
 
@@ -160,7 +180,7 @@ public class GdkGraphics2D extends Graphics2D
   private native void gdkDrawDrawable (GdkGraphics2D other, int x, int y);
 
   // drawing utility methods
-  private native void drawPixels (int pixels[], int w, int h, int stride);
+  private native void drawPixels (int pixels[], int w, int h, int stride, double i2u[]);
   private native void setTexturePixels (int pixels[], int w, int h, int stride);
   private native void setGradient (double x1, double y1,
                                    double x2, double y2,
@@ -171,13 +191,10 @@ public class GdkGraphics2D extends Graphics2D
   // simple passthroughs to cairo
   private native void cairoSave ();
   private native void cairoRestore ();
-  private native void cairoSetMatrix (double m00, double m10, 
-                                      double m01, double m11,
-                                      double m02, double m12);
+  private native void cairoSetMatrix (double m[]);
   private native void cairoSetFont (GdkClasspathFontPeer peer);
   private native void cairoShowGlyphs (int codes[],
-                                       float positions[],
-                                       int nglyphs);
+                                       float positions[]);
   private native void cairoSetOperator (int cairoOperator);
   private native void cairoSetRGBColor (double red, double green, double blue);
   private native void cairoSetAlpha (double alpha);
@@ -187,20 +204,17 @@ public class GdkGraphics2D extends Graphics2D
   private native void cairoSetLineJoin (int cairoLineJoin);
   private native void cairoSetDash (double dashes[], int ndash, double offset);
   private native void cairoSetMiterLimit (double limit);
-  private native void cairoTranslate (double tx, double ty);
-  private native void cairoScale (double sx, double sy);
-  private native void cairoRotate (double angle);
   private native void cairoNewPath ();
   private native void cairoMoveTo (double x, double y);
   private native void cairoLineTo (double x, double y);
   private native void cairoCurveTo (double x1, double y1,
-                                 double x2, double y2,
-                                 double x3, double y3);  
+                                    double x2, double y2,
+                                    double x3, double y3);  
   private native void cairoRelMoveTo (double dx, double dy);
   private native void cairoRelLineTo (double dx, double dy);
   private native void cairoRelCurveTo (double dx1, double dy1,
-                                    double dx2, double dy2,
-                                    double dx3, double dy3);
+                                       double dx2, double dy2,
+                                       double dx3, double dy3);
   private native void cairoRectangle (double x, double y, 
                                    double width, double height);
   private native void cairoClosePath ();
@@ -213,6 +227,51 @@ public class GdkGraphics2D extends Graphics2D
   ////// General Drawing Support Methods //////
   /////////////////////////////////////////////
 
+    private class DrawState
+    {
+       private Paint paint;
+       private Stroke stroke;
+       private Color fg;
+       private Color bg;
+       private Shape clip;
+       private AffineTransform transform;
+       private Font font;  
+       DrawState (GdkGraphics2D g)
+       {
+           this.paint = g.paint;
+           this.stroke = g.stroke;
+           this.fg = g.fg;
+           this.bg = g.bg;
+           this.clip = g.clip;
+           if (g.transform != null)
+               this.transform = (AffineTransform) g.transform.clone();
+           this.font = g.font;
+       }
+       public void restore(GdkGraphics2D g)
+       {
+           g.paint = this.paint;
+           g.stroke = this.stroke;
+           g.fg = this.fg;
+           g.bg = this.bg;
+           g.clip = this.clip;
+           g.transform = this.transform;
+           g.font = this.font;
+       }
+    }
+    
+    private void stateSave ()
+    {
+       stateStack.push (new DrawState (this));
+       cairoSave ();
+    }
+
+    private void stateRestore ()
+    {
+       ((DrawState)(stateStack.pop ())).restore (this);
+       cairoRestore ();
+    }
+
+
   double x;
   double y;
   private void setPos (double nx, double ny)
@@ -288,7 +347,7 @@ public class GdkGraphics2D extends Graphics2D
         return;
       }
 
-    cairoSave ();
+    stateSave ();
     cairoNewPath ();
     if (s instanceof Rectangle2D)
       {
@@ -298,12 +357,12 @@ public class GdkGraphics2D extends Graphics2D
     else      
       walkPath (s.getPathIterator (null));
     cairoStroke ();
-    cairoRestore ();
+    stateRestore ();
   }
 
-  public void fill(Shape s)
+  public void fill (Shape s)
   {
-    cairoSave();
+    stateSave();
     cairoNewPath ();
     if (s instanceof Rectangle2D)
       {
@@ -313,23 +372,40 @@ public class GdkGraphics2D extends Graphics2D
     else      
       walkPath (s.getPathIterator (null));
     cairoFill ();
-    cairoRestore ();
+    stateRestore ();
   }
 
   public void clip (Shape s)
   {
-    clip = s;
-    cairoNewPath ();
-    if (s instanceof Rectangle2D)
-      {
-        Rectangle2D r = (Rectangle2D)s;
-        cairoRectangle (r.getX (), r.getY (), 
-                        r.getWidth (), r.getHeight ());
-      }
-    else      
-      walkPath (s.getPathIterator (null));
-    cairoClosePath ();
-    cairoClip ();
+      // update it
+
+      if (clip == null || s == null)
+         clip = s;
+      else if (s instanceof Rectangle2D
+              && clip instanceof Rectangle2D)
+         {
+             Rectangle2D r = (Rectangle2D)s;
+             Rectangle2D curr = (Rectangle2D)clip;
+             clip = curr.createIntersection (r);
+         }
+      else
+         throw new UnsupportedOperationException ();
+
+      // draw it
+      if (clip != null)
+         {
+             cairoNewPath ();
+             if (clip instanceof Rectangle2D)
+                 {
+                     Rectangle2D r = (Rectangle2D)clip;
+                     cairoRectangle (r.getX (), r.getY (), 
+                                     r.getWidth (), r.getHeight ());
+                 }
+             else
+                 walkPath (clip.getPathIterator (null));
+             cairoClosePath ();
+             cairoClip ();
+         }
   }
 
   public Paint getPaint ()
@@ -339,11 +415,14 @@ public class GdkGraphics2D extends Graphics2D
 
   public AffineTransform getTransform ()
   {
-    return transform;
+      return (AffineTransform) transform.clone ();
   }
 
   public void setPaint (Paint p)
   {
+    if (paint == null)
+        return;
+      
     paint = p;
     if (paint instanceof Color)
       {
@@ -385,7 +464,7 @@ public class GdkGraphics2D extends Graphics2D
       {
         double m[] = new double[6];
         transform.getMatrix (m);
-        cairoSetMatrix (m[0], m[1], m[2], m[3], m[4], m[5]);
+        cairoSetMatrix (m);
       }
   }
 
@@ -400,32 +479,22 @@ public class GdkGraphics2D extends Graphics2D
 
   public void rotate(double theta)
   {
-    if (transform != null)
-      transform.rotate (theta);
-    cairoRotate (theta);
+    transform (AffineTransform.getRotateInstance (theta));
   }
 
   public void rotate(double theta, double x, double y)
   {
-    if (transform != null)
-      transform.rotate (theta, x, y);
-    cairoTranslate (x, y);
-    cairoRotate (theta);
-    cairoTranslate (-x, -y);
+    transform (AffineTransform.getRotateInstance (theta, x, y));
   }
 
   public void scale(double sx, double sy)
   {
-    if (transform != null)
-      transform.scale (sx, sy);
-    cairoScale (sx, sy);
+    transform (AffineTransform.getScaleInstance (sx, sy));
   }
 
   public void translate (double tx, double ty)
   {
-    if (transform != null)
-      transform.translate (tx, ty);
-    cairoTranslate (tx, ty);
+    transform (AffineTransform.getTranslateInstance (tx, ty));
   }
 
   public void translate (int x, int y)
@@ -433,6 +502,11 @@ public class GdkGraphics2D extends Graphics2D
     translate ((double) x, (double) y);
   }
 
+  public void shear(double shearX, double shearY)
+  {
+    transform (AffineTransform.getShearInstance (shearX, shearY));
+  }
+
   public Stroke getStroke()
   {
     return stroke;
@@ -445,7 +519,7 @@ public class GdkGraphics2D extends Graphics2D
       {
         BasicStroke bs = (BasicStroke) stroke;
         cairoSetLineCap (bs.getEndCap());
-        cairoSetLineWidth (bs.getLineWidth());
+        cairoSetLineWidth (bs.getLineWidth() / 2.0);
         cairoSetLineJoin (bs.getLineJoin());
         cairoSetMiterLimit (bs.getMiterLimit());
         float dashes[] = bs.getDashArray();
@@ -467,7 +541,7 @@ public class GdkGraphics2D extends Graphics2D
 
   public void setPaintMode () 
   { 
-    setComposite (java.awt.AlphaComposite.Xor); 
+    setComposite (java.awt.AlphaComposite.SrcOver); 
   }
 
   public void setXORMode (Color c) 
@@ -478,6 +552,7 @@ public class GdkGraphics2D extends Graphics2D
   public void setColor (Color c)
   {
     fg = c;
+    paint = c;
     cairoSetRGBColor (fg.getRed() / 255.0, 
                       fg.getGreen() / 255.0, 
                       fg.getBlue() / 255.0);
@@ -491,29 +566,12 @@ public class GdkGraphics2D extends Graphics2D
 
   public void clipRect (int x, int y, int width, int height)
   {
-    // this is *slightly* different than all the other clip functions: it
-    // intersects the clip area with the new clip rectangle. obviously.  of
-    // course, since Shape doesn't *have* any way of intersecting with a
-    // rectangle, we will promote the current clipping region to its
-    // bounding rectangle and then intersect with that.
-    if (clip == null)
-      {
-        cairoNewPath ();
-        cairoRectangle (x, y, width, height);
-        cairoClosePath ();
-        cairoClip ();
-        clip = new Rectangle (x, y, width, height);
-      }
-    else
-      {
-        clip (clip.getBounds ().intersection 
-              (new Rectangle (x, y, width, height)));
-      }
+      clip (new Rectangle (x, y, width, height));
   }
 
   public Shape getClip ()
   {
-    return clip;
+    return getClipInDevSpace ();
   }
 
   public Rectangle getClipBounds ()
@@ -524,13 +582,32 @@ public class GdkGraphics2D extends Graphics2D
       return clip.getBounds ();
   }
 
+    protected Rectangle2D getClipInDevSpace ()
+    {
+       Rectangle2D uclip = clip.getBounds2D ();
+       if (transform == null)
+           return uclip;
+       else
+           {
+               Point2D pos = transform.transform (new Point2D.Double(uclip.getX (), 
+                                                                     uclip.getY ()), 
+                                                  (Point2D)null);              
+               Point2D extent = transform.deltaTransform (new Point2D.Double(uclip.getWidth (), 
+                                                                             uclip.getHeight ()), 
+                                                          (Point2D)null);
+               return new Rectangle2D.Double (pos.getX (), pos.getY (),
+                                              extent.getX (), extent.getY ());       
+           }
+    }
+
   public void setClip (int x, int y, int width, int height)
   {
-    cairoNewPath ();
-    cairoRectangle (x, y, width, height);
-    cairoClosePath ();
-    cairoClip ();
-    clip = new Rectangle (x, y, width, height);
+      cairoNewPath ();
+      cairoRectangle (x, y, width, height);
+      cairoClosePath ();
+      cairoClip ();
+      clip = new Rectangle2D.Double ((double)x, (double)y, 
+                                    (double)width, (double)height);
   }
 
   public void setClip (Shape s)
@@ -558,7 +635,7 @@ public class GdkGraphics2D extends Graphics2D
     double y1 = (double) y;
     double y2 = (double) y + height;
 
-    cairoSave ();
+    stateSave ();
     
     cairoNewPath ();
     setColor (light);
@@ -574,9 +651,7 @@ public class GdkGraphics2D extends Graphics2D
     cairoLineTo (x2, y2);
     cairoStroke ();
     
-    cairoRestore ();    
-    setColor (std);
-
+    stateRestore ();    
   }
 
   public void fill3DRect(int x, int y, int width, 
@@ -594,15 +669,15 @@ public class GdkGraphics2D extends Graphics2D
       
     draw3DRect (x, y, width, height, raised);
     
-    cairoSave ();
-    cairoTranslate (step/2.0, step/2.0);
+    stateSave ();
+    translate (step/2.0, step/2.0);
     cairoNewPath ();
     cairoRectangle ((double) x, (double) y, 
                     ((double) width) - step, 
                     ((double) height) - step );
     cairoClosePath ();
     cairoFill ();
-    cairoRestore ();
+    stateRestore ();
   }
 
 
@@ -618,7 +693,7 @@ public class GdkGraphics2D extends Graphics2D
 
   public void clearRect (int x, int y, int width, int height)
   {
-    cairoSave ();
+    stateSave ();
     cairoSetRGBColor (bg.getRed() / 255.0, 
                       bg.getGreen() / 255.0, 
                       bg.getBlue() / 255.0);
@@ -627,7 +702,7 @@ public class GdkGraphics2D extends Graphics2D
     cairoRectangle (x, y, width, height);
     cairoClosePath ();
     cairoFill ();
-    cairoRestore ();
+    stateRestore ();
   }
 
   public void setBackground(Color c)
@@ -635,13 +710,11 @@ public class GdkGraphics2D extends Graphics2D
     bg = c;
   }
 
-
   public Color getBackground()
   {
     return bg;
   }
 
-
   private void doPolygon(int[] xPoints, int[] yPoints, int nPoints, 
                          boolean close, boolean fill)
   {    
@@ -698,7 +771,8 @@ public class GdkGraphics2D extends Graphics2D
     doPolygon (xPoints, yPoints, nPoints, false, false);
   }
 
-  private boolean drawRaster (ColorModel cm, Raster r)
+  private boolean drawRaster (ColorModel cm, Raster r, 
+                              AffineTransform imageToUser)
   {
     if (r == null)
       return false;
@@ -712,6 +786,16 @@ public class GdkGraphics2D extends Graphics2D
     if (cm == null)
       cm = ColorModel.getRGBdefault ();
 
+    double[] i2u = new double[6];
+    if (imageToUser != null)
+      imageToUser.getMatrix(i2u);
+    else
+      {
+        i2u[0] = 1; i2u[1] = 0;
+        i2u[2] = 0; i2u[3] = 1;
+        i2u[2] = 0; i2u[3] = 0;
+      }
+
     int pixels[] = null;
 
     if (sm.getDataType () == DataBuffer.TYPE_INT &&
@@ -735,23 +819,39 @@ public class GdkGraphics2D extends Graphics2D
         pixels = pixels2;
       }
     
-    cairoSave ();
-    cairoTranslate (x, y);
-    drawPixels (pixels, r.getWidth (), r.getHeight (), r.getWidth ());
-    cairoRestore ();    
+    stateSave ();
+    translate (x, y);
+    drawPixels (pixels, r.getWidth (), r.getHeight (), r.getWidth (), i2u);
+    stateRestore ();    
     return true;
   }
 
-  public boolean drawImage (Image img, int x, int y, 
-                            ImageObserver observer)
+  public void drawRenderedImage(RenderedImage image,
+                                AffineTransform xform)
+  {
+    drawRaster (image.getColorModel(), image.getData(), xform);
+  }
+  
+  public void drawRenderableImage(RenderableImage image,
+                                  AffineTransform xform)
+  {
+    drawRenderedImage (image.createRendering (new RenderContext (xform)), xform);
+  }
+  
+  public boolean drawImage(Image img, 
+                           AffineTransform xform,
+                           ImageObserver obs)
   {
     if (img instanceof GtkOffScreenImage &&
         img.getGraphics () instanceof GdkGraphics2D &&            
-        (transform == null || transform.isIdentity ())) 
+        (xform == null 
+         || xform.getType () == AffineTransform.TYPE_IDENTITY 
+         || xform.getType () == AffineTransform.TYPE_TRANSLATION)
+        ) 
       {
         // we are being asked to flush a double buffer from Gdk
         GdkGraphics2D g2 = (GdkGraphics2D) img.getGraphics ();
-        gdkDrawDrawable (g2, x, y);
+        gdkDrawDrawable (g2, (int)xform.getTranslateX(), (int)xform.getTranslateY());
         return true;
       }
     else
@@ -760,17 +860,32 @@ public class GdkGraphics2D extends Graphics2D
           {
             // draw an image which has actually been loaded into memory fully
             BufferedImage b = (BufferedImage) img;
-            return drawRaster (b.getColorModel (), b.getData ());
+            return drawRaster (b.getColorModel (), b.getData (), xform);
           }        
         else
           {
             // begin progressive loading in a separate thread
-            new PainterThread (this, img);
+            new PainterThread (this, img, xform);
             return false;
           }
       }
   }
 
+  public void drawImage(BufferedImage image,
+                        BufferedImageOp op,
+                        int x,
+                        int y)
+  {
+    Image filtered = op.filter(image, null);
+    drawImage(filtered, new AffineTransform(1f,0f,0f,1f,x,y), null);
+  }
+
+  public boolean drawImage (Image img, int x, int y, 
+                            ImageObserver observer)
+  {
+    return drawImage(img, new AffineTransform(1f,0f,0f,1f,x,y), observer);    
+  }
+
 
   ////////////////////////////////////////
   ////// Supporting Private Classes //////
@@ -790,10 +905,12 @@ public class GdkGraphics2D extends Graphics2D
     GdkGraphics2D gr;
     Image image;
     ColorModel defaultModel;
+    AffineTransform xform;
 
-    public PainterThread (GdkGraphics2D g, Image im)
+    public PainterThread (GdkGraphics2D g, Image im, AffineTransform xf)
     {
       image = im;
+      xform = xf;
       this.gr = (GdkGraphics2D) g.create ();
       new Thread (this).start ();
     }
@@ -823,8 +940,8 @@ public class GdkGraphics2D extends Graphics2D
     public void setPixels (int x, int y, int w, int h, ColorModel model, 
                            int[] pixels, int off, int scansize)
       {
-        gr.cairoSave ();
-        gr.cairoTranslate (x, y);
+        gr.stateSave ();
+        gr.translate (x, y);
 
         if (model == null)
           model = defaultModel;
@@ -843,8 +960,10 @@ public class GdkGraphics2D extends Graphics2D
         else
           pixels2 = pixels;
 
-        gr.drawPixels (pixels2, w, h, scansize);
-        gr.cairoRestore ();
+        double[] xf = new double[6];
+        xform.getMatrix(xf);        
+        gr.drawPixels (pixels2, w, h, scansize, xf);
+        gr.stateRestore ();
       }
 
     public void setProperties (java.util.Hashtable props)
@@ -934,43 +1053,7 @@ public class GdkGraphics2D extends Graphics2D
   ////// Unimplemented Stubs and Overloads //////
   ///////////////////////////////////////////////
 
-  public boolean drawImage(Image image, 
-                           AffineTransform xform,
-                           ImageObserver obs)
-  {
-    throw new java.lang.UnsupportedOperationException ();
-  }
-  
-  public void drawImage(BufferedImage image,
-                        BufferedImageOp op,
-                        int x,
-                        int y)
-  {
-    throw new java.lang.UnsupportedOperationException ();
-  }
   
-  public void drawRenderedImage(RenderedImage image,
-                                AffineTransform xform)
-  {
-    throw new java.lang.UnsupportedOperationException ();
-  }
-  
-  public void drawRenderableImage(RenderableImage image,
-                                  AffineTransform xform)
-  {
-    throw new java.lang.UnsupportedOperationException ();
-  }
-
-  public void drawString(String text, float x, float y)
-  {
-    throw new java.lang.UnsupportedOperationException ();
-  }
-  
-  public void drawString(AttributedCharacterIterator iterator,
-                         float x, float y)
-  {
-    throw new java.lang.UnsupportedOperationException ();
-  }
     
   public boolean hit(Rectangle rect, Shape text,
                      boolean onStroke)
@@ -1014,11 +1097,6 @@ public class GdkGraphics2D extends Graphics2D
     throw new java.lang.UnsupportedOperationException ();
   }
 
-  public void shear(double shearX, double shearY)
-  {
-    throw new java.lang.UnsupportedOperationException ();
-  }
-
   public Composite getComposite()
   {
     throw new java.lang.UnsupportedOperationException ();
@@ -1026,18 +1104,20 @@ public class GdkGraphics2D extends Graphics2D
 
   public FontRenderContext getFontRenderContext ()
   {
-    throw new java.lang.UnsupportedOperationException ();
+    return new FontRenderContext (transform, true, true);
   }
 
   public void drawGlyphVector (GlyphVector g, float x, float y)
   {    
-    cairoSave ();
-    cairoTranslate ((double)x, (double)y);
+    stateSave ();
+    setFont (g.getFont ());
+    translate ((double)x, (double)y);
+    cairoMoveTo (0, 0);
     int nglyphs = g.getNumGlyphs ();
     int codes[] = g.getGlyphCodes (0, nglyphs, (int []) null);
     float posns[] = g.getGlyphPositions (0, nglyphs, (float []) null);
-    cairoShowGlyphs (codes, posns, nglyphs);
-    cairoRestore ();
+    cairoShowGlyphs (codes, posns);
+    stateRestore ();
   }
 
   public void copyArea (int x, int y, int width, int height, int dx, int dy)
@@ -1048,7 +1128,10 @@ public class GdkGraphics2D extends Graphics2D
   public void drawArc (int x, int y, int width, int height,
                        int startAngle, int arcAngle)
   {
-    throw new java.lang.UnsupportedOperationException ();
+    draw (new Arc2D.Double((double)x, (double)y, 
+                           (double)width, (double)height,
+                           (double)startAngle, (double)arcAngle,
+                           Arc2D.OPEN));
   }
 
   public boolean drawImage (Image img, int x, int y, Color bgcolor, 
@@ -1085,61 +1168,84 @@ public class GdkGraphics2D extends Graphics2D
 
   public void drawOval(int x, int y, int width, int height)
   {
-    throw new java.lang.UnsupportedOperationException ();
+    drawArc (x, y, width, height, 0, 360);
   }
 
   public void drawRoundRect(int x, int y, int width, int height, 
                             int arcWidth, int arcHeight)
   {
-    throw new java.lang.UnsupportedOperationException ();
+    int x1 = x + arcWidth, x2 = x + width - arcWidth;
+    int y1 = y + arcHeight, y2 = y + height - arcHeight;
+    fillRect (x1, y, x2 - x1, height);
+    fillRect (x, y1, width, y2 - y1);
+    fillArc (x, y, arcWidth, arcHeight, 90, 90);
+    fillArc (x1, y, arcWidth, arcHeight, 0, 90);
+    fillArc (x2, y2, arcWidth, arcHeight, 270, 90);
+    fillArc (x, y2, arcWidth, arcHeight, 180, 90);
   }
 
   public void drawString (String str, int x, int y)
   {
-    throw new java.lang.UnsupportedOperationException ();
+    drawString (str, (float)x, (float)y);
+  }
+
+  public void drawString (String str, float x, float y)
+  {
+    GlyphVector gv = font.createGlyphVector (getFontRenderContext(), str);
+    drawGlyphVector (gv, x, y);
   }
 
   public void drawString (AttributedCharacterIterator ci, int x, int y)
   {
-    throw new java.lang.UnsupportedOperationException ();
+    drawString (ci, (float)x, (float)y);
+  }
+
+  public void drawString (AttributedCharacterIterator ci, float x, float y)
+  {
+    GlyphVector gv = font.createGlyphVector (getFontRenderContext(), ci);
+    drawGlyphVector (gv, x, y);
   }
 
   public void fillArc (int x, int y, int width, int height, 
                        int startAngle, int arcAngle)
   {
-    cairoNewPath ();
-    walkPath (new Arc2D.Double((double)x, (double)y, 
-                               (double)width, (double)height,
-                               (double)startAngle, (double)arcAngle,
-                               Arc2D.PIE).getPathIterator (null));
-    cairoClosePath ();
-    cairoFill ();
+    fill (new Arc2D.Double((double)x, (double)y, 
+                           (double)width, (double)height,
+                           (double)startAngle, (double)arcAngle,
+                           Arc2D.OPEN));
   }
 
   public void fillOval(int x, int y, int width, int height)
   {
-    throw new java.lang.UnsupportedOperationException ();
+    fillArc (x, y, width, height, 0, 360);
   }
 
   public void fillRoundRect (int x, int y, int width, int height, 
                              int arcWidth, int arcHeight)
   {
-    throw new java.lang.UnsupportedOperationException ();
+    int x1 = x + arcWidth, x2 = x + width - arcWidth;
+    int y1 = y + arcHeight, y2 = y + height - arcHeight;
+    fillRect (x1, y, x2 - x1, height);
+    fillRect (x, y1, width, y2 - y1);
+    fillArc (x, y, arcWidth, arcHeight, 90, 90);
+    fillArc (x1, y, arcWidth, arcHeight, 0, 90);
+    fillArc (x2, y2, arcWidth, arcHeight, 270, 90);
+    fillArc (x, y2, arcWidth, arcHeight, 180, 90);
   }
 
   public Font getFont ()
   {
-    throw new java.lang.UnsupportedOperationException ();
+    return font;
   }
 
   public FontMetrics getFontMetrics ()
   {
-    throw new java.lang.UnsupportedOperationException ();
+    return Toolkit.getDefaultToolkit ().getFontMetrics (font);
   }
 
   public FontMetrics getFontMetrics (Font f)
   {
-    throw new java.lang.UnsupportedOperationException ();
+    return Toolkit.getDefaultToolkit ().getFontMetrics (f);
   }
 
   public void setFont (Font f)
index 092979b..afb705b 100644 (file)
@@ -120,6 +120,13 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkClasspathFontPeer_setFont
   pfont = (struct peerfont *)NSA_GET_FONT_PTR (env, self);
   g_assert (pfont != NULL);
 
+  if (pfont->ctx != NULL)
+    g_object_unref (pfont->ctx);
+  if (pfont->font != NULL)
+    g_object_unref (pfont->font);
+  if (pfont->desc != NULL)
+    pango_font_description_free (pfont->desc);
+
   pfont->desc = pango_font_description_new ();
   g_assert (pfont->desc != NULL);
 
@@ -153,7 +160,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkClasspathFontPeer_setFont
 
   pfont->font = pango_font_map_load_font (map, pfont->ctx, pfont->desc);
   g_assert (pfont->font != NULL);
-  
+
   gdk_threads_leave ();
 }
 
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c
new file mode 100644 (file)
index 0000000..0f0b424
--- /dev/null
@@ -0,0 +1,93 @@
+/* gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c
+   Copyright (C) 1999, 2003 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. */
+
+#include <math.h>
+
+#include "gtkpeer.h"
+#include "gdkfont.h"
+#include "gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.h"
+
+#define ASCENT      0
+#define MAX_ASCENT  1
+#define DESCENT     2
+#define MAX_DESCENT 3
+#define MAX_ADVANCE 4
+#define NUM_METRICS 5
+
+JNIEXPORT jintArray JNICALL Java_gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics_initState
+  (JNIEnv *env, jobject self, jobject font)
+{
+  jintArray array;
+  jint *metrics;
+  struct peerfont *pf = NULL;
+
+  pf = NSA_GET_FONT_PTR(env, font);
+  g_assert (pf != NULL);
+
+  array = (*env)->NewIntArray (env, NUM_METRICS);
+  metrics = (*env)->GetIntArrayElements (env, array, NULL);
+
+  gdk_threads_enter ();
+
+#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 63.0))
+#define DOUBLE_FROM_26_6(t) (((double)((t) >> 6)) \
+                            + ((double)((t) & 0x3F) / 63.0))
+
+  double pointsize = pango_font_description_get_size (pf->desc);
+  pointsize /= (double) PANGO_SCALE;
+
+  FT_Face face = pango_ft2_font_get_face (pf->font);  
+  FT_Set_Char_Size( face, 
+                   DOUBLE_TO_26_6 (pointsize),
+                   DOUBLE_TO_26_6 (pointsize),
+                   0, 0);
+
+  metrics[ASCENT]      = ceil (DOUBLE_FROM_26_6(face->size->metrics.ascender));
+  metrics[MAX_ASCENT]  = metrics[ASCENT];
+  metrics[DESCENT]     = floor (DOUBLE_FROM_26_6(face->size->metrics.descender));
+  if (metrics[DESCENT] < 0)
+    metrics[DESCENT] = - metrics[DESCENT];
+  metrics[MAX_DESCENT] = metrics[DESCENT];
+  metrics[MAX_ADVANCE] = ceil (DOUBLE_FROM_26_6(face->size->metrics.max_advance));
+
+  gdk_threads_leave ();
+
+  (*env)->ReleaseIntArrayElements (env, array, metrics, 0);
+
+  return array;
+}
+
index 052f7e9..29616c7 100644 (file)
 
 struct state_table *native_glyphvector_state_table;
 
+typedef struct { 
+  double x;
+  double y;
+  double width;
+  double height;
+} rect_t;
+
+#define DOUBLE_TO_26_6(d) ((FT_F26Dot6)((d) * 63.0))
+#define DOUBLE_FROM_26_6(t) (((double)((t) >> 6)) \
+                            + ((double)((t) & 0x3F) / 63.0))
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_initStaticState 
   (JNIEnv *env, jclass clazz)
@@ -64,8 +74,11 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_initState
   vec = (struct glyphvec *) g_malloc0 (sizeof (struct glyphvec));
   g_assert (vec != NULL);
 
-  vec->desc = pango_font_description_copy (pfont->desc);
+  vec->desc = pango_font_describe (pfont->font); 
   g_assert (vec->desc != NULL);
+
+  vec->font = pfont->font;
+  g_object_ref (vec->font);
     
   vec->ctx = pfont->ctx;
   g_object_ref (vec->ctx);
@@ -150,10 +163,10 @@ static void seek_glyph_idx (GList *list, int idx,
   *g = gs->glyphs + nidx;
 }
 
-static void union_rects (PangoRectangle *r1, 
-                        const PangoRectangle *r2)
+static void union_rects (rect_t *r1, 
+                        const rect_t *r2)
 {
-  PangoRectangle r;
+  rect_t r;
 
   g_assert (r1 != NULL);
   g_assert (r2 != NULL);
@@ -184,7 +197,7 @@ static void union_rects (PangoRectangle *r1,
   *r1 = r;  
 }
 
-static jdoubleArray rect_to_array (JNIEnv *env, const PangoRectangle *r)
+static jdoubleArray rect_to_array (JNIEnv *env, const rect_t *r)
 {
   /* We often return rectangles as arrays : { x, y, w, h } */
   jdoubleArray ret;
@@ -193,11 +206,11 @@ static jdoubleArray rect_to_array (JNIEnv *env, const PangoRectangle *r)
   ret = (*env)->NewDoubleArray (env, 4);
   rp = (*env)->GetDoubleArrayElements (env, ret, NULL);
   g_assert (rp != NULL);
-  rp[0] = r->x / (double)PANGO_SCALE;
+  rp[0] = r->x;
   /* freetype and pango's view of space is upside down from java2d's */
-  rp[1] = (r->y / (double)PANGO_SCALE) * -1;
-  rp[2] = r->width / (double)PANGO_SCALE;
-  rp[3] = r->height / (double)PANGO_SCALE;
+  rp[1] = r->y * -1;
+  rp[2] = r->width;
+  rp[3] = r->height;
   (*env)->ReleaseDoubleArrayElements (env, ret, rp, 0);
   return ret;
 }
@@ -251,18 +264,14 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_setChars
   str = (gchar *)(*env)->GetStringUTFChars (env, chars, NULL);
   g_assert (str != NULL);
 
-  /* step 1: mark the text as having our FontFescription as an 
-     attribute, then "itemize" the text */
+  /* step 1: set our FontFescription in the context, then "itemize" the
+     text */
 
   attrs = pango_attr_list_new ();
   g_assert (attrs != NULL);
   
-  PangoAttribute *da = pango_attr_font_desc_new(vec->desc);
-  g_assert (da != NULL);
-  da->start_index = 0;
-  da->end_index = len;
-  
-  pango_attr_list_insert (attrs, da);
+  pango_context_set_font_description (vec->ctx, vec->desc);
+
   items = pango_itemize (vec->ctx, str, 0, len, attrs, NULL);
   g_assert (items != NULL);
   
@@ -393,15 +402,19 @@ JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_glyphCharIndex
 }
 
 
-JNIEXPORT jdoubleArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_allLogicalExtents 
+JNIEXPORT jdoubleArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_allInkExtents 
   (JNIEnv *env, jobject self)
 {
   struct glyphvec *vec = NULL;
+  int j;
   GList *i;
   PangoGlyphItem *gi = NULL;
-  PangoRectangle rect = {0,0,0,0};
-  PangoRectangle tmp, dummy;  
+  rect_t rect = {0,0,0,0};
+  rect_t tmp;  
   jdoubleArray ret;
+  double x = 0, y = 0;
+  double pointsize;
+  FT_Face face;
 
   gdk_threads_enter ();
   g_assert (self != NULL);
@@ -409,17 +422,33 @@ JNIEXPORT jdoubleArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_allLogi
   g_assert (vec != NULL);
   g_assert (vec->glyphitems != NULL);
 
+  pointsize = pango_font_description_get_size (vec->desc);
+  pointsize /= (double) PANGO_SCALE;
+
   for (i = g_list_first (vec->glyphitems); i != NULL; i = g_list_next (i))
     {
       g_assert (i->data != NULL);
       gi = (PangoGlyphItem *)i->data;
       g_assert (gi->glyphs != NULL);
+
+      face = pango_ft2_font_get_face (gi->item->analysis.font);
+      FT_Set_Char_Size( face, 
+                       DOUBLE_TO_26_6 (pointsize),
+                       DOUBLE_TO_26_6 (pointsize),
+                       0, 0);
       
-      pango_glyph_string_extents (gi->glyphs,
-                                 gi->item->analysis.font,
-                                 &dummy,
-                                 &tmp);
-      union_rects (&rect, &tmp);
+      for (j = 0; j < gi->glyphs->num_glyphs; ++j)
+       {
+         FT_Load_Glyph (face, gi->glyphs->glyphs[j].glyph, FT_LOAD_DEFAULT);
+         /* FIXME: this needs to change for vertical layouts */
+         tmp.x = x + DOUBLE_FROM_26_6 (face->glyph->metrics.horiBearingX);
+         tmp.y = y + DOUBLE_FROM_26_6 (face->glyph->metrics.horiBearingY);
+         tmp.width = DOUBLE_FROM_26_6 (face->glyph->metrics.width);
+         tmp.height = DOUBLE_FROM_26_6 (face->glyph->metrics.height);
+         union_rects (&rect, &tmp);
+         x += DOUBLE_FROM_26_6 (face->glyph->advance.x);
+         y += DOUBLE_FROM_26_6 (face->glyph->advance.y);
+       }
     }      
 
   ret = rect_to_array (env, &rect);
@@ -428,15 +457,19 @@ JNIEXPORT jdoubleArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_allLogi
 }
 
 
-JNIEXPORT jdoubleArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_allInkExtents 
+JNIEXPORT jdoubleArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_allLogicalExtents 
   (JNIEnv *env, jobject self)
 {
   struct glyphvec *vec = NULL;
+  int j;
   GList *i;
   PangoGlyphItem *gi = NULL;
-  PangoRectangle rect = {0,0,0,0};
-  PangoRectangle tmp, dummy;  
+  rect_t rect = {0,0,0,0};
+  rect_t tmp;  
   jdoubleArray ret;
+  double x = 0, y = 0;
+  double pointsize;
+  FT_Face face;
 
   gdk_threads_enter ();
   g_assert (self != NULL);
@@ -444,17 +477,38 @@ JNIEXPORT jdoubleArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_allInkE
   g_assert (vec != NULL);
   g_assert (vec->glyphitems != NULL);
 
+  pointsize = pango_font_description_get_size (vec->desc);
+  pointsize /= (double) PANGO_SCALE;
+
   for (i = g_list_first (vec->glyphitems); i != NULL; i = g_list_next (i))
     {
       g_assert (i->data != NULL);
       gi = (PangoGlyphItem *)i->data;
       g_assert (gi->glyphs != NULL);
+
+      face = pango_ft2_font_get_face (gi->item->analysis.font);
+      FT_Set_Char_Size( face, 
+                       DOUBLE_TO_26_6 (pointsize),
+                       DOUBLE_TO_26_6 (pointsize),
+                       0, 0);
       
-      pango_glyph_string_extents (gi->glyphs,
-                                 gi->item->analysis.font,
-                                 &tmp,
-                                 &dummy);
-      union_rects (&rect, &tmp);
+      for (j = 0; j < gi->glyphs->num_glyphs; ++j)
+       {
+         FT_Load_Glyph (face, gi->glyphs->glyphs[j].glyph, FT_LOAD_DEFAULT);
+
+         /* FIXME: also, this is probably not the correct set of metrics;
+            the "logical bounds" are some fancy combination of hori
+            advance and height such that it's good for inverting as a
+            highlight. revisit. */
+
+         tmp.x = x;
+         tmp.y = y;
+         tmp.width = DOUBLE_FROM_26_6 (face->glyph->advance.x);
+         tmp.height = DOUBLE_FROM_26_6 (face->glyph->advance.y);
+         union_rects (&rect, &tmp);
+         x += DOUBLE_FROM_26_6 (face->glyph->advance.x);
+         y += DOUBLE_FROM_26_6 (face->glyph->advance.y);
+       }
     }      
 
   ret = rect_to_array (env, &rect);
@@ -462,27 +516,47 @@ JNIEXPORT jdoubleArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_allInkE
   return ret;
 }
 
+
 JNIEXPORT jdoubleArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_glyphLogicalExtents 
   (JNIEnv *env, jobject self, jint idx)
 {
   struct glyphvec *vec = NULL;
-  PangoRectangle rect = {0,0,0,0};
-  PangoRectangle dummy;  
+  rect_t rect = {0,0,0,0};
   PangoGlyphInfo *gi = NULL;
   PangoFont *font = NULL;
   jdoubleArray ret;
+  double pointsize;
+  FT_Face face;
 
   gdk_threads_enter ();
   g_assert (self != NULL);
   vec = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
   g_assert (vec != NULL);
   g_assert (vec->glyphitems != NULL);
-
   seek_glyph_idx (vec->glyphitems, idx, &gi, &font);
   g_assert (gi != NULL);
   g_assert (font != NULL);
 
-  pango_font_get_glyph_extents (font, gi->glyph, &dummy, &rect);
+  pointsize = pango_font_description_get_size (vec->desc);
+  pointsize /= (double) PANGO_SCALE;
+  face = pango_ft2_font_get_face (font);
+  FT_Set_Char_Size( face, 
+                   DOUBLE_TO_26_6 (pointsize),
+                   DOUBLE_TO_26_6 (pointsize),
+                   0, 0);
+  
+  FT_Load_Glyph (face, gi->glyph, FT_LOAD_DEFAULT);
+
+  /* FIXME: this is probably not the correct set of metrics;
+     the "logical bounds" are some fancy combination of hori
+     advance and height such that it's good for inverting as a
+     highlight. revisit. */
+  
+  rect.x = 0; 
+  rect.y = 0; 
+  rect.width = DOUBLE_FROM_26_6 (face->glyph->advance.x);
+  rect.height = DOUBLE_FROM_26_6 (face->glyph->advance.y);
 
   ret = rect_to_array (env, &rect);
   gdk_threads_leave ();
@@ -494,29 +568,44 @@ JNIEXPORT jdoubleArray JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_glyphIn
   (JNIEnv *env, jobject self, jint idx)
 {
   struct glyphvec *vec = NULL;
-  PangoRectangle rect = {0,0,0,0};
-  PangoRectangle dummy;  
+  rect_t rect = {0,0,0,0};
   PangoGlyphInfo *gi = NULL;
   PangoFont *font = NULL;
   jdoubleArray ret;
-
+  double pointsize;
+  FT_Face face;
+  
   gdk_threads_enter ();
   g_assert (self != NULL);
   vec = (struct glyphvec *)NSA_GET_GV_PTR (env, self);
   g_assert (vec != NULL);
   g_assert (vec->glyphitems != NULL);
-
   seek_glyph_idx (vec->glyphitems, idx, &gi, &font);
   g_assert (gi != NULL);
   g_assert (font != NULL);
 
-  pango_font_get_glyph_extents (font, gi->glyph, &rect, &dummy);
+  pointsize = pango_font_description_get_size (vec->desc);
+  pointsize /= (double) PANGO_SCALE;
+  face = pango_ft2_font_get_face (font);
+  FT_Set_Char_Size( face, 
+                   DOUBLE_TO_26_6 (pointsize),
+                   DOUBLE_TO_26_6 (pointsize),
+                   0, 0);
+  
+  FT_Load_Glyph (face, gi->glyph, FT_LOAD_DEFAULT);
+  /* FIXME: this needs to change for vertical layouts */
+  rect.x = DOUBLE_FROM_26_6 (face->glyph->metrics.horiBearingX);
+  rect.y = DOUBLE_FROM_26_6 (face->glyph->metrics.horiBearingY);
+  rect.width = DOUBLE_FROM_26_6 (face->glyph->metrics.width);
+  rect.height = DOUBLE_FROM_26_6 (face->glyph->metrics.height);
 
   ret = rect_to_array (env, &rect);
   gdk_threads_leave ();
   return ret;
 }
 
+
 JNIEXPORT jboolean JNICALL Java_gnu_java_awt_peer_gtk_GdkGlyphVector_glyphIsHorizontal 
   (JNIEnv *env, jobject self, jint idx)
 {
index 08a9742..76305ca 100644 (file)
@@ -302,6 +302,8 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_copyState
   g_old = (struct graphics2d *) NSA_GET_G2D_PTR (env, old);
   g_assert (g_old != NULL);
 
+  if (g_old->debug) printf ("copying state from existing graphics2d\n");
+
   g->drawable = g_old->drawable;
   g->debug = g_old->debug; 
 
@@ -316,7 +318,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_copyState
   else
     init_graphics2d_as_pixbuf (g);
 
-  cairo_surface_set_filter (g->surface, CAIRO_FILTER_BILINEAR);
+  cairo_surface_set_filter (g->surface, CAIRO_FILTER_FAST);
 
   gdk_threads_leave ();
 
@@ -649,36 +651,61 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_setTexturePixels
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_drawPixels 
-  (JNIEnv *env, jobject obj, jintArray jarr, jint w, jint h, jint stride)
+  (JNIEnv *env, jobject obj, jintArray java_pixels, 
+   jint w, jint h, jint stride, jdoubleArray java_matrix)
 {
   struct graphics2d *gr = NULL;
-  jint *jpixels = NULL;
+  jint *native_pixels = NULL;
+  jdouble *native_matrix = NULL;
 
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
 
   if (gr->debug) printf ("drawPixels (%d pixels, %dx%d, stride: %d)\n",
-                        (*env)->GetArrayLength (env, jarr), w, h, stride);
+                        (*env)->GetArrayLength (env, java_pixels), w, h, stride);
 
-  jpixels = (*env)->GetIntArrayElements (env, jarr, NULL);
-  g_assert (jpixels != NULL);
+  native_pixels = (*env)->GetIntArrayElements (env, java_pixels, NULL);
+  native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);
+  g_assert (native_pixels != NULL);
+  g_assert (native_matrix != NULL);
+  g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
 
   begin_drawing_operation (gr);
-
   
  {
-   cairo_surface_t *surf = cairo_surface_create_for_image ((char *)jpixels, 
+   cairo_matrix_t *mat = NULL;
+   cairo_surface_t *surf = cairo_surface_create_for_image ((char *)native_pixels, 
                                                           CAIRO_FORMAT_ARGB32, 
                                                           w, h, stride * 4);   
-   cairo_surface_set_filter (surf, CAIRO_FILTER_BILINEAR);
+   mat = cairo_matrix_create ();
+   cairo_matrix_set_affine (mat, 
+                           native_matrix[0], native_matrix[1],
+                           native_matrix[2], native_matrix[3],
+                           native_matrix[4], native_matrix[5]);
+   cairo_surface_set_matrix (surf, mat);
+   if (native_matrix[0] != 1.
+       || native_matrix[1] != 0.
+       || native_matrix[2] != 0.
+       || native_matrix[3] != 1.)
+     {
+       cairo_surface_set_filter (surf, CAIRO_FILTER_BILINEAR);
+       cairo_surface_set_filter (gr->surface, CAIRO_FILTER_BILINEAR);
+     }
+   else
+     {
+       cairo_surface_set_filter (surf, CAIRO_FILTER_FAST);
+       cairo_surface_set_filter (gr->surface, CAIRO_FILTER_FAST);
+     }
    cairo_show_surface (gr->cr, surf, w, h);
+   cairo_surface_set_filter (gr->surface, CAIRO_FILTER_FAST);
+   cairo_matrix_destroy (mat);
    cairo_surface_destroy (surf);
  }
   
-
  end_drawing_operation (gr);
 
-  (*env)->ReleaseIntArrayElements (env, jarr, jpixels, 0);
+  (*env)->ReleaseIntArrayElements (env, java_pixels, native_pixels, 0);
+  (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
 
 }
 
@@ -706,25 +733,34 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRestore
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMatrix 
-   (JNIEnv *env, jobject obj,
-    jdouble m00, jdouble m10,
-    jdouble m01, jdouble m11,
-    jdouble m02, jdouble m12)
+   (JNIEnv *env, jobject obj, jdoubleArray java_matrix)
 {
   struct graphics2d *gr = NULL;
+  jdouble *native_matrix = NULL;
+
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
-  if (gr->debug) printf ("cairo_set_matrix\n");
+
+  native_matrix = (*env)->GetDoubleArrayElements (env, java_matrix, NULL);  
+  g_assert (native_matrix != NULL);
+  g_assert ((*env)->GetArrayLength (env, java_matrix) == 6);
+
+  if (gr->debug) printf ("cairo_set_matrix [ %f, %f, %f, %f, %f, %f ]\n",
+                        native_matrix[0], native_matrix[1],
+                        native_matrix[2], native_matrix[3],
+                        native_matrix[4], native_matrix[5]);
 
   {
     cairo_matrix_t * mat = cairo_matrix_create ();
-    cairo_matrix_set_affine (mat,
-                            m00, m10,
-                            m01, m11,
-                            m02, m12);
+    cairo_matrix_set_affine (mat, 
+                            native_matrix[0], native_matrix[1],
+                            native_matrix[2], native_matrix[3],
+                            native_matrix[4], native_matrix[5]);
     cairo_set_matrix (gr->cr, mat);
     cairo_matrix_destroy (mat);
   }
+
+  (*env)->ReleaseDoubleArrayElements (env, java_matrix, native_matrix, 0);
   update_pattern_transform (gr);
 }
 
@@ -750,8 +786,7 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetFont
   ft = cairo_ft_font_create_for_ft_face (face);
   g_assert (ft != NULL);
 
-  if (gr->debug) printf ("cairo_set_font '%s'\n", 
-                        face->family_name);
+  if (gr->debug) printf ("cairo_set_font '%s'\n", face->family_name);
   
   cairo_set_font (gr->cr, ft);
 
@@ -765,40 +800,46 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetFont
 }
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoShowGlyphs
-   (JNIEnv *env, jobject obj, jintArray jcodes, jfloatArray jposns, jint nglyphs)
+   (JNIEnv *env, jobject obj, jintArray java_codes, jfloatArray java_posns)
 {
   struct graphics2d *gr = NULL;
   cairo_glyph_t *glyphs = NULL;
-  jfloat *posns = NULL;
-  jint *codes = NULL;
+  jfloat *native_posns = NULL;
+  jint *native_codes = NULL;
   jint i;
+  jint ncodes, nposns;
 
   gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
   g_assert (gr != NULL);
 
-  if (gr->debug) printf ("cairo_show_glyphs (%d glyphs)\n", nglyphs);
+  native_codes = (*env)->GetIntArrayElements (env, java_codes, NULL);  
+  native_posns = (*env)->GetFloatArrayElements (env, java_posns, NULL);  
+  g_assert (native_codes != NULL);
+  g_assert (native_posns != NULL);
 
-  glyphs = malloc (sizeof(cairo_glyph_t) * nglyphs);
-  g_assert (glyphs);
+  ncodes = (*env)->GetArrayLength (env, java_codes);
+  nposns = (*env)->GetArrayLength (env, java_posns);
+  g_assert (2 * ncodes == nposns);
 
-  codes = (*env)->GetIntArrayElements (env, jcodes, NULL);  
-  g_assert (codes != NULL);
+  if (gr->debug) printf ("cairo_show_glyphs (%d glyphs)\n", ncodes);
 
-  posns = (*env)->GetFloatArrayElements (env, jposns, NULL);  
-  g_assert (posns != NULL);
+  glyphs = malloc (sizeof(cairo_glyph_t) * ncodes);
+  g_assert (glyphs);
 
-  for (i = 0; i < nglyphs; ++i)
+  for (i = 0; i < ncodes; ++i)
     {
-      glyphs[i].index = codes[i];
-      glyphs[i].x = (double) posns[2*i];
-      glyphs[i].y = (double) posns[2*i + 1];
+      glyphs[i].index = native_codes[i];
+      glyphs[i].x = (double) native_posns[2*i];
+      glyphs[i].y = (double) native_posns[2*i + 1];
+      if (gr->debug) printf ("cairo_show_glyphs (glyph %d (code %d) : %f,%f)\n", 
+                            i, glyphs[i].index, glyphs[i].x, glyphs[i].y);
     }
 
-  (*env)->ReleaseIntArrayElements (env, jcodes, codes, 0);
-  (*env)->ReleaseFloatArrayElements (env, jposns, posns, 0);
+  (*env)->ReleaseIntArrayElements (env, java_codes, native_codes, 0);
+  (*env)->ReleaseFloatArrayElements (env, java_posns, native_posns, 0);
 
   begin_drawing_operation (gr);
-  cairo_show_glyphs (gr->cr, glyphs, nglyphs);
+  cairo_show_glyphs (gr->cr, glyphs, ncodes);
   end_drawing_operation (gr);
 
   free(glyphs);
@@ -991,38 +1032,6 @@ JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoSetMiterLim
   cairo_set_miter_limit (gr->cr, miter);
 }
 
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoTranslate 
-   (JNIEnv *env, jobject obj, jdouble dx, jdouble dy)
-{
-  struct graphics2d *gr = NULL;
-  gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
-  g_assert (gr != NULL);
-  if (gr->debug) printf ("cairo_translate (%f, %f)\n", dx, dy);
-  cairo_translate (gr->cr, dx, dy);
-  update_pattern_transform (gr);
-}
-
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoScale 
-   (JNIEnv *env, jobject obj, jdouble sx, jdouble sy)
-{
-  struct graphics2d *gr = NULL;
-  gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
-  g_assert (gr != NULL);
-  if (gr->debug) printf ("cairo_scale (%f, %f)\n", sx, sy);
-  cairo_scale (gr->cr, sx, sy);
-  update_pattern_transform (gr);
-}
-
-JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoRotate 
-   (JNIEnv *env, jobject obj, jdouble angle)
-{
-  struct graphics2d *gr = NULL;
-  gr = (struct graphics2d *) NSA_GET_G2D_PTR (env, obj);
-  g_assert (gr != NULL);
-  if (gr->debug) printf ("cairo_rotate %f\n", angle);
-  cairo_rotate (gr->cr, angle);
-  update_pattern_transform (gr);
-}
 
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GdkGraphics2D_cairoNewPath 
    (JNIEnv *env, jobject obj)