diff options
Diffstat (limited to 'libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java')
-rw-r--r-- | libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java | 566 |
1 files changed, 241 insertions, 325 deletions
diff --git a/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java b/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java index 0986960b8b3..82de03d5aec 100644 --- a/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java +++ b/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java @@ -1,5 +1,5 @@ /* GdkGraphics2D.java - Copyright (C) 2003, 2004 Free Software Foundation, Inc. + Copyright (C) 2003, 2004 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -38,21 +38,60 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.awt.*; -import java.awt.geom.*; -import java.awt.font.*; -import java.awt.color.*; -import java.awt.image.*; -import java.awt.image.renderable.*; -import java.util.HashMap; -import java.util.Map; +import gnu.classpath.Configuration; +import gnu.java.awt.ClasspathToolkit; +import gnu.java.awt.peer.ClasspathFontPeer; +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.GradientPaint; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GraphicsConfiguration; +import java.awt.Image; +import java.awt.Paint; +import java.awt.Rectangle; +import java.awt.RenderingHints; +import java.awt.Shape; +import java.awt.Stroke; +import java.awt.TexturePaint; +import java.awt.Toolkit; +import java.awt.color.ColorSpace; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.GlyphJustificationInfo; +import java.awt.geom.Arc2D; +import java.awt.geom.GeneralPath; +import java.awt.geom.NoninvertibleTransformException; +import java.awt.geom.PathIterator; +import java.awt.geom.Point2D; +import java.awt.geom.Rectangle2D; +import java.awt.geom.AffineTransform; +import java.awt.image.AffineTransformOp; +import java.awt.image.BufferedImage; +import java.awt.image.BufferedImageOp; +import java.awt.image.ColorModel; +import java.awt.image.CropImageFilter; +import java.awt.image.DataBuffer; +import java.awt.image.DataBufferInt; +import java.awt.image.FilteredImageSource; +import java.awt.image.ImageConsumer; +import java.awt.image.ImageObserver; +import java.awt.image.ImagingOpException; +import java.awt.image.SampleModel; +import java.awt.image.Raster; +import java.awt.image.RenderedImage; +import java.awt.image.WritableRaster; +import java.awt.image.renderable.RenderableImage; +import java.awt.image.renderable.RenderContext; import java.text.AttributedCharacterIterator; +import java.util.HashMap; +import java.util.Map; import java.util.Stack; -import java.lang.Integer; -import gnu.java.awt.ClasspathToolkit; -import gnu.java.awt.peer.ClasspathFontPeer; -import gnu.classpath.Configuration; public class GdkGraphics2D extends Graphics2D { @@ -85,6 +124,8 @@ public class GdkGraphics2D extends Graphics2D private RenderingHints hints; private BufferedImage bimage; + private Composite comp; + private Stack stateStack; native private void initState (GtkComponentPeer component); @@ -93,6 +134,7 @@ public class GdkGraphics2D extends Graphics2D native public void dispose (); native private int[] getImagePixels(); native private void cairoSurfaceSetFilter(int filter); + native void connectSignals (GtkComponentPeer component); public void finalize () { @@ -113,7 +155,7 @@ public class GdkGraphics2D extends Graphics2D { paint = g.paint; stroke = g.stroke; - hints = g.hints; + setRenderingHints (g.hints); if (g.fg.getAlpha() != -1) fg = new Color (g.fg.getRed (), g.fg.getGreen (), @@ -145,8 +187,8 @@ public class GdkGraphics2D extends Graphics2D setBackground (bg); setPaint (paint); setStroke (stroke); - setClip (clip); setTransform (transform); + setClip (clip); stateStack = new Stack(); } @@ -168,12 +210,22 @@ public class GdkGraphics2D extends Graphics2D GdkGraphics2D (GtkComponentPeer component) { this.component = component; + + setFont (new Font("SansSerif", Font.PLAIN, 12)); + + if (component.isRealized ()) + initComponentGraphics2D (); + else + connectSignals (component); + } + + void initComponentGraphics2D () + { initState (component); setColor (component.awtComponent.getForeground ()); setBackground (component.awtComponent.getBackground ()); setPaint (getColor()); - setFont (new Font("SansSerif", Font.PLAIN, 12)); setTransform (new AffineTransform ()); setStroke (new BasicStroke ()); setRenderingHints (getDefaultHints()); @@ -224,9 +276,6 @@ public class GdkGraphics2D extends Graphics2D private native void cairoSave (); private native void cairoRestore (); private native void cairoSetMatrix (double m[]); - private native void cairoSetFont (GdkClasspathFontPeer peer); - private native void cairoShowGlyphs (int codes[], - float positions[]); private native void cairoSetOperator (int cairoOperator); private native void cairoSetRGBColor (double red, double green, double blue); private native void cairoSetAlpha (double alpha); @@ -268,6 +317,7 @@ public class GdkGraphics2D extends Graphics2D private Shape clip; private AffineTransform transform; private Font font; + private Composite comp; DrawState (GdkGraphics2D g) { this.paint = g.paint; @@ -278,6 +328,7 @@ public class GdkGraphics2D extends Graphics2D if (g.transform != null) this.transform = (AffineTransform) g.transform.clone(); this.font = g.font; + this.comp = g.comp; } public void restore(GdkGraphics2D g) { @@ -288,6 +339,7 @@ public class GdkGraphics2D extends Graphics2D g.clip = this.clip; g.transform = this.transform; g.font = this.font; + g.comp = this.comp; } } @@ -303,17 +355,23 @@ public class GdkGraphics2D extends Graphics2D cairoRestore (); } + // Some operations (drawing rather than filling) require that their + // coords be shifted to land on 0.5-pixel boundaries, in order to land on + // "middle of pixel" coordinates and light up complete pixels. - double x; - double y; - private void setPos (double nx, double ny) + private boolean shiftDrawCalls = false; + private final double shifted(double coord, boolean doShift) { - x = nx; - y = ny; + if (doShift) + return Math.floor(coord) + 0.5; + else + return coord; } - private void walkPath(PathIterator p) + private final void walkPath(PathIterator p, boolean doShift) { + double x = 0; + double y = 0; double coords[] = new double[6]; cairoSetFillRule (p.getWindingRule ()); @@ -324,13 +382,15 @@ public class GdkGraphics2D extends Graphics2D { case PathIterator.SEG_MOVETO: - setPos(coords[0], coords[1]); - cairoMoveTo (coords[0], coords[1]); + x = shifted(coords[0], doShift); + y = shifted(coords[1], doShift); + cairoMoveTo (x, y); break; case PathIterator.SEG_LINETO: - setPos(coords[0], coords[1]); - cairoLineTo (coords[0], coords[1]); + x = shifted(coords[0], doShift); + y = shifted(coords[1], doShift); + cairoLineTo (x, y); break; case PathIterator.SEG_QUADTO: @@ -338,23 +398,25 @@ public class GdkGraphics2D extends Graphics2D // splitting a quadratic bezier into a cubic: // see: http://pfaedit.sourceforge.net/bezier.html - double x1 = x + (2.0/3.0) * (coords[0] - x); - double y1 = y + (2.0/3.0) * (coords[1] - y); + double x1 = x + (2.0/3.0) * (shifted(coords[0], doShift) - x); + double y1 = y + (2.0/3.0) * (shifted(coords[1], doShift) - y); - double x2 = x1 + (1.0/3.0) * (coords[2] - x); - double y2 = y1 + (1.0/3.0) * (coords[3] - y); + double x2 = x1 + (1.0/3.0) * (shifted(coords[2], doShift) - x); + double y2 = y1 + (1.0/3.0) * (shifted(coords[3], doShift) - y); - setPos(coords[2], coords[3]); + x = shifted(coords[2], doShift); + y = shifted(coords[3], doShift); cairoCurveTo (x1, y1, x2, y2, - coords[2], coords[3]); + x, y); break; case PathIterator.SEG_CUBICTO: - setPos(coords[4], coords[5]); - cairoCurveTo (coords[0], coords[1], - coords[2], coords[3], - coords[4], coords[5]); + x = shifted(coords[4], doShift); + y = shifted(coords[5], doShift); + cairoCurveTo (shifted(coords[0], doShift), shifted(coords[1], doShift), + shifted(coords[2], doShift), shifted(coords[3], doShift), + x, y); break; case PathIterator.SEG_CLOSE: @@ -365,7 +427,7 @@ public class GdkGraphics2D extends Graphics2D } - private Map getDefaultHints() + private final Map getDefaultHints() { HashMap defaultHints = new HashMap (); @@ -388,23 +450,19 @@ public class GdkGraphics2D extends Graphics2D } - private void updateBufferedImage() + private final void updateBufferedImage() { int[] pixels = getImagePixels(); updateImagePixels(pixels); } - private boolean isBufferedImageGraphics () + private final boolean isBufferedImageGraphics () { - - if (bimage != null) - return true; - else - return false; + return bimage != null; } - private void updateImagePixels (int[] pixels) + private final void updateImagePixels (int[] pixels) { // This function can only be used if @@ -439,11 +497,15 @@ public class GdkGraphics2D extends Graphics2D } - private boolean drawImage(Image img, - AffineTransform xform, - Color bgcolor, - ImageObserver obs) + private final boolean drawImage(Image img, + AffineTransform xform, + Color bgcolor, + ImageObserver obs) { + + if (img == null) + return false; + if (img instanceof GtkOffScreenImage && img.getGraphics () instanceof GdkGraphics2D && (xform == null @@ -461,8 +523,8 @@ public class GdkGraphics2D extends Graphics2D return true; } else - { - + { + // In this case, xform is an AffineTransform that transforms bounding // box of the specified image from image space to user space. However // when we pass this transform to cairo, cairo will use this transform @@ -475,23 +537,22 @@ public class GdkGraphics2D extends Graphics2D try { - invertedXform = xform.createInverse(); + invertedXform = xform.createInverse(); if (img instanceof BufferedImage) { // draw an image which has actually been loaded // into memory fully - BufferedImage b = (BufferedImage) img; - return drawRaster (b.getColorModel (), - b.getData (), - invertedXform, - bgcolor); + BufferedImage b = (BufferedImage) img; + return drawRaster (b.getColorModel (), + b.getData (), + invertedXform, + bgcolor); } else { - // begin progressive loading in a separate thread - new PainterThread (this, img, invertedXform, bgcolor); - return false; + return this.drawImage(GdkPixbufDecoder.createBufferedImage(img.getSource()), + xform, bgcolor,obs); } } catch (NoninvertibleTransformException e) @@ -517,38 +578,25 @@ public class GdkGraphics2D extends Graphics2D return; } - stateSave (); cairoNewPath (); - - boolean normalize; - normalize = hints.containsValue (RenderingHints.VALUE_STROKE_NORMALIZE) - || hints.containsValue (RenderingHints.VALUE_STROKE_DEFAULT); - - if (normalize) - translate (0.5,0.5); if (s instanceof Rectangle2D) { Rectangle2D r = (Rectangle2D)s; - cairoRectangle (r.getX (), r.getY (), r.getWidth (), r.getHeight ()); + cairoRectangle (shifted(r.getX (), shiftDrawCalls), + shifted(r.getY (), shiftDrawCalls), + r.getWidth (), r.getHeight ()); } else - walkPath (s.getPathIterator (null)); + walkPath (s.getPathIterator (null), shiftDrawCalls); cairoStroke (); - if (normalize) - translate (-0.5,-0.5); - - stateRestore (); - if (isBufferedImageGraphics ()) updateBufferedImage(); - } public void fill (Shape s) { - stateSave(); cairoNewPath (); if (s instanceof Rectangle2D) { @@ -556,9 +604,8 @@ public class GdkGraphics2D extends Graphics2D cairoRectangle (r.getX (), r.getY (), r.getWidth (), r.getHeight ()); } else - walkPath (s.getPathIterator (null)); + walkPath (s.getPathIterator (null), false); cairoFill (); - stateRestore (); if (isBufferedImageGraphics ()) updateBufferedImage(); @@ -592,8 +639,8 @@ public class GdkGraphics2D extends Graphics2D r.getWidth (), r.getHeight ()); } else - walkPath (clip.getPathIterator (null)); - cairoClosePath (); + walkPath (clip.getPathIterator (null), false); + // cairoClosePath (); cairoClip (); } } @@ -739,7 +786,7 @@ public class GdkGraphics2D extends Graphics2D { BasicStroke bs = (BasicStroke) stroke; cairoSetLineCap (bs.getEndCap()); - cairoSetLineWidth (bs.getLineWidth() / 2.0); + cairoSetLineWidth (bs.getLineWidth()); cairoSetLineJoin (bs.getLineJoin()); cairoSetMiterLimit (bs.getMiterLimit()); float dashes[] = bs.getDashArray(); @@ -771,6 +818,9 @@ public class GdkGraphics2D extends Graphics2D public void setColor (Color c) { + if (c == null) + c = Color.BLACK; + fg = c; paint = c; cairoSetRGBColor (fg.getRed() / 255.0, @@ -802,23 +852,23 @@ 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 ()); - } - } + 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) { @@ -839,96 +889,34 @@ public class GdkGraphics2D extends Graphics2D r.getWidth (), r.getHeight ()); } else - walkPath (s.getPathIterator (null)); - cairoClosePath (); + walkPath (s.getPathIterator (null), false); + // cairoClosePath (); cairoClip (); } } + private static BasicStroke draw3DRectStroke = new BasicStroke(); + public void draw3DRect(int x, int y, int width, int height, boolean raised) { - Color std = fg; - Color light = std.brighter(); - Color dark = std.darker(); - - if (!raised) - { - Color t = light; - light = dark; - dark = t; - } - - double x1 = (double) x; - double x2 = (double) x + width; - - double y1 = (double) y; - double y2 = (double) y + height; - - stateSave (); - - cairoNewPath (); - - boolean normalize; - normalize = hints.containsValue (RenderingHints.VALUE_STROKE_NORMALIZE) - || hints.containsValue (RenderingHints.VALUE_STROKE_DEFAULT); - - if (normalize) - { - x1 += 0.5; - y1 += 0.5; - x2 += 0.5; - y2 += 0.5; - } - - setColor (light); - cairoMoveTo (x1, y1); - cairoLineTo (x2, y1); - cairoLineTo (x2, y2); - cairoStroke (); - - cairoNewPath (); - setColor (dark); - cairoMoveTo (x1, y1); - cairoLineTo (x1, y2); - cairoLineTo (x2, y2); - cairoStroke (); - - stateRestore (); - + Stroke tmp = stroke; + setStroke(draw3DRectStroke); + super.draw3DRect(x, y, width, height, raised); + setStroke(tmp); if (isBufferedImageGraphics ()) updateBufferedImage(); - } public void fill3DRect(int x, int y, int width, int height, boolean raised) { - double step = 1.0; - if (stroke != null && stroke instanceof BasicStroke) - { - BasicStroke bs = (BasicStroke) stroke; - step = bs.getLineWidth(); - } - - Color bright = fg.brighter (); - Color dark = fg.darker (); - - draw3DRect (x, y, width, height, raised); - - stateSave (); - translate (step/2.0, step/2.0); - cairoNewPath (); - cairoRectangle ((double) x, (double) y, - ((double) width) - step, - ((double) height) - step ); - cairoClosePath (); - cairoFill (); - stateRestore (); - + Stroke tmp = stroke; + setStroke(draw3DRectStroke); + super.fill3DRect(x, y, width, height, raised); + setStroke(tmp); if (isBufferedImageGraphics ()) updateBufferedImage(); - } @@ -939,21 +927,21 @@ public class GdkGraphics2D extends Graphics2D public void fillRect (int x, int y, int width, int height) { - fill(new Rectangle (x, y, width, height)); + cairoNewPath (); + cairoRectangle (x, y, width, height); + cairoFill (); } public void clearRect (int x, int y, int width, int height) { - stateSave (); cairoSetRGBColor (bg.getRed() / 255.0, bg.getGreen() / 255.0, bg.getBlue() / 255.0); cairoSetAlpha (1.0); cairoNewPath (); cairoRectangle (x, y, width, height); - cairoClosePath (); cairoFill (); - stateRestore (); + setColor (fg); if (isBufferedImageGraphics ()) updateBufferedImage(); @@ -970,8 +958,8 @@ public class GdkGraphics2D extends Graphics2D return bg; } - private void doPolygon(int[] xPoints, int[] yPoints, int nPoints, - boolean close, boolean fill) + private final void doPolygon(int[] xPoints, int[] yPoints, int nPoints, + boolean close, boolean fill) { if (nPoints < 1) return; @@ -1026,9 +1014,9 @@ public class GdkGraphics2D extends Graphics2D doPolygon (xPoints, yPoints, nPoints, false, false); } - private boolean drawRaster (ColorModel cm, Raster r, - AffineTransform imageToUser, - Color bgcolor) + private final boolean drawRaster (ColorModel cm, Raster r, + AffineTransform imageToUser, + Color bgcolor) { if (r == null) return false; @@ -1087,10 +1075,7 @@ public class GdkGraphics2D extends Graphics2D } } - stateSave (); - translate (x, y); drawPixels (pixels, r.getWidth (), r.getHeight (), r.getWidth (), i2u); - stateRestore (); if (isBufferedImageGraphics ()) updateBufferedImage(); @@ -1133,113 +1118,6 @@ public class GdkGraphics2D extends Graphics2D } - //////////////////////////////////////// - ////// Supporting Private Classes ////// - //////////////////////////////////////// - - private class PainterThread implements Runnable, ImageConsumer - { - - // this is a helper which is spun off when someone tries to do - // Graphics2D.drawImage on an image we cannot determine to be either - // one of our own offscreen images or a BufferedImage; that is, when - // someone wants to draw an image which is possibly still loading over - // a network or something. you run it in a separate thread and it - // writes through to the underlying Graphics2D as pixels becomg - // available. - - GdkGraphics2D gr; - Image image; - ColorModel defaultModel; - AffineTransform xform; - Color bgcolor; - - public PainterThread (GdkGraphics2D g, Image im, - AffineTransform xf, Color bg) - { - image = im; - xform = xf; - bgcolor = bg; - this.gr = (GdkGraphics2D) g.create (); - new Thread (this).start (); - } - - public void imageComplete (int status) - { - } - - public void setColorModel (ColorModel model) - { - defaultModel = model; - } - - public void setDimensions (int width, int height) - { - } - - public void setHints (int hintflags) - { - } - - public void setPixels (int x, int y, int w, int h, ColorModel model, - byte[] pixels, int off, int scansize) - { - } - - public void setPixels (int x, int y, int w, int h, ColorModel model, - int[] pixels, int off, int scansize) - { - gr.stateSave (); - gr.translate (x, y); - - if (model == null) - model = defaultModel; - - int pixels2[]; - if (model != null) - { - pixels2 = new int[pixels.length]; - for (int yy = 0; yy < h; yy++) - for (int xx = 0; xx < w; xx++) - { - int i = yy * scansize + xx; - pixels2[i] = model.getRGB (pixels[i]); - } - } - else - pixels2 = pixels; - - // change all transparent pixels in the image to the - // specified bgcolor - - if (bgcolor != null) - { - for (int i = 0; i < pixels2.length; i++) - { - if (model.getAlpha (pixels2[i]) == 0) - pixels2[i] = bgcolor.getRGB (); - } - } - - double[] xf = new double[6]; - xform.getMatrix(xf); - gr.drawPixels (pixels2, w, h, scansize, xf); - gr.stateRestore (); - } - - public void setProperties (java.util.Hashtable props) - { - } - - public void run () - { - image.getSource ().startProduction (this); - gr.dispose (); - } - } - - - /////////////////////////////////////////////// ////// Unimplemented Stubs and Overloads ////// /////////////////////////////////////////////// @@ -1259,6 +1137,8 @@ public class GdkGraphics2D extends Graphics2D public void setComposite(Composite comp) { + this.comp = comp; + if (comp instanceof AlphaComposite) { AlphaComposite a = (AlphaComposite) comp; @@ -1297,8 +1177,11 @@ public class GdkGraphics2D extends Graphics2D else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT)) cairoSurfaceSetFilter(4); - } + } + shiftDrawCalls = hints.containsValue (RenderingHints.VALUE_STROKE_NORMALIZE) + || hints.containsValue (RenderingHints.VALUE_STROKE_DEFAULT); + } public Object getRenderingHint(RenderingHints.Key hintKey) @@ -1331,6 +1214,9 @@ public class GdkGraphics2D extends Graphics2D else if(hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT)) cairoSurfaceSetFilter(4); } + + shiftDrawCalls = hints.containsValue (RenderingHints.VALUE_STROKE_NORMALIZE) + || hints.containsValue (RenderingHints.VALUE_STROKE_DEFAULT); } public void addRenderingHints(Map hints) @@ -1345,7 +1231,10 @@ public class GdkGraphics2D extends Graphics2D public Composite getComposite() { - throw new java.lang.UnsupportedOperationException (); + if (comp == null) + return AlphaComposite.SrcOver; + else + return comp; } public FontRenderContext getFontRenderContext () @@ -1353,23 +1242,6 @@ public class GdkGraphics2D extends Graphics2D return new FontRenderContext (transform, true, true); } - public void drawGlyphVector (GlyphVector g, float x, float 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); - - if (isBufferedImageGraphics ()) - updateBufferedImage(); - - stateRestore (); - } - public void copyArea (int x, int y, int width, int height, int dx, int dy) { throw new java.lang.UnsupportedOperationException (); @@ -1418,6 +1290,9 @@ public class GdkGraphics2D extends Graphics2D Color bgcolor, ImageObserver observer) { + if (img == null) + return false; + Image subImage; int sourceWidth = sx2 - sx1; @@ -1501,15 +1376,40 @@ public class GdkGraphics2D extends Graphics2D drawLine (x1, y + height, x2, y + height); } - public void drawString (String str, int x, int y) + // these are the most accelerated painting paths + native void cairoDrawGdkGlyphVector (GdkFontPeer f, GdkGlyphVector gv, float x, float y); + native void cairoDrawGdkTextLayout (GdkFontPeer f, GdkTextLayout gl, float x, float y); + native void cairoDrawString (GdkFontPeer f, String str, float x, float y); + + GdkFontPeer getFontPeer() { - drawString (str, (float)x, (float)y); + return (GdkFontPeer) getFont().getPeer(); + } + + public void drawGdkGlyphVector(GdkGlyphVector gv, float x, float y) + { + cairoDrawGdkGlyphVector(getFontPeer(), gv, x, y); + if (isBufferedImageGraphics ()) + updateBufferedImage(); + } + + public void drawGdkTextLayout(GdkTextLayout gl, float x, float y) + { + cairoDrawGdkTextLayout(getFontPeer(), gl, x, y); + if (isBufferedImageGraphics ()) + updateBufferedImage(); } public void drawString (String str, float x, float y) { - GlyphVector gv = font.createGlyphVector (getFontRenderContext(), str); - drawGlyphVector (gv, x, y); + cairoDrawString(getFontPeer(), str, x, y); + if (isBufferedImageGraphics ()) + updateBufferedImage(); + } + + public void drawString (String str, int x, int y) + { + drawString (str, (float)x, (float)y); } public void drawString (AttributedCharacterIterator ci, int x, int y) @@ -1517,6 +1417,14 @@ public class GdkGraphics2D extends Graphics2D drawString (ci, (float)x, (float)y); } + public void drawGlyphVector (GlyphVector gv, float x, float y) + { + if (gv instanceof GdkGlyphVector) + drawGdkGlyphVector((GdkGlyphVector)gv, x, y); + else + throw new java.lang.UnsupportedOperationException (); + } + public void drawString (AttributedCharacterIterator ci, float x, float y) { GlyphVector gv = font.createGlyphVector (getFontRenderContext(), ci); @@ -1562,30 +1470,38 @@ public class GdkGraphics2D extends Graphics2D return font; } + // Until such time as pango is happy to talk directly to cairo, we + // actually need to redirect some calls from the GtkFontPeer and + // GtkFontMetrics into the drawing kit and ask cairo ourselves. + + static native void releasePeerGraphicsResource(GdkFontPeer f); + static native void getPeerTextMetrics (GdkFontPeer f, String str, double [] metrics); + static native void getPeerFontMetrics (GdkFontPeer f, double [] metrics); + public FontMetrics getFontMetrics () { + // the reason we go via the toolkit here is to try to get + // a cached object. the toolkit keeps such a cache. return Toolkit.getDefaultToolkit ().getFontMetrics (font); } public FontMetrics getFontMetrics (Font f) { + // the reason we go via the toolkit here is to try to get + // a cached object. the toolkit keeps such a cache. return Toolkit.getDefaultToolkit ().getFontMetrics (f); } public void setFont (Font f) { - if (f.getPeer() instanceof GdkClasspathFontPeer) + if (f.getPeer() instanceof GdkFontPeer) font = f; else font = ((ClasspathToolkit)(Toolkit.getDefaultToolkit ())) - .getFont (f.getName(), f.getAttributes ()); - - if (f != null && - f.getPeer() instanceof GdkClasspathFontPeer) - cairoSetFont ((GdkClasspathFontPeer) f.getPeer()); + .getFont (f.getName(), f.getAttributes ()); } - + public String toString() { return getClass ().getName () + |