aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libjava/ChangeLog40
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java64
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.java116
-rw-r--r--libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java444
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c9
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c93
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c173
-rw-r--r--libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c151
8 files changed, 802 insertions, 288 deletions
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 98cc75e..7bbf92b 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -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>
diff --git a/libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java b/libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java
index 7e31700..ca26289 100644
--- a/libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java
+++ b/libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeer.java
@@ -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
index 0000000..2f019e4
--- /dev/null
+++ b/libjava/gnu/java/awt/peer/gtk/GdkClasspathFontPeerMetrics.java
@@ -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];
+ }
+}
diff --git a/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java b/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java
index 7adb307..036e40f 100644
--- a/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java
+++ b/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java
@@ -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)
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c
index 092979b..afb705b 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeer.c
@@ -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
index 0000000..0f0b424
--- /dev/null
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkClasspathFontPeerMetrics.c
@@ -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;
+}
+
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c
index 052f7e9..29616c7 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGlyphVector.c
@@ -40,6 +40,16 @@
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)
{
diff --git a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
index 08a9742..76305ca 100644
--- a/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
+++ b/libjava/jni/gtk-peer/gnu_java_awt_peer_gtk_GdkGraphics2D.c
@@ -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)