diff options
Diffstat (limited to 'libjava/gnu/java/awt')
36 files changed, 1777 insertions, 1273 deletions
diff --git a/libjava/gnu/java/awt/ClasspathToolkit.java b/libjava/gnu/java/awt/ClasspathToolkit.java index de97c4a0edf..72302e11c30 100644 --- a/libjava/gnu/java/awt/ClasspathToolkit.java +++ b/libjava/gnu/java/awt/ClasspathToolkit.java @@ -41,16 +41,20 @@ package gnu.java.awt; import gnu.java.awt.peer.ClasspathFontPeer; import gnu.java.awt.peer.ClasspathTextLayoutPeer; -import java.awt.Image; +import java.awt.AWTException; import java.awt.Dimension; import java.awt.DisplayMode; +import java.awt.EventQueue; import java.awt.Font; import java.awt.FontMetrics; +import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; +import java.awt.Image; import java.awt.Toolkit; import java.awt.font.FontRenderContext; import java.awt.image.ColorModel; import java.awt.image.ImageProducer; +import java.awt.peer.RobotPeer; import java.io.File; import java.io.InputStream; import java.net.MalformedURLException; @@ -90,7 +94,7 @@ public abstract class ClasspathToolkit * #getImage(java.net.URL)}. For images that were loaded via a path * to an image file, the map contains a key with a file URL. */ - private Map imageCache; + private HashMap imageCache; /** @@ -169,7 +173,6 @@ public abstract class ClasspathToolkit * this font peer should have, such as size, weight, family name, or * transformation. */ - public abstract ClasspathFontPeer getClasspathFontPeer (String name, Map attrs); public abstract ClasspathTextLayoutPeer @@ -184,7 +187,6 @@ public abstract class ClasspathToolkit * implement {@link java.awt.font.OpenType} or * {@link java.awt.font.MultipleMaster}. */ - public Font getFont (String name, Map attrs) { return new Font (name, attrs); @@ -350,6 +352,9 @@ public abstract class ClasspathToolkit return null; } + public abstract RobotPeer createRobot (GraphicsDevice screen) + throws AWTException; + /** * Used to register ImageIO SPIs provided by the toolkit. */ @@ -357,4 +362,8 @@ public abstract class ClasspathToolkit public void registerImageIOSpis(IIORegistry reg) { } + + public abstract boolean nativeQueueEmpty(); + public abstract void wakeNativeQueue(); + public abstract void iterateNativeQueue(EventQueue locked, boolean block); } diff --git a/libjava/gnu/java/awt/EmbeddedWindow.java b/libjava/gnu/java/awt/EmbeddedWindow.java index 08bc02755ea..c3cfac48b19 100644 --- a/libjava/gnu/java/awt/EmbeddedWindow.java +++ b/libjava/gnu/java/awt/EmbeddedWindow.java @@ -38,7 +38,6 @@ exception statement from your version. */ package gnu.java.awt; -import gnu.classpath.Configuration; import gnu.java.awt.peer.EmbeddedWindowPeer; import gnu.java.security.action.SetAccessibleAction; diff --git a/libjava/gnu/java/awt/color/ClutProfileConverter.java b/libjava/gnu/java/awt/color/ClutProfileConverter.java index d33a6887eec..5b06f48eed8 100644 --- a/libjava/gnu/java/awt/color/ClutProfileConverter.java +++ b/libjava/gnu/java/awt/color/ClutProfileConverter.java @@ -38,7 +38,6 @@ package gnu.java.awt.color; -import java.awt.color.ColorSpace; import java.awt.color.ICC_Profile; diff --git a/libjava/gnu/java/awt/image/ImageDecoder.java b/libjava/gnu/java/awt/image/ImageDecoder.java index 233dfb1b28d..d279d567467 100644 --- a/libjava/gnu/java/awt/image/ImageDecoder.java +++ b/libjava/gnu/java/awt/image/ImageDecoder.java @@ -74,6 +74,11 @@ public abstract class ImageDecoder implements ImageProducer this.url = url; } + public ImageDecoder (InputStream is) + { + this.input = is; + } + public ImageDecoder (byte[] imagedata, int imageoffset, int imagelength) { data = imagedata; @@ -99,7 +104,7 @@ public abstract class ImageDecoder implements ImageProducer public void startProduction (ImageConsumer ic) { if (!isConsumer(ic)) - addConsumer (ic); + addConsumer(ic); Vector list = (Vector) consumers.clone (); try @@ -108,17 +113,30 @@ public abstract class ImageDecoder implements ImageProducer // ImageDecoder constructors so that exceptions cause // imageComplete to be called with an appropriate error // status. - if (url != null) - input = url.openStream(); - else - { - if (filename != null) - input = new FileInputStream (filename); - else - input = new ByteArrayInputStream (data, offset, length); - } - - produce (list, input); + if (input == null) + { + try + { + if (url != null) + input = url.openStream(); + else + { + if (filename != null) + input = new FileInputStream (filename); + else + input = new ByteArrayInputStream (data, offset, length); + } + produce (list, input); + } + finally + { + input = null; + } + } + else + { + produce (list, input); + } } catch (Exception e) { diff --git a/libjava/gnu/java/awt/peer/ClasspathTextLayoutPeer.java b/libjava/gnu/java/awt/peer/ClasspathTextLayoutPeer.java index 143412caf99..07b4b3eb403 100644 --- a/libjava/gnu/java/awt/peer/ClasspathTextLayoutPeer.java +++ b/libjava/gnu/java/awt/peer/ClasspathTextLayoutPeer.java @@ -38,19 +38,12 @@ exception statement from your version. */ package gnu.java.awt.peer; -import java.awt.Font; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.font.TextHitInfo; import java.awt.font.TextLayout; import java.awt.geom.AffineTransform; import java.awt.geom.Rectangle2D; -import java.text.CharacterIterator; -import java.text.AttributedCharacterIterator; -import java.text.AttributedString; -import java.util.Map; -import java.awt.font.TextAttribute; - /** * @author Graydon Hoare diff --git a/libjava/gnu/java/awt/peer/gtk/GdkFontMetrics.java b/libjava/gnu/java/awt/peer/gtk/GdkFontMetrics.java index 3cd2f9a1cd2..e871587a4a9 100644 --- a/libjava/gnu/java/awt/peer/gtk/GdkFontMetrics.java +++ b/libjava/gnu/java/awt/peer/gtk/GdkFontMetrics.java @@ -63,8 +63,6 @@ public class GdkFontMetrics extends FontMetrics static final int TEXT_METRICS_X_ADVANCE = 4; static final int TEXT_METRICS_Y_ADVANCE = 5; - static native void getPeerFontMetrics(GdkFontPeer peer, double [] metrics); - static native void getPeerTextMetrics(GdkFontPeer peer, String str, double [] metrics); public GdkFontMetrics (Font font) { @@ -77,12 +75,7 @@ public class GdkFontMetrics extends FontMetrics font_metrics = new int[5]; double [] hires = new double[5]; - - if (GtkToolkit.useGraphics2D ()) - GdkGraphics2D.getPeerFontMetrics(peer, hires); - else - getPeerFontMetrics (peer, hires); - + peer.getFontMetrics (hires); for (int i = 0; i < 5; ++i) font_metrics[i] = (int) hires[i]; } @@ -90,10 +83,7 @@ public class GdkFontMetrics extends FontMetrics public int stringWidth (String str) { double [] hires = new double[6]; - if (GtkToolkit.useGraphics2D()) - GdkGraphics2D.getPeerTextMetrics(peer, str, hires); - else - getPeerTextMetrics(peer, str, hires); + peer.getTextMetrics(str, hires); return (int) hires [TEXT_METRICS_WIDTH]; } @@ -115,7 +105,6 @@ public class GdkFontMetrics extends FontMetrics public int getLeading () { return 1; -// return metrics[ASCENT] + metrics[DESCENT]; } public int getAscent () diff --git a/libjava/gnu/java/awt/peer/gtk/GdkFontPeer.java b/libjava/gnu/java/awt/peer/gtk/GdkFontPeer.java index ee051451026..5573a1b4d7f 100644 --- a/libjava/gnu/java/awt/peer/gtk/GdkFontPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GdkFontPeer.java @@ -37,19 +37,21 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.awt.peer.FontPeer; -import java.awt.*; -import java.awt.geom.*; -import java.awt.font.*; + +import gnu.classpath.Configuration; +import gnu.java.awt.peer.ClasspathFontPeer; + +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.LineMetrics; +import java.awt.geom.Rectangle2D; import java.util.Locale; import java.util.Map; import java.util.ResourceBundle; -import java.util.MissingResourceException; import java.text.CharacterIterator; -import java.text.AttributedCharacterIterator; import java.text.StringCharacterIterator; -import gnu.classpath.Configuration; -import gnu.java.awt.peer.ClasspathFontPeer; public class GdkFontPeer extends ClasspathFontPeer { @@ -81,6 +83,9 @@ public class GdkFontPeer extends ClasspathFontPeer private native void dispose (); private native void setFont (String family, int style, int size, boolean useGraphics2D); + native void getFontMetrics(double [] metrics); + native void getTextMetrics(String str, double [] metrics); + protected void finalize () { if (GtkToolkit.useGraphics2D ()) @@ -158,26 +163,33 @@ public class GdkFontPeer extends ClasspathFontPeer public boolean canDisplay (Font font, char c) { - throw new UnsupportedOperationException (); + // FIXME: inquire with pango + return true; } public int canDisplayUpTo (Font font, CharacterIterator i, int start, int limit) { - throw new UnsupportedOperationException (); + // FIXME: inquire with pango + return -1; } + + private native GdkGlyphVector getGlyphVector(String txt, + Font f, + FontRenderContext ctx); public GlyphVector createGlyphVector (Font font, FontRenderContext ctx, CharacterIterator i) { - return new GdkGlyphVector(font, this, ctx, buildString (i)); + return getGlyphVector(buildString (i), font, ctx); } public GlyphVector createGlyphVector (Font font, FontRenderContext ctx, int[] glyphCodes) { - return new GdkGlyphVector (font, this, ctx, glyphCodes); + return null; + // return new GdkGlyphVector (font, this, ctx, glyphCodes); } public byte getBaselineFor (Font font, char c) @@ -259,7 +271,8 @@ public class GdkFontPeer extends ClasspathFontPeer public Rectangle2D getStringBounds (Font font, CharacterIterator ci, int begin, int limit, FontRenderContext frc) { - throw new UnsupportedOperationException (); + GdkGlyphVector gv = getGlyphVector(buildString (ci, begin, limit), font, frc); + return gv.getVisualBounds(); } public boolean hasUniformLineMetrics (Font font) diff --git a/libjava/gnu/java/awt/peer/gtk/GdkGlyphVector.java b/libjava/gnu/java/awt/peer/gtk/GdkGlyphVector.java index c37de5274ac..4e66a86eb42 100644 --- a/libjava/gnu/java/awt/peer/gtk/GdkGlyphVector.java +++ b/libjava/gnu/java/awt/peer/gtk/GdkGlyphVector.java @@ -38,8 +38,6 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import gnu.classpath.Configuration; - import java.awt.Font; import java.awt.Rectangle; import java.awt.Shape; @@ -54,36 +52,57 @@ import java.awt.geom.Rectangle2D; public class GdkGlyphVector extends GlyphVector { - static + /* We use a simple representation for glyph vectors here. Glyph i + * consumes 8 doubles: + * + * logical x: extents[ 10*i ] + * logical y: extents[ 10*i + 1 ] + * logical width: extents[ 10*i + 2 ] + * logical height: extents[ 10*i + 3 ] + * + * visual x: extents[ 10*i + 4 ] + * visual y: extents[ 10*i + 5 ] + * visual width: extents[ 10*i + 6 ] + * visual height: extents[ 10*i + 7 ] + * + * origin pos x: extents[ 10*i + 8 ] + * origin pos y: extents[ 10*i + 9 ] + * + * as well as one int, code[i], representing the glyph code in the font. + */ + + double [] extents; + int [] codes; + + Font font; + FontRenderContext fontRenderContext; + + Rectangle2D allLogical; + Rectangle2D allVisual; + + public GdkGlyphVector(double[] extents, int[] codes, Font font, FontRenderContext frc) { - if (Configuration.INIT_LOAD_LIBRARY) + this.extents = extents; + this.codes = codes; + this.font = font; + this.fontRenderContext = frc; + + allLogical = new Rectangle2D.Double(); + allVisual = new Rectangle2D.Double(); + + for (int i = 0; i < codes.length; ++i) { - System.loadLibrary("gtkpeer"); + allLogical.add (new Rectangle2D.Double(extents[10*i ] + extents[10*i + 8], + extents[10*i + 1] + extents[10*i + 9], + extents[10*i + 2], + extents[10*i + 3])); + + allVisual.add (new Rectangle2D.Double(extents[10*i + 4] + extents[10*i + 8], + extents[10*i + 5] + extents[10*i + 9], + extents[10*i + 6], + extents[10*i + 7])); } - - if (GtkToolkit.useGraphics2D ()) - initStaticState (); } - native static void initStaticState (); - private final int native_state = GtkGenericPeer.getUniqueInteger (); - - private Font font; - private FontRenderContext ctx; - - private native void initState (GdkFontPeer peer, FontRenderContext ctx); - private native void setChars (String s); - private native void setGlyphCodes (int codes[]); - private native void dispose (); - private native int glyphCode (int idx); - private native int numGlyphs (); - private native int glyphCharIndex (int idx); - private native double[] allLogicalExtents (); - private native double[] allInkExtents (); - private native double[] glyphLogicalExtents (int idx); - private native double[] glyphInkExtents (int idx); - private native boolean glyphIsHorizontal (int idx); - private native boolean isEqual (GdkGlyphVector ggv); - /* geometric notes: @@ -108,26 +127,14 @@ public class GdkGlyphVector extends GlyphVector */ - - public GdkGlyphVector (Font f, GdkFontPeer peer, FontRenderContext c, String s) + public double[] getExtents() { - font = f; - ctx = c; - initState (peer, ctx); - setChars (s); + return extents; } - public GdkGlyphVector (Font f, GdkFontPeer peer, FontRenderContext c, int codes[]) + public int[] getCodes() { - font = f; - ctx = c; - initState (peer, ctx); - setGlyphCodes (codes); - } - - protected void finalize () - { - dispose (); + return codes; } public Font getFont () @@ -137,12 +144,15 @@ public class GdkGlyphVector extends GlyphVector public FontRenderContext getFontRenderContext () { - return ctx; + return fontRenderContext; } public int getGlyphCharIndex (int glyphIndex) { - return glyphCharIndex (glyphIndex); + // FIXME: currently pango does not provide glyph-by-glyph + // reverse mapping information, so we assume a broken 1:1 + // glyph model here. This is plainly wrong. + return glyphIndex; } public int[] getGlyphCharIndices (int beginGlyphIndex, @@ -154,50 +164,44 @@ public class GdkGlyphVector extends GlyphVector ix = new int[numEntries]; for (int i = 0; i < numEntries; i++) - ix[i] = glyphCharIndex (beginGlyphIndex + i); + ix[i] = getGlyphCharIndex (beginGlyphIndex + i); return ix; } public int getGlyphCode (int glyphIndex) { - return glyphCode (glyphIndex); + return codes[glyphIndex]; } public int[] getGlyphCodes (int beginGlyphIndex, int numEntries, int[] codeReturn) { - int ix[] = codeReturn; - if (ix == null) - ix = new int[numEntries]; + if (codeReturn == null) + codeReturn = new int[numEntries]; - for (int i = 0; i < numEntries; i++) - ix[i] = glyphCode (beginGlyphIndex + i); - return ix; + System.arraycopy(codes, beginGlyphIndex, codeReturn, 0, numEntries); + return codeReturn; } - public Shape getGlyphLogicalBounds (int glyphIndex) + public Shape getGlyphLogicalBounds (int i) { - double extents[] = glyphLogicalExtents (glyphIndex); - return new Rectangle2D.Double (extents[0], extents[1], - extents[2], extents[3]); + return new Rectangle2D.Double (extents[8*i], extents[8*i + 1], + extents[8*i + 2], extents[8*i + 3]); } - public GlyphMetrics getGlyphMetrics (int glyphIndex) + public GlyphMetrics getGlyphMetrics (int i) { - double extents[] = glyphLogicalExtents (glyphIndex); - Rectangle2D log_bounds = new Rectangle2D.Double (extents[0], extents[1], - extents[2], extents[3]); - - extents = glyphInkExtents (glyphIndex); - Rectangle2D ink_bounds = new Rectangle2D.Double (extents[0], extents[1], - extents[2], extents[3]); - - boolean is_horizontal = glyphIsHorizontal (glyphIndex); - - return new GlyphMetrics (is_horizontal, - (float)(log_bounds.getWidth() + log_bounds.getX()), - (float)(log_bounds.getHeight() + log_bounds.getY()), - ink_bounds, GlyphMetrics.STANDARD); + // FIXME: pango does not yield vertical layout information at the + // moment. + + boolean is_horizontal = true; + double advanceX = extents[8*i + 2]; // "logical width" == advanceX + double advanceY = 0; + + return new GlyphMetrics (is_horizontal, + (float) advanceX, (float) advanceY, + (Rectangle2D) getGlyphVisualBounds(i), + GlyphMetrics.STANDARD); } public Shape getGlyphOutline (int glyphIndex) @@ -210,20 +214,18 @@ public class GdkGlyphVector extends GlyphVector throw new UnsupportedOperationException (); } - public Rectangle getGlyphPixelBounds (int glyphIndex, + public Rectangle getGlyphPixelBounds (int i, FontRenderContext renderFRC, float x, float y) { - double extents[] = glyphInkExtents(glyphIndex); - return new Rectangle ((int)x, (int)y, (int)extents[2], (int)extents[3]); + return new Rectangle((int) x, (int) y, + (int) extents[8*i + 6], (int) extents[8*i + 7]); } - public Point2D getGlyphPosition (int glyphIndex) + public Point2D getGlyphPosition (int i) { - float[] ret = new float[2 * (glyphIndex + 1)]; - getGlyphPositions (0, glyphIndex + 1, ret); - return new Point2D.Float (ret[2 * glyphIndex], - ret[2 * glyphIndex + 1]); + return new Point2D.Double (extents[10*i + 8], + extents[10*i + 9]); } public float[] getGlyphPositions (int beginGlyphIndex, @@ -234,35 +236,25 @@ public class GdkGlyphVector extends GlyphVector if (fx == null) fx = new float[numEntries * 2]; - - float x = 0.0f; - float y = 0.0f; for (int i = 0; i < numEntries; ++i) { - boolean is_horizontal = glyphIsHorizontal (beginGlyphIndex + i); - double log_extents[] = glyphLogicalExtents (beginGlyphIndex + i); - fx[2*i] = x + (float)log_extents[0]; // x offset - fx[2*i + 1] = y + (float)log_extents[1]; // y offset - if (is_horizontal) - x += (float)log_extents[2]; // x advance ("logical width") in pango-ese - else - y += (float)log_extents[3]; // y advance ("logical height") in pango-ese + fx[2*i ] = (float) extents[10*i + 8]; + fx[2*i + 1] = (float) extents[10*i + 9]; } return fx; } public AffineTransform getGlyphTransform (int glyphIndex) { - // glyphs don't have independent transforms in these simple glyph + // Glyphs don't have independent transforms in these simple glyph // vectors; docs specify null is an ok return here. return null; } - public Shape getGlyphVisualBounds (int glyphIndex) + public Shape getGlyphVisualBounds (int i) { - double extents[] = glyphInkExtents (glyphIndex); - return new Rectangle2D.Double (extents[0], extents[1], - extents[2], extents[3]); + return new Rectangle2D.Double(extents[8*i + 4], extents[8*i + 5], + extents[8*i + 6], extents[8*i + 7]); } public int getLayoutFlags () @@ -272,14 +264,12 @@ public class GdkGlyphVector extends GlyphVector public Rectangle2D getLogicalBounds () { - double extents[] = allLogicalExtents (); - return new Rectangle2D.Double (extents[0], extents[1], - extents[2], extents[3]); + return allLogical; } public int getNumGlyphs () { - return numGlyphs (); + return codes.length; } public Shape getOutline () @@ -290,26 +280,28 @@ public class GdkGlyphVector extends GlyphVector public Rectangle getPixelBounds (FontRenderContext renderFRC, float x, float y) { - double extents[] = allInkExtents(); - return new Rectangle ((int)x, (int)y, - (int)extents[2], (int)extents[3]); + return new Rectangle((int)x, + (int)y, + (int) allVisual.getWidth(), + (int) allVisual.getHeight()); } public Rectangle2D getVisualBounds () { - double extents[] = allInkExtents(); - return new Rectangle2D.Double (extents[0], extents[1], - extents[2], extents[3]); + return allVisual; } public void performDefaultLayout () { } - public void setGlyphPosition (int glyphIndex, Point2D newPos) + public void setGlyphPosition (int i, Point2D newPos) { - // should we be ok twiddling pango's structure here? - throw new UnsupportedOperationException (); + extents[8*i ] = newPos.getX(); + extents[8*i + 1] = newPos.getY(); + + extents[8*i + 4] = newPos.getX(); + extents[8*i + 5] = newPos.getY(); } public void setGlyphTransform (int glyphIndex, @@ -327,8 +319,31 @@ public class GdkGlyphVector extends GlyphVector if (! (gv instanceof GdkGlyphVector)) return false; - GdkGlyphVector ggv = (GdkGlyphVector)gv; - return isEqual(ggv); + GdkGlyphVector ggv = (GdkGlyphVector) gv; + + if ((ggv.codes.length != this.codes.length) + || (ggv.extents.length != this.extents.length)) + return false; + + if ((ggv.font == null && this.font != null) + || (ggv.font != null && this.font == null) + || (!ggv.font.equals(this.font))) + return false; + + if ((ggv.fontRenderContext == null && this.fontRenderContext != null) + || (ggv.fontRenderContext != null && this.fontRenderContext == null) + || (!ggv.fontRenderContext.equals(this.fontRenderContext))) + return false; + + for (int i = 0; i < ggv.codes.length; ++i) + if (ggv.codes[i] != this.codes[i]) + return false; + + for (int i = 0; i < ggv.extents.length; ++i) + if (ggv.extents[i] != this.extents[i]) + return false; + + return true; } public GlyphJustificationInfo getGlyphJustificationInfo(int idx) diff --git a/libjava/gnu/java/awt/peer/gtk/GdkGraphics.java b/libjava/gnu/java/awt/peer/gtk/GdkGraphics.java index 5aacf5296c6..0811287e9b6 100644 --- a/libjava/gnu/java/awt/peer/gtk/GdkGraphics.java +++ b/libjava/gnu/java/awt/peer/gtk/GdkGraphics.java @@ -426,7 +426,8 @@ public class GdkGraphics extends Graphics public void setClip (int x, int y, int width, int height) { - if (component != null && ! component.isRealized ()) + if ((component != null && ! component.isRealized ()) + || clip == null) return; clip.x = x; diff --git a/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java b/libjava/gnu/java/awt/peer/gtk/GdkGraphics2D.java index 82de03d5aec..3bf169cb6f7 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. +/* GdkGraphics2D.java -- + Copyright (C) 2003, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -40,7 +40,6 @@ package gnu.java.awt.peer.gtk; import gnu.classpath.Configuration; import gnu.java.awt.ClasspathToolkit; -import gnu.java.awt.peer.ClasspathFontPeer; import java.awt.AlphaComposite; import java.awt.BasicStroke; @@ -60,17 +59,15 @@ 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.AffineTransform; 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; @@ -78,16 +75,17 @@ import java.awt.image.ColorModel; import java.awt.image.CropImageFilter; import java.awt.image.DataBuffer; import java.awt.image.DataBufferInt; +import java.awt.image.DirectColorModel; 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.MultiPixelPackedSampleModel; import java.awt.image.Raster; import java.awt.image.RenderedImage; +import java.awt.image.SampleModel; import java.awt.image.WritableRaster; -import java.awt.image.renderable.RenderableImage; import java.awt.image.renderable.RenderContext; +import java.awt.image.renderable.RenderableImage; import java.text.AttributedCharacterIterator; import java.util.HashMap; import java.util.Map; @@ -95,7 +93,6 @@ import java.util.Stack; public class GdkGraphics2D extends Graphics2D { - ////////////////////////////////////// ////// State Management Methods ////// ////////////////////////////////////// @@ -103,14 +100,14 @@ public class GdkGraphics2D extends Graphics2D static { if (Configuration.INIT_LOAD_LIBRARY) - { - System.loadLibrary("gtkpeer"); - } + System.loadLibrary("gtkpeer"); - if (GtkToolkit.useGraphics2D ()) - initStaticState (); + if (GtkToolkit.useGraphics2D()) + initStaticState(); } - native static void initStaticState (); + + static native void initStaticState(); + private final int native_state = GtkGenericPeer.getUniqueInteger(); private Paint paint; @@ -120,246 +117,255 @@ public class GdkGraphics2D extends Graphics2D private Shape clip; private AffineTransform transform; private GtkComponentPeer component; - private Font font; + private Font font; private RenderingHints hints; private BufferedImage bimage; - + private boolean pixelConversionRequired; + private int[] pixelBuffer; private Composite comp; - private Stack stateStack; - - native private void initState (GtkComponentPeer component); - native private void initState (int width, int height); - native private void copyState (GdkGraphics2D g); - native public void dispose (); - native private int[] getImagePixels(); - native private void cairoSurfaceSetFilter(int filter); - native void connectSignals (GtkComponentPeer component); - public void finalize () + private native void initState(GtkComponentPeer component); + private native void initState(int width, int height); + private native void initState(int[] pixes, int width, int height); + private native void copyState(GdkGraphics2D g); + public native void dispose(); + private native void cairoSurfaceSetFilter(int filter); + native void connectSignals(GtkComponentPeer component); + + public void finalize() { dispose(); } - public Graphics create () + public Graphics create() { - return new GdkGraphics2D (this); + return new GdkGraphics2D(this); } - public Graphics create (int x, int y, int width, int height) + public Graphics create(int x, int y, int width, int height) { - return new GdkGraphics2D (width, height); + return new GdkGraphics2D(width, height); } - GdkGraphics2D (GdkGraphics2D g) + GdkGraphics2D(GdkGraphics2D g) { paint = g.paint; stroke = g.stroke; - setRenderingHints (g.hints); + setRenderingHints(g.hints); if (g.fg.getAlpha() != -1) - fg = new Color (g.fg.getRed (), g.fg.getGreen (), - g.fg.getBlue (), g.fg.getAlpha ()); - else - fg = new Color (g.fg.getRGB ()); + fg = new Color(g.fg.getRed(), g.fg.getGreen(), g.fg.getBlue(), + g.fg.getAlpha()); + else + fg = new Color(g.fg.getRGB()); if (g.bg.getAlpha() != -1) - bg = new Color(g.bg.getRed (), g.bg.getGreen (), - g.bg.getBlue (), g.bg.getAlpha ()); + bg = new Color(g.bg.getRed(), g.bg.getGreen(), g.bg.getBlue(), + g.bg.getAlpha()); else - bg = new Color (g.bg.getRGB ()); + bg = new Color(g.bg.getRGB()); if (g.clip == null) clip = null; else - clip = new Rectangle (g.getClipBounds ()); + clip = new Rectangle(g.getClipBounds()); if (g.transform == null) - transform = new AffineTransform (); + transform = new AffineTransform(); else - transform = new AffineTransform (g.transform); + transform = new AffineTransform(g.transform); font = g.font; component = g.component; - copyState (g); - - setColor (fg); - setBackground (bg); - setPaint (paint); - setStroke (stroke); - setTransform (transform); - setClip (clip); + copyState(g); + + setColor(fg); + setBackground(bg); + setPaint(paint); + setStroke(stroke); + setTransform(transform); + setClip(clip); stateStack = new Stack(); } - GdkGraphics2D (int width, int height) + GdkGraphics2D(int width, int height) { - initState (width, height); + initState(width, height); setColor(Color.black); - setBackground (Color.black); - setPaint (getColor()); - setFont (new Font("SansSerif", Font.PLAIN, 12)); - setTransform (new AffineTransform ()); - setStroke (new BasicStroke ()); - setRenderingHints (getDefaultHints()); + setBackground(Color.black); + setPaint(getColor()); + setFont(new Font("SansSerif", Font.PLAIN, 12)); + setTransform(new AffineTransform()); + setStroke(new BasicStroke()); + setRenderingHints(getDefaultHints()); stateStack = new Stack(); } - GdkGraphics2D (GtkComponentPeer component) + GdkGraphics2D(GtkComponentPeer component) { this.component = component; - - setFont (new Font("SansSerif", Font.PLAIN, 12)); - - if (component.isRealized ()) - initComponentGraphics2D (); + + if (component.isRealized()) + initComponentGraphics2D(); else - connectSignals (component); + connectSignals(component); } - void initComponentGraphics2D () + void initComponentGraphics2D() { - initState (component); + initState(component); - setColor (component.awtComponent.getForeground ()); - setBackground (component.awtComponent.getBackground ()); - setPaint (getColor()); - setTransform (new AffineTransform ()); - setStroke (new BasicStroke ()); - setRenderingHints (getDefaultHints()); + setColor(component.awtComponent.getForeground()); + setBackground(component.awtComponent.getBackground()); + setPaint(getColor()); + setTransform(new AffineTransform()); + setStroke(new BasicStroke()); + setRenderingHints(getDefaultHints()); + setFont(new Font("SansSerif", Font.PLAIN, 12)); - stateStack = new Stack (); + stateStack = new Stack(); } - GdkGraphics2D (BufferedImage bimage) + GdkGraphics2D(BufferedImage bimage) { - - this.bimage = bimage; - initState (bimage.getWidth(), bimage.getHeight()); + this.bimage = bimage; + this.pixelBuffer = findSimpleIntegerArray(bimage.getColorModel(), + bimage.getRaster()); + if (this.pixelBuffer == null) + { + this.pixelBuffer = new int[bimage.getRaster().getWidth() * bimage.getRaster() + .getHeight()]; + this.pixelConversionRequired = true; + } + else + { + this.pixelConversionRequired = false; + } + + initState(this.pixelBuffer, bimage.getWidth(), bimage.getHeight()); setColor(Color.black); - setBackground (Color.black); - setPaint (getColor()); - setFont (new Font("SansSerif", Font.PLAIN, 12)); - setTransform (new AffineTransform ()); - setStroke (new BasicStroke ()); - setRenderingHints (getDefaultHints()); + setBackground(Color.black); + setPaint(getColor()); + setFont(new Font("SansSerif", Font.PLAIN, 12)); + setTransform(new AffineTransform()); + setStroke(new BasicStroke()); + setRenderingHints(getDefaultHints()); stateStack = new Stack(); - + // draw current buffered image to the pixmap associated - // with it. - - drawImage (bimage, new AffineTransform (1,0,0,1,0,0), bg, null); + // with it, if the image is not equal to our paint buffer. + if (pixelConversionRequired) + drawImage(bimage, new AffineTransform(1, 0, 0, 1, 0, 0), bg, null); } - //////////////////////////////////// ////// Native Drawing Methods ////// //////////////////////////////////// // GDK drawing methods - private native void gdkDrawDrawable (GdkGraphics2D other, int x, int y); + 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, 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, - int r1, int g1, int b1, int a1, - int r2, int g2, int b2, int a2, - boolean cyclic); + 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, + int r1, int g1, int b1, int a1, int r2, + int g2, int b2, int a2, boolean cyclic); // simple passthroughs to cairo - private native void cairoSave (); - private native void cairoRestore (); - private native void cairoSetMatrix (double m[]); - private native void cairoSetOperator (int cairoOperator); - private native void cairoSetRGBColor (double red, double green, double blue); - private native void cairoSetAlpha (double alpha); - private native void cairoSetFillRule (int cairoFillRule); - private native void cairoSetLineWidth (double width); - private native void cairoSetLineCap (int cairoLineCap); - 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 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); - 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); - private native void cairoRectangle (double x, double y, - double width, double height); - private native void cairoClosePath (); - private native void cairoStroke (); - private native void cairoFill (); - private native void cairoClip (); - + private native void cairoSave(); + private native void cairoRestore(); + private native void cairoSetMatrix(double[] m); + private native void cairoSetOperator(int cairoOperator); + private native void cairoSetRGBColor(double red, double green, double blue); + private native void cairoSetAlpha(double alpha); + private native void cairoSetFillRule(int cairoFillRule); + private native void cairoSetLineWidth(double width); + private native void cairoSetLineCap(int cairoLineCap); + 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 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); + 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); + private native void cairoRectangle(double x, double y, double width, + double height); + private native void cairoClosePath(); + private native void cairoStroke(); + private native void cairoFill(); + private native void cairoClip(); ///////////////////////////////////////////// ////// 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; - private Composite comp; - 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; - this.comp = g.comp; - } - 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; - g.comp = this.comp; - } - } - - private void stateSave () + private class DrawState + { + private Paint paint; + private Stroke stroke; + private Color fg; + private Color bg; + private Shape clip; + private AffineTransform transform; + private Font font; + private Composite comp; + + DrawState(GdkGraphics2D g) { - stateStack.push (new DrawState (this)); - cairoSave (); + 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; + this.comp = g.comp; } - private void stateRestore () + public void restore(GdkGraphics2D g) { - ((DrawState)(stateStack.pop ())).restore (this); - cairoRestore (); + 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; + g.comp = this.comp; } + } + + private void stateSave() + { + stateStack.push(new DrawState(this)); + cairoSave(); + } + + private void stateRestore() + { + ((DrawState) (stateStack.pop())).restore(this); + 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. - private boolean shiftDrawCalls = false; + private final double shifted(double coord, boolean doShift) { if (doShift) @@ -372,406 +378,377 @@ public class GdkGraphics2D extends Graphics2D { double x = 0; double y = 0; - double coords[] = new double[6]; + double[] coords = new double[6]; - cairoSetFillRule (p.getWindingRule ()); - for ( ; ! p.isDone (); p.next()) + cairoSetFillRule(p.getWindingRule()); + for (; ! p.isDone(); p.next()) { - int seg = p.currentSegment (coords); - switch(seg) - { - - case PathIterator.SEG_MOVETO: - x = shifted(coords[0], doShift); - y = shifted(coords[1], doShift); - cairoMoveTo (x, y); - break; - - case PathIterator.SEG_LINETO: - x = shifted(coords[0], doShift); - y = shifted(coords[1], doShift); - cairoLineTo (x, y); - break; - - case PathIterator.SEG_QUADTO: - - // splitting a quadratic bezier into a cubic: - // see: http://pfaedit.sourceforge.net/bezier.html - - 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) * (shifted(coords[2], doShift) - x); - double y2 = y1 + (1.0/3.0) * (shifted(coords[3], doShift) - y); - - x = shifted(coords[2], doShift); - y = shifted(coords[3], doShift); - cairoCurveTo (x1, y1, - x2, y2, - x, y); - break; - - case PathIterator.SEG_CUBICTO: - 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: - cairoClosePath (); - break; - } - } + int seg = p.currentSegment(coords); + switch (seg) + { + case PathIterator.SEG_MOVETO: + x = shifted(coords[0], doShift); + y = shifted(coords[1], doShift); + cairoMoveTo(x, y); + break; + case PathIterator.SEG_LINETO: + x = shifted(coords[0], doShift); + y = shifted(coords[1], doShift); + cairoLineTo(x, y); + break; + case PathIterator.SEG_QUADTO: + // splitting a quadratic bezier into a cubic: + // see: http://pfaedit.sourceforge.net/bezier.html + 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) * (shifted(coords[2], doShift) - x); + double y2 = y1 + (1.0 / 3.0) * (shifted(coords[3], doShift) - y); + + x = shifted(coords[2], doShift); + y = shifted(coords[3], doShift); + cairoCurveTo(x1, y1, x2, y2, x, y); + break; + case PathIterator.SEG_CUBICTO: + 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: + cairoClosePath(); + break; + } + } } - private final Map getDefaultHints() { - HashMap defaultHints = new HashMap (); - - defaultHints.put (RenderingHints.KEY_TEXT_ANTIALIASING, - RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT); - - defaultHints.put (RenderingHints.KEY_STROKE_CONTROL, - RenderingHints.VALUE_STROKE_DEFAULT); - - defaultHints.put (RenderingHints.KEY_FRACTIONALMETRICS, - RenderingHints.VALUE_FRACTIONALMETRICS_OFF); - - defaultHints.put (RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_OFF); - - defaultHints.put (RenderingHints.KEY_RENDERING, - RenderingHints.VALUE_RENDER_DEFAULT); - + HashMap defaultHints = new HashMap(); + + defaultHints.put(RenderingHints.KEY_TEXT_ANTIALIASING, + RenderingHints.VALUE_TEXT_ANTIALIAS_DEFAULT); + + defaultHints.put(RenderingHints.KEY_STROKE_CONTROL, + RenderingHints.VALUE_STROKE_DEFAULT); + + defaultHints.put(RenderingHints.KEY_FRACTIONALMETRICS, + RenderingHints.VALUE_FRACTIONALMETRICS_OFF); + + defaultHints.put(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_OFF); + + defaultHints.put(RenderingHints.KEY_RENDERING, + RenderingHints.VALUE_RENDER_DEFAULT); + return defaultHints; - } - private final void updateBufferedImage() + public static final int[] findSimpleIntegerArray (ColorModel cm, Raster raster) { - int[] pixels = getImagePixels(); - updateImagePixels(pixels); - } + if (cm == null || raster == null) + return null; - - private final boolean isBufferedImageGraphics () - { - return bimage != null; - } - - private final void updateImagePixels (int[] pixels) - { + if (! cm.getColorSpace().isCS_sRGB()) + return null; - // This function can only be used if - // this graphics object is used to draw into - // buffered image - - if (! isBufferedImageGraphics ()) - return; + if (! (cm instanceof DirectColorModel)) + return null; - WritableRaster raster = bimage.getRaster(); - DataBuffer db = raster.getDataBuffer (); + DirectColorModel dcm = (DirectColorModel) cm; - // update pixels in the bufferedImage + if (dcm.getRedMask() != 0x00FF0000 || dcm.getGreenMask() != 0x0000FF00 + || dcm.getBlueMask() != 0x000000FF) + return null; - if (raster.getSampleModel ().getDataType () == DataBuffer.TYPE_INT - && db instanceof DataBufferInt - && db.getNumBanks () == 1) - { + if (! (raster instanceof WritableRaster)) + return null; - // single bank, ARGB-ints buffer in sRGB space - DataBufferInt dbi = (DataBufferInt) raster.getDataBuffer (); + if (raster.getSampleModel().getDataType() != DataBuffer.TYPE_INT) + return null; - for (int i=0; i < pixels.length; i++) - dbi.setElem(i, pixels[i]); - - } - else - { - bimage.getRaster().setPixels (0, 0, raster.getWidth (), - raster.getHeight (), pixels); - } - } + if (! (raster.getDataBuffer() instanceof DataBufferInt)) + return null; + DataBufferInt db = (DataBufferInt) raster.getDataBuffer(); - private final boolean drawImage(Image img, - AffineTransform xform, - Color bgcolor, - ImageObserver obs) + if (db.getNumBanks() != 1) + return null; + + // Finally, we have determined that this is a single bank, [A]RGB-int + // buffer in sRGB space. It's worth checking all this, because it means + // that cairo can paint directly into the data buffer, which is very + // fast compared to all the normal copying and converting. + + return db.getData(); + } + + private final void updateBufferedImage() { + if (bimage != null && pixelConversionRequired) + { + int height = bimage.getHeight(); + int width = bimage.getWidth(); + for (int y = 0; y < height; ++y) + for (int x = 0; x < width; ++x) + bimage.setRGB(x, y, pixelBuffer[y*width+height]); + } + } + 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 - || xform.getType () == AffineTransform.TYPE_IDENTITY - || xform.getType () == AffineTransform.TYPE_TRANSLATION) - ) + if (img instanceof GtkOffScreenImage + && img.getGraphics() instanceof GdkGraphics2D + && (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, (int)xform.getTranslateX(), (int)xform.getTranslateY()); - - if (isBufferedImageGraphics ()) - updateBufferedImage(); - - return true; + // we are being asked to flush a double buffer from Gdk + GdkGraphics2D g2 = (GdkGraphics2D) img.getGraphics(); + gdkDrawDrawable(g2, (int) xform.getTranslateX(), + (int) xform.getTranslateY()); + + updateBufferedImage(); + + 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 - // to map "user coordinates" to "pixel" coordinates, which is the - // other way around. Therefore to get the "user -> pixel" transform - // that cairo wants from "image -> user" transform that we currently - // have, we will need to invert the transformation matrix. - - AffineTransform invertedXform = new AffineTransform(); - - try - { - 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); - } - else - { - return this.drawImage(GdkPixbufDecoder.createBufferedImage(img.getSource()), - xform, bgcolor,obs); - } - } - catch (NoninvertibleTransformException e) - { - throw new ImagingOpException("Unable to invert transform " - + xform.toString()); - } + { + // 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 + // to map "user coordinates" to "pixel" coordinates, which is the + // other way around. Therefore to get the "user -> pixel" transform + // that cairo wants from "image -> user" transform that we currently + // have, we will need to invert the transformation matrix. + AffineTransform invertedXform = new AffineTransform(); + + try + { + 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); + } + else + return this.drawImage(GdkPixbufDecoder.createBufferedImage(img + .getSource()), + xform, bgcolor, obs); + } + catch (NoninvertibleTransformException e) + { + throw new ImagingOpException("Unable to invert transform " + + xform.toString()); + } } } - ////////////////////////////////////////////////// ////// Implementation of Graphics2D Methods ////// ////////////////////////////////////////////////// - public void draw (Shape s) + public void draw(Shape s) { - - if (stroke != null && - !(stroke instanceof BasicStroke)) + if (stroke != null && ! (stroke instanceof BasicStroke)) { - fill (stroke.createStrokedShape (s)); - return; + fill(stroke.createStrokedShape(s)); + return; } - cairoNewPath (); - + cairoNewPath(); + if (s instanceof Rectangle2D) { - Rectangle2D r = (Rectangle2D)s; - cairoRectangle (shifted(r.getX (), shiftDrawCalls), - shifted(r.getY (), shiftDrawCalls), - r.getWidth (), r.getHeight ()); + Rectangle2D r = (Rectangle2D) s; + cairoRectangle(shifted(r.getX(), shiftDrawCalls), + shifted(r.getY(), shiftDrawCalls), r.getWidth(), + r.getHeight()); } - else - walkPath (s.getPathIterator (null), shiftDrawCalls); - cairoStroke (); - - if (isBufferedImageGraphics ()) - updateBufferedImage(); + else + walkPath(s.getPathIterator(null), shiftDrawCalls); + cairoStroke(); + + updateBufferedImage(); } - public void fill (Shape s) + public void fill(Shape s) { - cairoNewPath (); + cairoNewPath(); if (s instanceof Rectangle2D) { - Rectangle2D r = (Rectangle2D)s; - cairoRectangle (r.getX (), r.getY (), r.getWidth (), r.getHeight ()); + Rectangle2D r = (Rectangle2D) s; + cairoRectangle(r.getX(), r.getY(), r.getWidth(), r.getHeight()); } - else - walkPath (s.getPathIterator (null), false); - cairoFill (); - - if (isBufferedImageGraphics ()) - updateBufferedImage(); + else + walkPath(s.getPathIterator(null), false); + + cairoFill(); + updateBufferedImage(); } - public void clip (Shape s) + public void clip(Shape s) { - // update it + // 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(); - if (clip == null || s == null) - clip = s; - else if (s instanceof Rectangle2D - && clip instanceof Rectangle2D) + // draw it + if (clip != null) + { + cairoNewPath(); + if (clip instanceof Rectangle2D) { - Rectangle2D r = (Rectangle2D)s; - Rectangle2D curr = (Rectangle2D)clip; - clip = curr.createIntersection (r); + Rectangle2D r = (Rectangle2D) clip; + cairoRectangle(r.getX(), r.getY(), r.getWidth(), r.getHeight()); } - else - throw new UnsupportedOperationException (); + else + walkPath(clip.getPathIterator(null), false); - // 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), false); - // cairoClosePath (); - cairoClip (); - } + // cairoClosePath (); + cairoClip(); + } } - public Paint getPaint () + public Paint getPaint() { return paint; } - public AffineTransform getTransform () + public AffineTransform getTransform() { - return (AffineTransform) transform.clone (); + return (AffineTransform) transform.clone(); } - public void setPaint (Paint p) + public void setPaint(Paint p) { if (paint == null) - return; - + return; + paint = p; if (paint instanceof Color) { - setColor ((Color) paint); + setColor((Color) paint); } else if (paint instanceof TexturePaint) { - TexturePaint tp = (TexturePaint) paint; - BufferedImage img = tp.getImage (); - - // map the image to the anchor rectangle + TexturePaint tp = (TexturePaint) paint; + BufferedImage img = tp.getImage(); - int width = (int) tp.getAnchorRect ().getWidth (); - int height = (int) tp.getAnchorRect ().getHeight (); - - double scaleX = width / (double) img.getWidth (); - double scaleY = width / (double) img.getHeight (); - - AffineTransform at = new AffineTransform (scaleX, 0, 0, scaleY, 0, 0); - AffineTransformOp op = new AffineTransformOp (at, getRenderingHints()); - BufferedImage texture = op.filter(img, null); - int pixels[] = texture.getRGB (0, 0, width, height, null, 0, width); - setTexturePixels (pixels, width, height, width); + // map the image to the anchor rectangle + int width = (int) tp.getAnchorRect().getWidth(); + int height = (int) tp.getAnchorRect().getHeight(); + + double scaleX = width / (double) img.getWidth(); + double scaleY = width / (double) img.getHeight(); + AffineTransform at = new AffineTransform(scaleX, 0, 0, scaleY, 0, 0); + AffineTransformOp op = new AffineTransformOp(at, getRenderingHints()); + BufferedImage texture = op.filter(img, null); + int[] pixels = texture.getRGB(0, 0, width, height, null, 0, width); + setTexturePixels(pixels, width, height, width); } else if (paint instanceof GradientPaint) { - GradientPaint gp = (GradientPaint) paint; - Point2D p1 = gp.getPoint1 (); - Point2D p2 = gp.getPoint2 (); - Color c1 = gp.getColor1 (); - Color c2 = gp.getColor2 (); - setGradient (p1.getX (), p1.getY (), - p2.getX (), p2.getY (), - c1.getRed (), c1.getGreen (), - c1.getBlue (), c1.getAlpha (), - c2.getRed (), c2.getGreen (), - c2.getBlue (), c2.getAlpha (), - gp.isCyclic ()); + GradientPaint gp = (GradientPaint) paint; + Point2D p1 = gp.getPoint1(); + Point2D p2 = gp.getPoint2(); + Color c1 = gp.getColor1(); + Color c2 = gp.getColor2(); + setGradient(p1.getX(), p1.getY(), p2.getX(), p2.getY(), c1.getRed(), + c1.getGreen(), c1.getBlue(), c1.getAlpha(), c2.getRed(), + c2.getGreen(), c2.getBlue(), c2.getAlpha(), gp.isCyclic()); } else - throw new java.lang.UnsupportedOperationException (); + throw new java.lang.UnsupportedOperationException(); } - public void setTransform (AffineTransform tx) + public void setTransform(AffineTransform tx) { transform = tx; if (transform != null) { - double m[] = new double[6]; - transform.getMatrix (m); - cairoSetMatrix (m); + double[] m = new double[6]; + transform.getMatrix(m); + cairoSetMatrix(m); } } - public void transform (AffineTransform tx) + public void transform(AffineTransform tx) { if (transform == null) - transform = new AffineTransform (tx); + transform = new AffineTransform(tx); else - transform.concatenate (tx); - setTransform (transform); + transform.concatenate(tx); + setTransform(transform); if (clip != null) { - // FIXME: this should actuall try to transform the shape - // rather than degrade to bounds. - Rectangle2D r = clip.getBounds2D(); - double[] coords = new double[] { r.getX(), r.getY(), - r.getX() + r.getWidth(), - r.getY() + r.getHeight() }; - try - { - tx.createInverse().transform(coords, 0, coords, 0, 2); - r.setRect(coords[0], coords[1], - coords[2] - coords[0], - coords[3] - coords[1]); - clip = r; - } - catch (java.awt.geom.NoninvertibleTransformException e) - { - } + // FIXME: this should actuall try to transform the shape + // rather than degrade to bounds. + Rectangle2D r = clip.getBounds2D(); + double[] coords = new double[] + { + r.getX(), r.getY(), r.getX() + r.getWidth(), + r.getY() + r.getHeight() + }; + try + { + tx.createInverse().transform(coords, 0, coords, 0, 2); + r.setRect(coords[0], coords[1], coords[2] - coords[0], + coords[3] - coords[1]); + clip = r; + } + catch (java.awt.geom.NoninvertibleTransformException e) + { + } } } public void rotate(double theta) { - transform (AffineTransform.getRotateInstance (theta)); + transform(AffineTransform.getRotateInstance(theta)); } public void rotate(double theta, double x, double y) { - transform (AffineTransform.getRotateInstance (theta, x, y)); + transform(AffineTransform.getRotateInstance(theta, x, y)); } public void scale(double sx, double sy) { - transform (AffineTransform.getScaleInstance (sx, sy)); + transform(AffineTransform.getScaleInstance(sx, sy)); } - public void translate (double tx, double ty) + public void translate(double tx, double ty) { - transform (AffineTransform.getTranslateInstance (tx, ty)); + transform(AffineTransform.getTranslateInstance(tx, ty)); } - public void translate (int x, int y) + public void translate(int x, int y) { - translate ((double) x, (double) y); + translate((double) x, (double) y); } public void shear(double shearX, double shearY) { - transform (AffineTransform.getShearInstance (shearX, shearY)); + transform(AffineTransform.getShearInstance(shearX, shearY)); } public Stroke getStroke() @@ -779,173 +756,165 @@ public class GdkGraphics2D extends Graphics2D return stroke; } - public void setStroke (Stroke st) + public void setStroke(Stroke st) { stroke = st; if (stroke instanceof BasicStroke) { - BasicStroke bs = (BasicStroke) stroke; - cairoSetLineCap (bs.getEndCap()); - cairoSetLineWidth (bs.getLineWidth()); - cairoSetLineJoin (bs.getLineJoin()); - cairoSetMiterLimit (bs.getMiterLimit()); - float dashes[] = bs.getDashArray(); - if (dashes != null) - { - double double_dashes[] = new double[dashes.length]; - for (int i = 0; i < dashes.length; i++) - double_dashes[i] = dashes[i]; - cairoSetDash (double_dashes, double_dashes.length, - (double) bs.getDashPhase ()); - } + BasicStroke bs = (BasicStroke) stroke; + cairoSetLineCap(bs.getEndCap()); + cairoSetLineWidth(bs.getLineWidth()); + cairoSetLineJoin(bs.getLineJoin()); + cairoSetMiterLimit(bs.getMiterLimit()); + float[] dashes = bs.getDashArray(); + if (dashes != null) + { + double[] double_dashes = new double[dashes.length]; + for (int i = 0; i < dashes.length; i++) + double_dashes[i] = dashes[i]; + cairoSetDash(double_dashes, double_dashes.length, + (double) bs.getDashPhase()); + } } } - //////////////////////////////////////////////// ////// Implementation of Graphics Methods ////// //////////////////////////////////////////////// - public void setPaintMode () - { - setComposite (java.awt.AlphaComposite.SrcOver); + public void setPaintMode() + { + setComposite(java.awt.AlphaComposite.SrcOver); } - public void setXORMode (Color c) - { - setComposite (new gnu.java.awt.BitwiseXORComposite(c)); + public void setXORMode(Color c) + { + setComposite(new gnu.java.awt.BitwiseXORComposite(c)); } - public void setColor (Color c) + public void setColor(Color c) { if (c == null) c = Color.BLACK; - + fg = c; paint = c; - cairoSetRGBColor (fg.getRed() / 255.0, - fg.getGreen() / 255.0, - fg.getBlue() / 255.0); - cairoSetAlpha ((fg.getAlpha() & 255) / 255.0); + cairoSetRGBColor(fg.getRed() / 255.0, fg.getGreen() / 255.0, + fg.getBlue() / 255.0); + cairoSetAlpha((fg.getAlpha() & 255) / 255.0); } - public Color getColor () + public Color getColor() { return fg; } - public void clipRect (int x, int y, int width, int height) + public void clipRect(int x, int y, int width, int height) { - clip (new Rectangle (x, y, width, height)); + clip(new Rectangle(x, y, width, height)); } - public Shape getClip () + public Shape getClip() { - return getClipInDevSpace (); + return clip.getBounds2D(); //getClipInDevSpace(); } - public Rectangle getClipBounds () + public Rectangle getClipBounds() { if (clip == null) return null; else - return clip.getBounds (); + return clip.getBounds(); } - protected Rectangle2D getClipInDevSpace () + protected Rectangle2D getClipInDevSpace() { - Rectangle2D uclip = clip.getBounds2D (); + 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 ()); + 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) + public void setClip(int x, int y, int width, int height) { - setClip(new Rectangle2D.Double ((double)x, (double)y, - (double)width, (double)height)); + setClip(new Rectangle2D.Double((double) x, (double) y, (double) width, + (double) height)); } - - public void setClip (Shape s) + + public void setClip(Shape s) { clip = s; if (s != null) { - cairoNewPath (); - if (s instanceof Rectangle2D) - { - Rectangle2D r = (Rectangle2D)s; - cairoRectangle (r.getX (), r.getY (), - r.getWidth (), r.getHeight ()); - } - else - walkPath (s.getPathIterator (null), false); - // cairoClosePath (); - cairoClip (); + cairoNewPath(); + if (s instanceof Rectangle2D) + { + Rectangle2D r = (Rectangle2D) s; + cairoRectangle(r.getX(), r.getY(), r.getWidth(), r.getHeight()); + } + else + 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) + public void draw3DRect(int x, int y, int width, int height, boolean raised) { Stroke tmp = stroke; setStroke(draw3DRectStroke); super.draw3DRect(x, y, width, height, raised); - setStroke(tmp); - if (isBufferedImageGraphics ()) - updateBufferedImage(); + setStroke(tmp); + updateBufferedImage(); } - public void fill3DRect(int x, int y, int width, - int height, boolean raised) + public void fill3DRect(int x, int y, int width, int height, boolean raised) { Stroke tmp = stroke; setStroke(draw3DRectStroke); super.fill3DRect(x, y, width, height, raised); - setStroke(tmp); - if (isBufferedImageGraphics ()) - updateBufferedImage(); + setStroke(tmp); + updateBufferedImage(); } - - public void drawRect (int x, int y, int width, int height) + public void drawRect(int x, int y, int width, int height) { - draw(new Rectangle (x, y, width, height)); + draw(new Rectangle(x, y, width, height)); } - public void fillRect (int x, int y, int width, int height) + public void fillRect(int x, int y, int width, int height) { - cairoNewPath (); - cairoRectangle (x, y, width, height); - cairoFill (); + cairoNewPath(); + cairoRectangle(x, y, width, height); + cairoFill(); } - public void clearRect (int x, int y, int width, int height) + public void clearRect(int x, int y, int width, int height) { - cairoSetRGBColor (bg.getRed() / 255.0, - bg.getGreen() / 255.0, - bg.getBlue() / 255.0); - cairoSetAlpha (1.0); - cairoNewPath (); - cairoRectangle (x, y, width, height); - cairoFill (); - setColor (fg); - - if (isBufferedImageGraphics ()) - updateBufferedImage(); + cairoSetRGBColor(bg.getRed() / 255.0, bg.getGreen() / 255.0, + bg.getBlue() / 255.0); + cairoSetAlpha(1.0); + cairoNewPath(); + cairoRectangle(x, y, width, height); + cairoFill(); + setColor(fg); + updateBufferedImage(); } public void setBackground(Color c) @@ -958,181 +927,172 @@ public class GdkGraphics2D extends Graphics2D return bg; } - private final void doPolygon(int[] xPoints, int[] yPoints, int nPoints, + private final void doPolygon(int[] xPoints, int[] yPoints, int nPoints, boolean close, boolean fill) - { + { if (nPoints < 1) return; - GeneralPath gp = new GeneralPath (PathIterator.WIND_EVEN_ODD); - gp.moveTo ((float)xPoints[0], (float)yPoints[0]); + GeneralPath gp = new GeneralPath(PathIterator.WIND_EVEN_ODD); + gp.moveTo((float) xPoints[0], (float) yPoints[0]); for (int i = 1; i < nPoints; i++) - gp.lineTo ((float)xPoints[i], (float)yPoints[i]); - + gp.lineTo((float) xPoints[i], (float) yPoints[i]); + if (close) - gp.closePath (); + gp.closePath(); Shape sh = gp; - if (fill == false && - stroke != null && - !(stroke instanceof BasicStroke)) + if (fill == false && stroke != null && ! (stroke instanceof BasicStroke)) { - sh = stroke.createStrokedShape (gp); - fill = true; + sh = stroke.createStrokedShape(gp); + fill = true; } - - if (fill) - fill (sh); - else - draw (sh); + + if (fill) + fill(sh); + else + draw(sh); } - public void drawLine (int x1, int y1, int x2, int y2) + public void drawLine(int x1, int y1, int x2, int y2) { - int xp[] = new int[2]; - int yp[] = new int[2]; + int[] xp = new int[2]; + int[] yp = new int[2]; xp[0] = x1; xp[1] = x2; yp[0] = y1; yp[1] = y2; - - doPolygon (xp, yp, 2, false, false); + + doPolygon(xp, yp, 2, false, false); } public void fillPolygon(int[] xPoints, int[] yPoints, int nPoints) { - doPolygon (xPoints, yPoints, nPoints, true, true); + doPolygon(xPoints, yPoints, nPoints, true, true); } - + public void drawPolygon(int[] xPoints, int[] yPoints, int nPoints) - { - doPolygon (xPoints, yPoints, nPoints, true, false); + { + doPolygon(xPoints, yPoints, nPoints, true, false); } public void drawPolyline(int[] xPoints, int[] yPoints, int nPoints) { - doPolygon (xPoints, yPoints, nPoints, false, false); + doPolygon(xPoints, yPoints, nPoints, false, false); } - private final 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; - SampleModel sm = r.getSampleModel (); - DataBuffer db = r.getDataBuffer (); + SampleModel sm = r.getSampleModel(); + DataBuffer db = r.getDataBuffer(); if (db == null || sm == null) return false; if (cm == null) - cm = ColorModel.getRGBdefault (); + 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[4] = 0; i2u[5] = 0; + i2u[0] = 1; + i2u[1] = 0; + i2u[2] = 0; + i2u[3] = 1; + i2u[4] = 0; + i2u[5] = 0; } - int pixels[] = null; + int[] pixels = findSimpleIntegerArray(cm, r); - if (sm.getDataType () == DataBuffer.TYPE_INT && - db instanceof DataBufferInt && - db.getNumBanks () == 1) + if (pixels == null) { - // single bank, ARGB-ints buffer in sRGB space - DataBufferInt dbi = (DataBufferInt)db; - pixels = dbi.getData (); + // FIXME: I don't think this code will work correctly with a non-RGB + // MultiPixelPackedSampleModel. Although this entire method should + // probably be rewritten to better utilize Cairo's different supported + // data formats. + if (sm instanceof MultiPixelPackedSampleModel) + { + pixels = r.getPixels(0, 0, r.getWidth(), r.getHeight(), pixels); + for (int i = 0; i < pixels.length; i++) + pixels[i] = cm.getRGB(pixels[i]); + } + else + { + pixels = new int[r.getWidth() * r.getHeight()]; + for (int i = 0; i < pixels.length; i++) + pixels[i] = cm.getRGB(db.getElem(i)); + } } - else - pixels = r.getPixels (0, 0, r.getWidth (), r.getHeight (), pixels); - - ColorSpace cs = cm.getColorSpace (); - if (cs != null && - cs.getType () != ColorSpace.CS_sRGB) + + // Change all transparent pixels in the image to the specified bgcolor, + // or (if there's no alpha) fill in an alpha channel so that it paints + // correctly. + if (cm.hasAlpha()) { - int pixels2[] = new int[pixels.length]; - for (int i = 0; i < pixels2.length; i++) - pixels2[i] = cm.getRGB (pixels[i]); - pixels = pixels2; + if (bgcolor != null && cm.hasAlpha()) + for (int i = 0; i < pixels.length; i++) + { + if (cm.getAlpha(pixels[i]) == 0) + pixels[i] = bgcolor.getRGB(); + } } - - // change all transparent pixels in the image to the - // specified bgcolor - - if (bgcolor != null) - { - for (int i = 0; i < pixels.length; i++) - { - if (cm.getAlpha (pixels[i]) == 0) - pixels[i] = bgcolor.getRGB (); - } - } - - drawPixels (pixels, r.getWidth (), r.getHeight (), r.getWidth (), i2u); - - if (isBufferedImageGraphics ()) - updateBufferedImage(); + else + for (int i = 0; i < pixels.length; i++) + pixels[i] |= 0xFF000000; + + drawPixels(pixels, r.getWidth(), r.getHeight(), r.getWidth(), i2u); + + updateBufferedImage(); return true; } - public void drawRenderedImage(RenderedImage image, - AffineTransform xform) + public void drawRenderedImage(RenderedImage image, AffineTransform xform) { - drawRaster (image.getColorModel(), image.getData(), xform, bg); + drawRaster(image.getColorModel(), image.getData(), xform, bg); } - - public void drawRenderableImage(RenderableImage image, - AffineTransform xform) + + public void drawRenderableImage(RenderableImage image, AffineTransform xform) { - drawRenderedImage (image.createRendering (new RenderContext (xform)), xform); + drawRenderedImage(image.createRendering(new RenderContext(xform)), xform); } - - public boolean drawImage(Image img, - AffineTransform xform, - ImageObserver obs) + + public boolean drawImage(Image img, AffineTransform xform, ImageObserver obs) { - return drawImage(img, xform, bg, obs); + return drawImage(img, xform, bg, obs); } - public void drawImage(BufferedImage image, - BufferedImageOp op, - int x, - int y) + 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), bg, null); + drawImage(filtered, new AffineTransform(1f, 0f, 0f, 1f, x, y), bg, null); } - public boolean drawImage (Image img, int x, int y, - ImageObserver observer) + public boolean drawImage(Image img, int x, int y, ImageObserver observer) { - return drawImage(img, new AffineTransform(1f,0f,0f,1f,x,y), bg, observer); + return drawImage(img, new AffineTransform(1f, 0f, 0f, 1f, x, y), bg, + observer); } - /////////////////////////////////////////////// ////// Unimplemented Stubs and Overloads ////// /////////////////////////////////////////////// - - - public boolean hit(Rectangle rect, Shape text, - boolean onStroke) + public boolean hit(Rectangle rect, Shape text, boolean onStroke) { - throw new java.lang.UnsupportedOperationException (); + throw new java.lang.UnsupportedOperationException(); } public GraphicsConfiguration getDeviceConfiguration() { - throw new java.lang.UnsupportedOperationException (); + throw new java.lang.UnsupportedOperationException(); } public void setComposite(Composite comp) @@ -1141,87 +1101,81 @@ public class GdkGraphics2D extends Graphics2D if (comp instanceof AlphaComposite) { - AlphaComposite a = (AlphaComposite) comp; - cairoSetOperator(a.getRule()); - Color c = getColor(); - setColor(new Color(c.getRed(), - c.getGreen(), - c.getBlue(), - (int) (a.getAlpha() * ((float) c.getAlpha())))); + AlphaComposite a = (AlphaComposite) comp; + cairoSetOperator(a.getRule()); + Color c = getColor(); + setColor(new Color(c.getRed(), c.getGreen(), c.getBlue(), + (int) (a.getAlpha() * ((float) c.getAlpha())))); } else - throw new java.lang.UnsupportedOperationException (); + throw new java.lang.UnsupportedOperationException(); } - public void setRenderingHint(RenderingHints.Key hintKey, - Object hintValue) + public void setRenderingHint(RenderingHints.Key hintKey, Object hintValue) { - hints.put (hintKey, hintValue); - + hints.put(hintKey, hintValue); + if (hintKey.equals(RenderingHints.KEY_INTERPOLATION) - || hintKey.equals(RenderingHints.KEY_ALPHA_INTERPOLATION)) + || hintKey.equals(RenderingHints.KEY_ALPHA_INTERPOLATION)) { - - if (hintValue.equals(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR)) - cairoSurfaceSetFilter(0); - - else if (hintValue.equals(RenderingHints.VALUE_INTERPOLATION_BILINEAR)) - cairoSurfaceSetFilter(1); - - else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED)) - cairoSurfaceSetFilter(2); - - else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY)) - cairoSurfaceSetFilter(3); - - else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT)) - cairoSurfaceSetFilter(4); - + if (hintValue.equals(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR)) + cairoSurfaceSetFilter(0); + + else if (hintValue.equals(RenderingHints.VALUE_INTERPOLATION_BILINEAR)) + cairoSurfaceSetFilter(1); + + else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED)) + cairoSurfaceSetFilter(2); + + else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY)) + cairoSurfaceSetFilter(3); + + else if (hintValue.equals(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT)) + cairoSurfaceSetFilter(4); } - shiftDrawCalls = hints.containsValue (RenderingHints.VALUE_STROKE_NORMALIZE) - || hints.containsValue (RenderingHints.VALUE_STROKE_DEFAULT); - + shiftDrawCalls = hints.containsValue(RenderingHints.VALUE_STROKE_NORMALIZE) + || hints.containsValue(RenderingHints.VALUE_STROKE_DEFAULT); } public Object getRenderingHint(RenderingHints.Key hintKey) { - return hints.get (hintKey); + return hints.get(hintKey); } - + public void setRenderingHints(Map hints) { - this.hints = new RenderingHints (getDefaultHints ()); - this.hints.add (new RenderingHints (hints)); - - if (hints.containsKey(RenderingHints.KEY_INTERPOLATION)) + this.hints = new RenderingHints(getDefaultHints()); + this.hints.add(new RenderingHints(hints)); + + if (hints.containsKey(RenderingHints.KEY_INTERPOLATION)) + { + if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR)) + cairoSurfaceSetFilter(0); + + else if (hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BILINEAR)) + cairoSurfaceSetFilter(1); + } + + if (hints.containsKey(RenderingHints.KEY_ALPHA_INTERPOLATION)) { - if(hints.containsValue(RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR)) - cairoSurfaceSetFilter(0); - - else if(hints.containsValue(RenderingHints.VALUE_INTERPOLATION_BILINEAR)) - cairoSurfaceSetFilter(1); + if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED)) + cairoSurfaceSetFilter(2); + + else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY)) + cairoSurfaceSetFilter(3); + + else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT)) + cairoSurfaceSetFilter(4); } - - if (hints.containsKey(RenderingHints.KEY_ALPHA_INTERPOLATION)) - { - if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_SPEED)) - cairoSurfaceSetFilter(2); - - else if (hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY)) - cairoSurfaceSetFilter(3); - - else if(hints.containsValue(RenderingHints.VALUE_ALPHA_INTERPOLATION_DEFAULT)) - cairoSurfaceSetFilter(4); - } - - shiftDrawCalls = hints.containsValue (RenderingHints.VALUE_STROKE_NORMALIZE) - || hints.containsValue (RenderingHints.VALUE_STROKE_DEFAULT); + + shiftDrawCalls = hints.containsValue(RenderingHints.VALUE_STROKE_NORMALIZE) + || hints.containsValue(RenderingHints.VALUE_STROKE_DEFAULT); } public void addRenderingHints(Map hints) { - this.hints.add (new RenderingHints (hints)); + this.hints.add(new RenderingHints(hints)); } public RenderingHints getRenderingHints() @@ -1237,70 +1191,62 @@ public class GdkGraphics2D extends Graphics2D return comp; } - public FontRenderContext getFontRenderContext () + public FontRenderContext getFontRenderContext() { - return new FontRenderContext (transform, true, true); + return new FontRenderContext(transform, true, true); } - public void copyArea (int x, int y, int width, int height, int dx, int dy) + public void copyArea(int x, int y, int width, int height, int dx, int dy) { - throw new java.lang.UnsupportedOperationException (); + throw new java.lang.UnsupportedOperationException(); } - public void drawArc (int x, int y, int width, int height, - int startAngle, int arcAngle) + public void drawArc(int x, int y, int width, int height, int startAngle, + int arcAngle) { - draw (new Arc2D.Double((double)x, (double)y, - (double)width, (double)height, - (double)startAngle, (double)arcAngle, - Arc2D.OPEN)); + 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, - ImageObserver observer) + public boolean drawImage(Image img, int x, int y, Color bgcolor, + ImageObserver observer) { - return drawImage (img, x, y, img.getWidth (observer), - img.getHeight (observer), bgcolor, observer); + return drawImage(img, x, y, img.getWidth(observer), + img.getHeight(observer), bgcolor, observer); } - public boolean drawImage (Image img, int x, int y, int width, int height, - Color bgcolor, ImageObserver observer) + public boolean drawImage(Image img, int x, int y, int width, int height, + Color bgcolor, ImageObserver observer) { - - double scaleX = width / (double) img.getWidth (observer); - double scaleY = height / (double) img.getHeight (observer); - - return drawImage (img, - new AffineTransform(scaleX, 0f, 0f, scaleY, x, y), - bgcolor, - observer); + double scaleX = width / (double) img.getWidth(observer); + double scaleY = height / (double) img.getHeight(observer); + return drawImage(img, new AffineTransform(scaleX, 0f, 0f, scaleY, x, y), + bgcolor, observer); } - public boolean drawImage (Image img, int x, int y, int width, int height, - ImageObserver observer) + public boolean drawImage(Image img, int x, int y, int width, int height, + ImageObserver observer) { - - return drawImage (img, x, y, width, height, bg, observer); - + return drawImage(img, x, y, width, height, bg, observer); } - public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2, - int sx1, int sy1, int sx2, int sy2, - Color bgcolor, ImageObserver observer) + public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, Color bgcolor, + ImageObserver observer) { - if (img == null) return false; - Image subImage; - + Image subImage; + int sourceWidth = sx2 - sx1; - int sourceHeight = sy2 - sy1; - + int sourceHeight = sy2 - sy1; + int destWidth = dx2 - dx1; int destHeight = dy2 - dy1; - + double scaleX = destWidth / (double) sourceWidth; double scaleY = destHeight / (double) sourceHeight; @@ -1309,48 +1255,42 @@ public class GdkGraphics2D extends Graphics2D if (img instanceof BufferedImage) { - - BufferedImage b = (BufferedImage) img; - subImage = b.getSubimage(sx1,sy1,sx2,sy2); - } - else + BufferedImage b = (BufferedImage) img; + subImage = b.getSubimage(sx1, sy1, sx2, sy2); + } + else { - - // FIXME: This code currently doesn't work. Null Pointer - // exception is thrown in this case. This happens - // because img.getSource() always returns null, since source gets - // never initialized when it is created with the help of - // createImage(int width, int height). - - CropImageFilter filter = new CropImageFilter(sx1,sx2,sx2,sy2); - FilteredImageSource src = new FilteredImageSource(img.getSource(), - filter); - - subImage = Toolkit.getDefaultToolkit().createImage(src); + // FIXME: This code currently doesn't work. Null Pointer + // exception is thrown in this case. This happens + // because img.getSource() always returns null, since source gets + // never initialized when it is created with the help of + // createImage(int width, int height). + CropImageFilter filter = new CropImageFilter(sx1, sx2, sx2, sy2); + FilteredImageSource src = new FilteredImageSource(img.getSource(), + filter); + + subImage = Toolkit.getDefaultToolkit().createImage(src); } - return drawImage(subImage, new AffineTransform(scaleX, 0, 0, - scaleY, dx1, dy1), - bgcolor, - observer); + return drawImage(subImage, + new AffineTransform(scaleX, 0, 0, scaleY, dx1, dy1), + bgcolor, observer); } - public boolean drawImage (Image img, int dx1, int dy1, int dx2, int dy2, - int sx1, int sy1, int sx2, int sy2, - ImageObserver observer) + public boolean drawImage(Image img, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, + ImageObserver observer) { - - return drawImage (img, dx1, dy1, dx2, dy2, - sx1, sy1, sx2, sy2, bg, observer); + return drawImage(img, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, bg, observer); } public void drawOval(int x, int y, int width, int height) { - drawArc (x, y, width, height, 0, 360); + drawArc(x, y, width, height, 0, 360); } - public void drawRoundRect(int x, int y, int width, int height, - int arcWidth, int arcHeight) + public void drawRoundRect(int x, int y, int width, int height, int arcWidth, + int arcHeight) { if (arcWidth > width) arcWidth = width; @@ -1360,93 +1300,89 @@ public class GdkGraphics2D extends Graphics2D int xx = x + width - arcWidth; int yy = y + height - arcHeight; - drawArc (x, y, arcWidth, arcHeight, 90, 90); - drawArc (xx, y, arcWidth, arcHeight, 0, 90); - drawArc (xx, yy, arcWidth, arcHeight, 270, 90); - drawArc (x, yy, arcWidth, arcHeight, 180, 90); + drawArc(x, y, arcWidth, arcHeight, 90, 90); + drawArc(xx, y, arcWidth, arcHeight, 0, 90); + drawArc(xx, yy, arcWidth, arcHeight, 270, 90); + drawArc(x, yy, arcWidth, arcHeight, 180, 90); int y1 = y + arcHeight / 2; int y2 = y + height - arcHeight / 2; - drawLine (x, y1, x, y2); - drawLine (x + width, y1, x + width, y2); + drawLine(x, y1, x, y2); + drawLine(x + width, y1, x + width, y2); int x1 = x + arcWidth / 2; int x2 = x + width - arcWidth / 2; - drawLine (x1, y, x2, y); - drawLine (x1, y + height, x2, y + height); + drawLine(x1, y, x2, y); + drawLine(x1, y + height, x2, y + height); } // 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); + native void cairoDrawGlyphVector(GdkFontPeer font, + float x, float y, int n, + int[] codes, float[] positions); - GdkFontPeer getFontPeer() - { - return (GdkFontPeer) getFont().getPeer(); - } + native void cairoDrawGdkTextLayout(GdkTextLayout gl, + float x, float y); - public void drawGdkGlyphVector(GdkGlyphVector gv, float x, float y) + GdkFontPeer getFontPeer() { - cairoDrawGdkGlyphVector(getFontPeer(), gv, x, y); - if (isBufferedImageGraphics ()) - updateBufferedImage(); + return (GdkFontPeer) getFont().getPeer(); } public void drawGdkTextLayout(GdkTextLayout gl, float x, float y) { - cairoDrawGdkTextLayout(getFontPeer(), gl, x, y); - if (isBufferedImageGraphics ()) - updateBufferedImage(); + cairoDrawGdkTextLayout (gl, x, y); + updateBufferedImage (); } - public void drawString (String str, float x, float y) + public void drawString(String str, float x, float y) { - cairoDrawString(getFontPeer(), str, x, y); - if (isBufferedImageGraphics ()) - updateBufferedImage(); + drawGlyphVector(getFont().createGlyphVector(null, str), x, y); + updateBufferedImage (); } - public void drawString (String str, int x, int y) + public void drawString(String str, int x, int y) { - drawString (str, (float)x, (float)y); + drawString (str, (float) x, (float) y); } - public void drawString (AttributedCharacterIterator ci, int x, int y) + public void drawString(AttributedCharacterIterator ci, int x, int y) { - drawString (ci, (float)x, (float)y); + drawString (ci, (float) x, (float) y); } - public void drawGlyphVector (GlyphVector gv, 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 (); + int n = gv.getNumGlyphs (); + int[] codes = gv.getGlyphCodes (0, n, null); + float[] positions = gv.getGlyphPositions (0, n, null); + + setFont (gv.getFont ()); + cairoDrawGlyphVector (getFontPeer(), x, y, n, codes, positions); + updateBufferedImage (); } - public void drawString (AttributedCharacterIterator ci, float x, float y) + public void drawString(AttributedCharacterIterator ci, float x, float y) { - GlyphVector gv = font.createGlyphVector (getFontRenderContext(), ci); - drawGlyphVector (gv, x, y); + GlyphVector gv = getFont().createGlyphVector(getFontRenderContext(), ci); + drawGlyphVector(gv, x, y); } - public void fillArc (int x, int y, int width, int height, - int startAngle, int arcAngle) + public void fillArc(int x, int y, int width, int height, int startAngle, + int arcAngle) { - fill (new Arc2D.Double((double)x, (double)y, - (double)width, (double)height, - (double)startAngle, (double)arcAngle, - Arc2D.OPEN)); + 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) { - fillArc (x, y, width, height, 0, 360); + fillArc(x, y, width, height, 0, 360); } - public void fillRoundRect (int x, int y, int width, int height, - int arcWidth, int arcHeight) + public void fillRoundRect(int x, int y, int width, int height, int arcWidth, + int arcHeight) { if (arcWidth > width) arcWidth = width; @@ -1456,17 +1392,19 @@ public class GdkGraphics2D extends Graphics2D int xx = x + width - arcWidth; int yy = y + height - arcHeight; - fillArc (x, y, arcWidth, arcHeight, 90, 90); - fillArc (xx, y, arcWidth, arcHeight, 0, 90); - fillArc (xx, yy, arcWidth, arcHeight, 270, 90); - fillArc (x, yy, arcWidth, arcHeight, 180, 90); + fillArc(x, y, arcWidth, arcHeight, 90, 90); + fillArc(xx, y, arcWidth, arcHeight, 0, 90); + fillArc(xx, yy, arcWidth, arcHeight, 270, 90); + fillArc(x, yy, arcWidth, arcHeight, 180, 90); - fillRect (x, y + arcHeight / 2, width, height - arcHeight + 1); - fillRect (x + arcWidth / 2, y, width - arcWidth + 1, height); + fillRect(x, y + arcHeight / 2, width, height - arcHeight + 1); + fillRect(x + arcWidth / 2, y, width - arcWidth + 1, height); } - public Font getFont () + public Font getFont() { + if (font == null) + return new Font("SansSerif", Font.PLAIN, 12); return font; } @@ -1475,38 +1413,34 @@ public class GdkGraphics2D extends Graphics2D // 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 () + 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); + return getFontMetrics(getFont()); } - public FontMetrics getFontMetrics (Font f) + 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); + return Toolkit.getDefaultToolkit().getFontMetrics(f); } - public void setFont (Font f) + public void setFont(Font f) { if (f.getPeer() instanceof GdkFontPeer) font = f; else font = - ((ClasspathToolkit)(Toolkit.getDefaultToolkit ())) - .getFont (f.getName(), f.getAttributes ()); + ((ClasspathToolkit)(Toolkit.getDefaultToolkit())) + .getFont(f.getName(), f.getAttributes()); } - + public String toString() { - return getClass ().getName () + - "[font=" + font.toString () + - ",color=" + fg.toString () + "]"; + return (getClass().getName() + + "[font=" + getFont().toString() + + ",color=" + fg.toString() + + "]"); } - } diff --git a/libjava/gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java b/libjava/gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java new file mode 100644 index 00000000000..c5afd0bc952 --- /dev/null +++ b/libjava/gnu/java/awt/peer/gtk/GdkGraphicsConfiguration.java @@ -0,0 +1,138 @@ +/* GdkGraphicsConfiguration.java -- describes characteristics of graphics + Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation + +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.BufferCapabilities; +import java.awt.ImageCapabilities; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.Rectangle; + +import java.awt.geom.AffineTransform; + +import java.awt.image.BufferedImage; +import java.awt.image.ColorModel; +import java.awt.image.VolatileImage; + +public class GdkGraphicsConfiguration + extends GraphicsConfiguration +{ + GdkScreenGraphicsDevice gdkScreenGraphicsDevice; + ColorModel cm; + Rectangle bounds; + + public GtkToolkit getToolkit() + { + return gdkScreenGraphicsDevice.getToolkit(); + } + + public GdkGraphicsConfiguration(GdkScreenGraphicsDevice dev) + { + this.gdkScreenGraphicsDevice = dev; + cm = new BufferedImage(1, 1, BufferedImage.TYPE_INT_ARGB).getColorModel(); + bounds = getToolkit().getBounds(); + } + + public GraphicsDevice getDevice() + { + return gdkScreenGraphicsDevice; + } + + public BufferedImage createCompatibleImage(int w, int h) + { + return new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); + } + + public BufferedImage createCompatibleImage(int w, int h, + int transparency) + { + return createCompatibleImage(w, h); + } + + public VolatileImage createCompatibleVolatileImage(int w, int h) + { + throw new java.lang.UnsupportedOperationException (); + } + + public VolatileImage createCompatibleVolatileImage(int w, int h, + ImageCapabilities caps) + throws java.awt.AWTException + { + throw new java.lang.UnsupportedOperationException (); + } + + public ColorModel getColorModel() + { + return cm; + } + + public ColorModel getColorModel(int transparency) + { + return getColorModel(); + } + + public AffineTransform getDefaultTransform() + { + // FIXME: extract the GDK DPI information here. + return new AffineTransform(); + } + + public AffineTransform getNormalizingTransform() + { + // FIXME: extract the GDK DPI information here. + return new AffineTransform(); + } + + public Rectangle getBounds() + { + return bounds; + } + + public BufferCapabilities getBufferCapabilities() + { + return new BufferCapabilities(getImageCapabilities(), + getImageCapabilities(), + BufferCapabilities.FlipContents.UNDEFINED); + } + + public ImageCapabilities getImageCapabilities() + { + return new ImageCapabilities(false); + } + +} diff --git a/libjava/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java b/libjava/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java index 45e0c21c0f2..1f10c486921 100644 --- a/libjava/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java +++ b/libjava/gnu/java/awt/peer/gtk/GdkGraphicsEnvironment.java @@ -42,26 +42,37 @@ import java.awt.Font; import java.awt.Graphics2D; import java.awt.GraphicsDevice; import java.awt.GraphicsEnvironment; -import java.awt.Rectangle; -import java.awt.Shape; +import java.awt.HeadlessException; import java.awt.image.BufferedImage; import java.util.Locale; public class GdkGraphicsEnvironment extends GraphicsEnvironment { - public GdkGraphicsEnvironment () + GtkToolkit gtkToolkit; + + public GtkToolkit getToolkit() + { + return gtkToolkit; + } + + public GdkGraphicsEnvironment (GtkToolkit tk) { super(); + gtkToolkit = tk; } public GraphicsDevice[] getScreenDevices () { - throw new java.lang.UnsupportedOperationException (); + // FIXME: Support multiple screens, since GDK can. + return new GraphicsDevice[] { new GdkScreenGraphicsDevice (this) }; } public GraphicsDevice getDefaultScreenDevice () { - throw new java.lang.UnsupportedOperationException (); + if (GraphicsEnvironment.isHeadless ()) + throw new HeadlessException (); + + return new GdkScreenGraphicsDevice (this); } public Graphics2D createGraphics (BufferedImage image) diff --git a/libjava/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java b/libjava/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java index a7b93e5b9ad..a9c1fb9db26 100644 --- a/libjava/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java +++ b/libjava/gnu/java/awt/peer/gtk/GdkPixbufDecoder.java @@ -45,14 +45,31 @@ import java.awt.image.ColorModel; import java.awt.image.DirectColorModel; import java.awt.image.ImageConsumer; import java.awt.image.ImageProducer; -import java.io.FileDescriptor; -import java.io.FileInputStream; +import java.awt.image.Raster; +import java.awt.image.RenderedImage; +import java.io.DataOutput; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.util.ArrayList; import java.util.Hashtable; +import java.util.Iterator; +import java.util.Locale; import java.util.Vector; +import javax.imageio.ImageReader; +import javax.imageio.ImageWriter; +import javax.imageio.ImageReadParam; +import javax.imageio.ImageTypeSpecifier; +import javax.imageio.ImageWriteParam; +import javax.imageio.IIOImage; +import javax.imageio.metadata.IIOMetadata; +import javax.imageio.spi.ImageReaderSpi; +import javax.imageio.spi.ImageWriterSpi; +import javax.imageio.spi.IIORegistry; +import javax.imageio.stream.ImageInputStream; +import javax.imageio.stream.ImageOutputStream; + public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder { static @@ -65,20 +82,27 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder } native static void initStaticState (); private final int native_state = GtkGenericPeer.getUniqueInteger (); + private boolean initialized = false; // the current set of ImageConsumers for this decoder Vector curr; // interface to GdkPixbuf native void initState (); - native void pumpBytes (byte bytes[], int len); + native void pumpBytes (byte[] bytes, int len); native void finish (); + static native void streamImage(int[] bytes, String format, int width, int height, boolean hasAlpha, DataOutput sink); // gdk-pixbuf provids data in RGBA format static final ColorModel cm = new DirectColorModel (32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff); + public GdkPixbufDecoder (InputStream in) + { + super (in); + } + public GdkPixbufDecoder (String filename) { super (filename); @@ -150,24 +174,349 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder curr = null; } - // remaining helper class and static method is a convenience for the Gtk - // peers, for loading a BufferedImage in off a disk file. one would think - // this ought to be fairly straightforward, but it does not appear - // anywhere else I can find. + public void finalize() + { + finish(); + } + + + public static class ImageFormatSpec + { + public String name; + public boolean writable = false; + public ArrayList mimeTypes = new ArrayList(); + public ArrayList extensions = new ArrayList(); + + public ImageFormatSpec(String name, boolean writable) + { + this.name = name; + this.writable = writable; + } + + public synchronized void addMimeType(String m) + { + mimeTypes.add(m); + } + + public synchronized void addExtension(String e) + { + extensions.add(e); + } + } + + static ArrayList imageFormatSpecs; + + public static ImageFormatSpec registerFormat(String name, boolean writable) + { + ImageFormatSpec ifs = new ImageFormatSpec(name, writable); + synchronized(GdkPixbufDecoder.class) + { + if (imageFormatSpecs == null) + imageFormatSpecs = new ArrayList(); + imageFormatSpecs.add(ifs); + } + return ifs; + } + + static String[] getFormatNames(boolean writable) + { + ArrayList names = new ArrayList(); + synchronized (imageFormatSpecs) + { + Iterator i = imageFormatSpecs.iterator(); + while (i.hasNext()) + { + ImageFormatSpec ifs = (ImageFormatSpec) i.next(); + if (writable && !ifs.writable) + continue; + names.add(ifs.name); + + /* + * In order to make the filtering code work, we need to register + * this type under every "format name" likely to be used as a synonym. + * This generally means "all the extensions people might use". + */ + + Iterator j = ifs.extensions.iterator(); + while (j.hasNext()) + names.add((String) j.next()); + } + } + Object[] objs = names.toArray(); + String[] strings = new String[objs.length]; + for (int i = 0; i < objs.length; ++i) + strings[i] = (String) objs[i]; + return strings; + } + + static String[] getFormatExtensions(boolean writable) + { + ArrayList extensions = new ArrayList(); + synchronized (imageFormatSpecs) + { + Iterator i = imageFormatSpecs.iterator(); + while (i.hasNext()) + { + ImageFormatSpec ifs = (ImageFormatSpec) i.next(); + if (writable && !ifs.writable) + continue; + Iterator j = ifs.extensions.iterator(); + while (j.hasNext()) + extensions.add((String) j.next()); + } + } + Object[] objs = extensions.toArray(); + String[] strings = new String[objs.length]; + for (int i = 0; i < objs.length; ++i) + strings[i] = (String) objs[i]; + return strings; + } + + static String[] getFormatMimeTypes(boolean writable) + { + ArrayList mimeTypes = new ArrayList(); + synchronized (imageFormatSpecs) + { + Iterator i = imageFormatSpecs.iterator(); + while (i.hasNext()) + { + ImageFormatSpec ifs = (ImageFormatSpec) i.next(); + if (writable && !ifs.writable) + continue; + Iterator j = ifs.mimeTypes.iterator(); + while (j.hasNext()) + mimeTypes.add((String) j.next()); + } + } + Object[] objs = mimeTypes.toArray(); + String[] strings = new String[objs.length]; + for (int i = 0; i < objs.length; ++i) + strings[i] = (String) objs[i]; + return strings; + } + + + static String findFormatName(Object ext, boolean needWritable) + { + if (ext == null) + throw new IllegalArgumentException("extension is null"); + + if (!(ext instanceof String)) + throw new IllegalArgumentException("extension is not a string"); + + String str = (String) ext; + + Iterator i = imageFormatSpecs.iterator(); + while (i.hasNext()) + { + ImageFormatSpec ifs = (ImageFormatSpec) i.next(); + + if (needWritable && !ifs.writable) + continue; + + if (ifs.name.equals(str)) + return str; + + Iterator j = ifs.extensions.iterator(); + while (j.hasNext()) + { + String extension = (String)j.next(); + if (extension.equals(str)) + return ifs.name; + } + + j = ifs.mimeTypes.iterator(); + while (j.hasNext()) + { + String mimeType = (String)j.next(); + if (mimeType.equals(str)) + return ifs.name; + } + } + throw new IllegalArgumentException("unknown extension '" + str + "'"); + } + + private static GdkPixbufReaderSpi readerSpi; + private static GdkPixbufWriterSpi writerSpi; + + public static synchronized GdkPixbufReaderSpi getReaderSpi() + { + if (readerSpi == null) + readerSpi = new GdkPixbufReaderSpi(); + return readerSpi; + } + + public static synchronized GdkPixbufWriterSpi getWriterSpi() + { + if (writerSpi == null) + writerSpi = new GdkPixbufWriterSpi(); + return writerSpi; + } + + public static void registerSpis(IIORegistry reg) + { + reg.registerServiceProvider(getReaderSpi(), ImageReaderSpi.class); + reg.registerServiceProvider(getWriterSpi(), ImageWriterSpi.class); + } + + public static class GdkPixbufWriterSpi extends ImageWriterSpi + { + public GdkPixbufWriterSpi() + { + super("GdkPixbuf", "2.x", + GdkPixbufDecoder.getFormatNames(true), + GdkPixbufDecoder.getFormatExtensions(true), + GdkPixbufDecoder.getFormatMimeTypes(true), + "gnu.java.awt.peer.gtk.GdkPixbufDecoder$GdkPixbufWriter", + new Class[] { ImageOutputStream.class }, + new String[] { "gnu.java.awt.peer.gtk.GdkPixbufDecoder$GdkPixbufReaderSpi" }, + false, null, null, null, null, + false, null, null, null, null); + } + + public boolean canEncodeImage(ImageTypeSpecifier ts) + { + return true; + } + + public ImageWriter createWriterInstance(Object ext) + { + return new GdkPixbufWriter(this, ext); + } + + public String getDescription(java.util.Locale loc) + { + return "GdkPixbuf Writer SPI"; + } + + } + + public static class GdkPixbufReaderSpi extends ImageReaderSpi + { + public GdkPixbufReaderSpi() + { + super("GdkPixbuf", "2.x", + GdkPixbufDecoder.getFormatNames(false), + GdkPixbufDecoder.getFormatExtensions(false), + GdkPixbufDecoder.getFormatMimeTypes(false), + "gnu.java.awt.peer.gtk.GdkPixbufDecoder$GdkPixbufReader", + new Class[] { ImageInputStream.class }, + new String[] { "gnu.java.awt.peer.gtk.GdkPixbufDecoder$GdkPixbufWriterSpi" }, + false, null, null, null, null, + false, null, null, null, null); + } - private static class BufferedImageBuilder implements ImageConsumer + public boolean canDecodeInput(Object obj) + { + return true; + } + + public ImageReader createReaderInstance(Object ext) + { + return new GdkPixbufReader(this, ext); + } + + public String getDescription(Locale loc) + { + return "GdkPixbuf Reader SPI"; + } + } + + private static class GdkPixbufWriter + extends ImageWriter + { + String ext; + public GdkPixbufWriter(GdkPixbufWriterSpi ownerSpi, Object ext) + { + super(ownerSpi); + this.ext = findFormatName(ext, true); + } + + public IIOMetadata convertImageMetadata (IIOMetadata inData, + ImageTypeSpecifier imageType, + ImageWriteParam param) + { + return null; + } + + public IIOMetadata convertStreamMetadata (IIOMetadata inData, + ImageWriteParam param) + { + return null; + } + + public IIOMetadata getDefaultImageMetadata (ImageTypeSpecifier imageType, + ImageWriteParam param) + { + return null; + } + + public IIOMetadata getDefaultStreamMetadata (ImageWriteParam param) + { + return null; + } + + public void write (IIOMetadata streamMetadata, IIOImage i, ImageWriteParam param) + throws IOException + { + RenderedImage image = i.getRenderedImage(); + Raster ras = image.getData(); + int width = ras.getWidth(); + int height = ras.getHeight(); + ColorModel model = image.getColorModel(); + int[] pixels = GdkGraphics2D.findSimpleIntegerArray (image.getColorModel(), ras); + + if (pixels == null) + { + BufferedImage img = new BufferedImage(width, height, + (model != null && model.hasAlpha() ? + BufferedImage.TYPE_INT_ARGB + : BufferedImage.TYPE_INT_RGB)); + int[] pix = new int[4]; + for (int y = 0; y < height; ++y) + for (int x = 0; x < width; ++x) + img.setRGB(x, y, model.getRGB(ras.getPixel(x, y, pix))); + pixels = GdkGraphics2D.findSimpleIntegerArray (img.getColorModel(), + img.getRaster()); + model = img.getColorModel(); + } + + processImageStarted(1); + streamImage(pixels, this.ext, width, height, model.hasAlpha(), + (DataOutput) this.getOutput()); + processImageComplete(); + } + } + + private static class GdkPixbufReader + extends ImageReader + implements ImageConsumer { + // ImageConsumer parts + GdkPixbufDecoder dec; BufferedImage bufferedImage; ColorModel defaultModel; + int width; + int height; + String ext; + + public GdkPixbufReader(GdkPixbufReaderSpi ownerSpi, Object ext) + { + super(ownerSpi); + this.ext = findFormatName(ext, false); + } - public BufferedImage getBufferedImage() + public GdkPixbufReader(GdkPixbufReaderSpi ownerSpi, Object ext, GdkPixbufDecoder d) { - return bufferedImage; + this(ownerSpi, ext); + dec = d; } - public void setDimensions(int width, int height) + public void setDimensions(int w, int h) { - bufferedImage = new BufferedImage (width, height, BufferedImage.TYPE_INT_ARGB); + processImageStarted(1); + width = w; + height = h; } public void setProperties(Hashtable props) {} @@ -189,65 +538,137 @@ public class GdkPixbufDecoder extends gnu.java.awt.image.ImageDecoder ColorModel model, int[] pixels, int offset, int scansize) { - if (bufferedImage != null) + if (model == null) + model = defaultModel; + + if (bufferedImage == null) { + bufferedImage = new BufferedImage (width, height, (model != null && model.hasAlpha() ? + BufferedImage.TYPE_INT_ARGB + : BufferedImage.TYPE_INT_RGB)); + } - 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; - - bufferedImage.setRGB (x, y, w, h, pixels2, offset, scansize); + 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; + + bufferedImage.setRGB (x, y, w, h, pixels2, offset, scansize); + processImageProgress(y / (height == 0 ? 1 : height)); + } + + public void imageComplete(int status) + { + processImageComplete(); + } + + public BufferedImage getBufferedImage() + { + if (bufferedImage == null && dec != null) + dec.startProduction (this); + return bufferedImage; + } + + // ImageReader parts + + public int getNumImages(boolean allowSearch) + throws IOException + { + return 1; + } + + public IIOMetadata getImageMetadata(int i) + { + return null; + } + + public IIOMetadata getStreamMetadata() + throws IOException + { + return null; } - public void imageComplete(int status) {} + public Iterator getImageTypes(int imageIndex) + throws IOException + { + BufferedImage img = getBufferedImage(); + Vector vec = new Vector(); + vec.add(new ImageTypeSpecifier(img)); + return vec.iterator(); + } + + public int getHeight(int imageIndex) + throws IOException + { + return getBufferedImage().getHeight(); + } + + public int getWidth(int imageIndex) + throws IOException + { + return getBufferedImage().getWidth(); + } + + public void setInput(Object input, + boolean seekForwardOnly, + boolean ignoreMetadata) + { + super.setInput(input, seekForwardOnly, ignoreMetadata); + dec = new GdkPixbufDecoder((InputStream) getInput()); + } + + public BufferedImage read(int imageIndex, ImageReadParam param) + throws IOException + { + return getBufferedImage (); + } } + // remaining helper class and static method is a convenience for the Gtk + // peers, for loading a BufferedImage in off a disk file without going + // through the whole imageio system. + public static BufferedImage createBufferedImage (String filename) { - BufferedImageBuilder bb = new BufferedImageBuilder (); - GdkPixbufDecoder dec = new GdkPixbufDecoder (filename); - dec.startProduction (bb); - return bb.getBufferedImage (); + GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(), + "png", // reader auto-detects, doesn't matter + new GdkPixbufDecoder (filename)); + return r.getBufferedImage (); } public static BufferedImage createBufferedImage (URL u) { - BufferedImageBuilder bb = new BufferedImageBuilder (); - GdkPixbufDecoder dec = new GdkPixbufDecoder (u); - dec.startProduction (bb); - return bb.getBufferedImage (); + GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(), + "png", // reader auto-detects, doesn't matter + new GdkPixbufDecoder (u)); + return r.getBufferedImage (); } public static BufferedImage createBufferedImage (byte[] imagedata, int imageoffset, int imagelength) { - BufferedImageBuilder bb = new BufferedImageBuilder (); - GdkPixbufDecoder dec = new GdkPixbufDecoder (imagedata, imageoffset, imagelength); - dec.startProduction (bb); - return bb.getBufferedImage (); + GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(), + "png", // reader auto-detects, doesn't matter + new GdkPixbufDecoder (imagedata, + imageoffset, + imagelength)); + return r.getBufferedImage (); } public static BufferedImage createBufferedImage (ImageProducer producer) { - BufferedImageBuilder bb = new BufferedImageBuilder (); - producer.startProduction(bb); - return bb.getBufferedImage (); + GdkPixbufReader r = new GdkPixbufReader (getReaderSpi(), "png" /* ignored */, null); + producer.startProduction(r); + return r.getBufferedImage (); } - - } diff --git a/libjava/gnu/java/awt/peer/gtk/GtkArg.java b/libjava/gnu/java/awt/peer/gtk/GdkRobotPeer.java index 0491856849c..2438b68501a 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkArg.java +++ b/libjava/gnu/java/awt/peer/gtk/GdkRobotPeer.java @@ -1,5 +1,5 @@ -/* GtkArg.java - Copyright (C) 1999 Free Software Foundation, Inc. +/* GdkRobot.java -- an XTest implementation of RobotPeer + Copyright (C) 2004 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -35,27 +35,60 @@ 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; -public class GtkArg +import java.awt.AWTException; +import java.awt.GraphicsDevice; +import java.awt.image.ColorModel; +import java.awt.image.DirectColorModel; +import java.awt.Rectangle; +import java.awt.peer.RobotPeer; + +/** + * Implements the RobotPeer interface using the XTest extension. + * + * @author Thomas Fitzsimmons + */ +public class GdkRobotPeer implements RobotPeer { - String name; - Object value; + // gdk-pixbuf provides data in RGBA format + static final ColorModel cm = new DirectColorModel (32, 0xff000000, + 0x00ff0000, + 0x0000ff00, + 0x000000ff); - public GtkArg (String name, Object value) + public GdkRobotPeer (GraphicsDevice screen) throws AWTException { - this.name = name; - this.value = value; + // FIXME: make use of screen parameter when GraphicsDevice is + // implemented. + if (!initXTest ()) + throw new AWTException ("XTest extension not supported"); } - public String getName () + native boolean initXTest (); + + // RobotPeer methods + public native void mouseMove (int x, int y); + public native void mousePress (int buttons); + public native void mouseRelease (int buttons); + public native void mouseWheel (int wheelAmt); + public native void keyPress (int keycode); + public native void keyRelease (int keycode); + native int[] nativeGetRGBPixels (int x, int y, int width, int height); + + public int getRGBPixel (int x, int y) { - return name; + return cm.getRGB (nativeGetRGBPixels (x, y, 1, 1)[0]); } - public Object getValue () + public int[] getRGBPixels (Rectangle r) { - return value; + int[] gdk_pixels = nativeGetRGBPixels (r.x, r.y, r.width, r.height); + int[] pixels = new int[r.width * r.height]; + + for (int i = 0; i < r.width * r.height; i++) + pixels[i] = cm.getRGB (gdk_pixels[i]); + + return pixels; } } diff --git a/libjava/gnu/java/awt/peer/gtk/GtkArgList.java b/libjava/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java index 28cea93db4a..0acef60b177 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkArgList.java +++ b/libjava/gnu/java/awt/peer/gtk/GdkScreenGraphicsDevice.java @@ -1,5 +1,5 @@ -/* GtkArgList.java - Copyright (C) 1999 Free Software Foundation, Inc. +/* GdkScreenGraphicsDevice.java -- information about a screen device + Copyright (C) 2004 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,39 +37,46 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.util.Vector; -public class GtkArgList extends Vector +import java.awt.GraphicsDevice; +import java.awt.GraphicsConfiguration; + +public class GdkScreenGraphicsDevice extends GraphicsDevice { - void add (GtkArg arg) + GdkGraphicsEnvironment env; + + public GtkToolkit getToolkit() { - addElement (arg); + return env.getToolkit(); } - void add (String name, boolean value) - { - addElement (new GtkArg (name, Boolean.valueOf(value))); + public GdkScreenGraphicsDevice (GdkGraphicsEnvironment e) + { + super (); + env = e; } - - void add (String name, int value) + + public int getType () { - addElement (new GtkArg (name, new Integer (value))); + return GraphicsDevice.TYPE_RASTER_SCREEN; } - void add (String name, float value) + public String getIDstring () { - addElement (new GtkArg (name, new Float (value))); + // FIXME: query X for this string + return "default GDK device ID string"; } - void add (String name, Object value) + public GraphicsConfiguration[] getConfigurations () { - addElement (new GtkArg (name, value)); + // FIXME: query X for the list of possible configurations + return new GraphicsConfiguration [] { new GdkGraphicsConfiguration(this) }; } - synchronized void setArgs (GtkComponentPeer cp) + public GraphicsConfiguration getDefaultConfiguration () { - for (int i = 0; i < elementCount; i++) - cp.set ((GtkArg)elementData[i]); + + // FIXME: query X for default configuration + return new GdkGraphicsConfiguration(this); } } - diff --git a/libjava/gnu/java/awt/peer/gtk/GdkTextLayout.java b/libjava/gnu/java/awt/peer/gtk/GdkTextLayout.java index 26cfc16f0da..b5548a837ba 100644 --- a/libjava/gnu/java/awt/peer/gtk/GdkTextLayout.java +++ b/libjava/gnu/java/awt/peer/gtk/GdkTextLayout.java @@ -52,7 +52,6 @@ import java.awt.geom.Rectangle2D; import java.text.CharacterIterator; import java.text.AttributedCharacterIterator; import java.text.AttributedString; -import java.util.Map; import java.awt.font.TextAttribute; import gnu.classpath.Configuration; diff --git a/libjava/gnu/java/awt/peer/gtk/GtkButtonPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkButtonPeer.java index 9fba828b74b..1ef992f02df 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkButtonPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkButtonPeer.java @@ -41,7 +41,6 @@ package gnu.java.awt.peer.gtk; import java.awt.AWTEvent; import java.awt.Button; import java.awt.Component; -import java.awt.Font; import java.awt.Point; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; diff --git a/libjava/gnu/java/awt/peer/gtk/GtkCheckboxMenuItemPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkCheckboxMenuItemPeer.java index adb7008ca3f..2d1f6500862 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkCheckboxMenuItemPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkCheckboxMenuItemPeer.java @@ -38,6 +38,8 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; +import java.awt.ItemSelectable; +import java.awt.event.ItemEvent; import java.awt.CheckboxMenuItem; import java.awt.peer.CheckboxMenuItemPeer; import java.awt.peer.MenuItemPeer; @@ -54,4 +56,15 @@ public class GtkCheckboxMenuItemPeer extends GtkMenuItemPeer } native public void setState (boolean t); + + protected void postMenuActionEvent () + { + CheckboxMenuItem item = (CheckboxMenuItem)awtWidget; + q().postEvent (new ItemEvent ((ItemSelectable)awtWidget, + ItemEvent.ITEM_STATE_CHANGED, + item.getActionCommand(), + item.getState() ? ItemEvent.DESELECTED : ItemEvent.SELECTED)); + + super.postMenuActionEvent(); + } } diff --git a/libjava/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java index a6fd1bac183..4af88f5332c 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkCheckboxPeer.java @@ -40,8 +40,6 @@ package gnu.java.awt.peer.gtk; import java.awt.Checkbox; import java.awt.CheckboxGroup; -import java.awt.Component; -import java.awt.Font; import java.awt.peer.CheckboxPeer; public class GtkCheckboxPeer extends GtkComponentPeer diff --git a/libjava/gnu/java/awt/peer/gtk/GtkChoicePeer.java b/libjava/gnu/java/awt/peer/gtk/GtkChoicePeer.java index 05464143dcf..a065e13abcb 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkChoicePeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkChoicePeer.java @@ -38,7 +38,6 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.awt.AWTEvent; import java.awt.Choice; import java.awt.event.ItemEvent; import java.awt.peer.ChoicePeer; diff --git a/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java index 31d59ce19b0..d9d9907e92e 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkComponentPeer.java @@ -47,14 +47,12 @@ import java.awt.Cursor; import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; -import java.awt.Frame; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.Image; import java.awt.Insets; import java.awt.ItemSelectable; -import java.awt.KeyboardFocusManager; import java.awt.Point; import java.awt.Rectangle; import java.awt.Toolkit; @@ -386,7 +384,7 @@ public class GtkComponentPeer extends GtkGenericPeer if (x == 0 && y == 0 && width == 0 && height == 0) return; - q.postEvent (new PaintEvent (awtComponent, PaintEvent.UPDATE, + q().postEvent (new PaintEvent (awtComponent, PaintEvent.UPDATE, new Rectangle (x, y, width, height))); } @@ -508,14 +506,14 @@ public class GtkComponentPeer extends GtkGenericPeer protected void postMouseEvent(int id, long when, int mods, int x, int y, int clickCount, boolean popupTrigger) { - q.postEvent(new MouseEvent(awtComponent, id, when, mods, x, y, + q().postEvent(new MouseEvent(awtComponent, id, when, mods, x, y, clickCount, popupTrigger)); } protected void postExposeEvent (int x, int y, int width, int height) { if (!isInRepaint) - q.postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT, + q().postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT, new Rectangle (x, y, width, height))); } @@ -535,23 +533,23 @@ public class GtkComponentPeer extends GtkGenericPeer { synchronized (q) { - q.postEvent (keyEvent); - q.postEvent (new KeyEvent (awtComponent, KeyEvent.KEY_TYPED, when, mods, + q().postEvent (keyEvent); + q().postEvent (new KeyEvent (awtComponent, KeyEvent.KEY_TYPED, when, mods, KeyEvent.VK_UNDEFINED, keyChar, keyLocation)); } } else - q.postEvent (keyEvent); + q().postEvent (keyEvent); } protected void postFocusEvent (int id, boolean temporary) { - q.postEvent (new FocusEvent (awtComponent, id, temporary)); + q().postEvent (new FocusEvent (awtComponent, id, temporary)); } protected void postItemEvent (Object item, int stateChange) { - q.postEvent (new ItemEvent ((ItemSelectable)awtComponent, + q().postEvent (new ItemEvent ((ItemSelectable)awtComponent, ItemEvent.ITEM_STATE_CHANGED, item, stateChange)); } diff --git a/libjava/gnu/java/awt/peer/gtk/GtkContainerPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkContainerPeer.java index 7fddd56619f..61551835ec7 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkContainerPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkContainerPeer.java @@ -38,7 +38,6 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.awt.AWTEvent; import java.awt.Color; import java.awt.Component; import java.awt.Container; @@ -46,7 +45,6 @@ import java.awt.Font; import java.awt.Graphics; import java.awt.Insets; import java.awt.Window; -import java.awt.event.PaintEvent; import java.awt.peer.ComponentPeer; import java.awt.peer.ContainerPeer; diff --git a/libjava/gnu/java/awt/peer/gtk/GtkDialogPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkDialogPeer.java index af22a2723ef..9bf234404d1 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkDialogPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkDialogPeer.java @@ -38,8 +38,6 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.awt.AWTEvent; -import java.awt.Component; import java.awt.Dialog; import java.awt.Graphics; import java.awt.Rectangle; @@ -76,7 +74,7 @@ public class GtkDialogPeer extends GtkWindowPeer protected void postExposeEvent (int x, int y, int width, int height) { if (!isInRepaint) - q.postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT, + q().postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT, new Rectangle (x + insets.left, y + insets.top, width, height))); diff --git a/libjava/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java index 19925568e87..fd9c155d2d1 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkFileDialogPeer.java @@ -38,12 +38,10 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.awt.AWTEvent; import java.awt.Dialog; import java.awt.FileDialog; import java.awt.Graphics; import java.awt.Window; -import java.awt.event.WindowEvent; import java.awt.peer.FileDialogPeer; import java.io.File; import java.io.FilenameFilter; @@ -114,7 +112,7 @@ public class GtkFileDialogPeer extends GtkDialogPeer implements FileDialogPeer // GtkFileChooser requires absolute filenames. If the given filename // is not absolute, let's construct it based on current directory. - currentFile = fileName; + currentFile = fileName; if (fileName.indexOf(FS) == 0) { nativeSetFile (fileName); diff --git a/libjava/gnu/java/awt/peer/gtk/GtkFontPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkFontPeer.java index 605d738a199..1369657a8aa 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkFontPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkFontPeer.java @@ -46,7 +46,6 @@ import java.awt.font.FontRenderContext; import java.awt.font.GlyphVector; import java.awt.font.LineMetrics; import java.awt.geom.Rectangle2D; -import java.awt.peer.FontPeer; import java.text.CharacterIterator; import java.util.Locale; import java.util.MissingResourceException; diff --git a/libjava/gnu/java/awt/peer/gtk/GtkFramePeer.java b/libjava/gnu/java/awt/peer/gtk/GtkFramePeer.java index c0c1437b656..b22a25e8869 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkFramePeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkFramePeer.java @@ -38,11 +38,8 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.awt.Component; -import java.awt.Container; import java.awt.Frame; import java.awt.Graphics; -import java.awt.Graphics2D; import java.awt.Image; import java.awt.MenuBar; import java.awt.Rectangle; @@ -165,7 +162,7 @@ public class GtkFramePeer extends GtkWindowPeer setMenuBar (frame.getMenuBar ()); setTitle (frame.getTitle ()); - setResizable (frame.isResizable ()); + gtkWindowSetResizable (frame.isResizable ()); setIconImage(frame.getIconImage()); } @@ -237,9 +234,9 @@ public class GtkFramePeer extends GtkWindowPeer frame_y, frame_width, frame_height); - } - awtComponent.validate(); + awtComponent.validate(); + } } protected void postMouseEvent(int id, long when, int mods, int x, int y, @@ -253,7 +250,7 @@ public class GtkFramePeer extends GtkWindowPeer protected void postExposeEvent (int x, int y, int width, int height) { if (!isInRepaint) - q.postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT, + q().postEvent (new PaintEvent (awtComponent, PaintEvent.PAINT, new Rectangle (x + insets.left, y + insets.top, width, height))); diff --git a/libjava/gnu/java/awt/peer/gtk/GtkGenericPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkGenericPeer.java index 657e830bf2e..f161526f647 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkGenericPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkGenericPeer.java @@ -39,6 +39,7 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; import java.awt.EventQueue; +import java.awt.Toolkit; import java.awt.event.ActionEvent; public class GtkGenericPeer @@ -57,6 +58,11 @@ public class GtkGenericPeer // Dispose of our native state. public native void dispose (); + static EventQueue q () + { + return Toolkit.getDefaultToolkit ().getSystemEventQueue (); + } + protected GtkGenericPeer (Object awtWidget) { this.awtWidget = awtWidget; @@ -70,7 +76,7 @@ public class GtkGenericPeer protected void postActionEvent (String command, int mods) { - q.postEvent (new ActionEvent (awtWidget, ActionEvent.ACTION_PERFORMED, + q().postEvent (new ActionEvent (awtWidget, ActionEvent.ACTION_PERFORMED, command, mods)); } diff --git a/libjava/gnu/java/awt/peer/gtk/GtkLabelPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkLabelPeer.java index 25473d78ea2..3e3e2e3f1cb 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkLabelPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkLabelPeer.java @@ -38,8 +38,6 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.awt.Component; -import java.awt.Font; import java.awt.Label; import java.awt.peer.LabelPeer; diff --git a/libjava/gnu/java/awt/peer/gtk/GtkMainThread.java b/libjava/gnu/java/awt/peer/gtk/GtkMainThread.java deleted file mode 100644 index 4cbe190731c..00000000000 --- a/libjava/gnu/java/awt/peer/gtk/GtkMainThread.java +++ /dev/null @@ -1,111 +0,0 @@ -/* GtkMainThread.java -- Runs gtk_main() - Copyright (C) 1998, 1999 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; - -public class GtkMainThread extends GtkGenericPeer implements Runnable -{ - private static Thread mainThread = null; - private static Object mainThreadLock = new Object(); - - // Whether the gtk+ subsystem has been initialized. - private boolean gtkInitCalled = false; - - /** - * Call gtk_init. It is very important that this happen before any other - * gtk calls. - * - * @param portableNativeSync 1 if the Java property - * gnu.classpath.awt.gtk.portable.native.sync is set to "true". 0 if it is - * set to "false". -1 if unset. - */ - static native void gtkInit(int portableNativeSync); - native void gtkMain(); - - public GtkMainThread() - { - super (null); - synchronized (mainThreadLock) - { - if (mainThread != null) - throw new IllegalStateException(); - mainThread = new Thread(this, "GtkMain"); - } - - synchronized (this) - { - mainThread.start(); - - while (!gtkInitCalled) - { - try - { - wait(); - } - catch (InterruptedException e) { } - } - } - } - - public void run() - { - /* Pass the value of the gnu.classpath.awt.gtk.portable.native.sync system - * property to C. */ - int portableNativeSync; - String portNatSyncProp = - System.getProperty("gnu.classpath.awt.gtk.portable.native.sync"); - - if (portNatSyncProp == null) - portableNativeSync = -1; // unset - else if (Boolean.valueOf(portNatSyncProp).booleanValue()) - portableNativeSync = 1; // true - else - portableNativeSync = 0; // false - - synchronized (this) - { - gtkInit(portableNativeSync); - gtkInitCalled = true; - notifyAll(); - } - gtkMain(); - } -} - - - diff --git a/libjava/gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java index dd061ed37b8..cd7ca8ac79b 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkMenuComponentPeer.java @@ -38,8 +38,6 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.awt.Font; -import java.awt.MenuComponent; import java.awt.peer.MenuComponentPeer; public class GtkMenuComponentPeer extends GtkGenericPeer diff --git a/libjava/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java index 81da90df012..33242f69c4b 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkMenuItemPeer.java @@ -43,8 +43,6 @@ import java.awt.Menu; import java.awt.MenuComponent; import java.awt.MenuBar; import java.awt.MenuItem; -import java.awt.peer.MenuBarPeer; -import java.awt.peer.MenuComponentPeer; import java.awt.peer.MenuItemPeer; import java.awt.peer.MenuPeer; diff --git a/libjava/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java b/libjava/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java index 233bed75a9b..b99ef24c881 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkScrollPanePeer.java @@ -41,7 +41,6 @@ package gnu.java.awt.peer.gtk; import java.awt.Adjustable; import java.awt.Dimension; import java.awt.ScrollPane; -import java.awt.peer.ComponentPeer; import java.awt.peer.ScrollPanePeer; public class GtkScrollPanePeer extends GtkContainerPeer diff --git a/libjava/gnu/java/awt/peer/gtk/GtkScrollbarPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkScrollbarPeer.java index ef4289633c4..d6a498ce5df 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkScrollbarPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkScrollbarPeer.java @@ -73,7 +73,7 @@ public class GtkScrollbarPeer extends GtkComponentPeer protected void postAdjustmentEvent (int type, int value) { - q.postEvent (new AdjustmentEvent ((Adjustable)awtComponent, + q().postEvent (new AdjustmentEvent ((Adjustable)awtComponent, AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED, type, value)); } diff --git a/libjava/gnu/java/awt/peer/gtk/GtkTextComponentPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkTextComponentPeer.java index 8893e36e838..3051ecfcfa8 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkTextComponentPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkTextComponentPeer.java @@ -38,11 +38,8 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; -import java.awt.AWTEvent; -import java.awt.Component; import java.awt.Rectangle; import java.awt.TextComponent; -import java.awt.event.KeyEvent; import java.awt.event.TextEvent; import java.awt.peer.TextComponentPeer; @@ -85,6 +82,6 @@ public class GtkTextComponentPeer extends GtkComponentPeer protected void postTextEvent () { - q.postEvent (new TextEvent (awtComponent, TextEvent.TEXT_VALUE_CHANGED)); + q().postEvent (new TextEvent (awtComponent, TextEvent.TEXT_VALUE_CHANGED)); } } diff --git a/libjava/gnu/java/awt/peer/gtk/GtkToolkit.java b/libjava/gnu/java/awt/peer/gtk/GtkToolkit.java index def22e9874e..f57f53a17a7 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkToolkit.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkToolkit.java @@ -51,7 +51,6 @@ import java.awt.datatransfer.Clipboard; import java.awt.dnd.DragGestureEvent; import java.awt.dnd.peer.DragSourceContextPeer; import java.awt.font.FontRenderContext; -import java.awt.font.TextAttribute; import java.awt.im.InputMethodHighlight; import java.awt.image.BufferedImage; import java.awt.image.ColorModel; @@ -59,15 +58,17 @@ import java.awt.image.ImageConsumer; import java.awt.image.ImageObserver; import java.awt.image.ImageProducer; import java.awt.peer.*; +import java.io.InputStream; import java.net.URL; import java.text.AttributedString; import java.util.HashMap; import java.util.HashSet; import java.util.Hashtable; import java.util.Iterator; +import java.util.LinkedHashMap; import java.util.Map; -import java.util.MissingResourceException; import java.util.Properties; +import javax.imageio.spi.IIORegistry; /* This class uses a deprecated method java.awt.peer.ComponentPeer.getPeer(). This merits comment. We are basically calling Sun's bluff on this one. @@ -86,9 +87,8 @@ import java.util.Properties; public class GtkToolkit extends gnu.java.awt.ClasspathToolkit implements EmbeddedWindowSupport { - GtkMainThread main; Hashtable containers = new Hashtable(); - static EventQueue q = new EventQueue(); + static EventQueue q; static Clipboard systemClipboard; static boolean useGraphics2dSet; static boolean useGraphics2d; @@ -103,19 +103,32 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit return useGraphics2d; } + static native void gtkInit(int portableNativeSync); + static { if (Configuration.INIT_LOAD_LIBRARY) System.loadLibrary("gtkpeer"); + + int portableNativeSync; + String portNatSyncProp = + System.getProperty("gnu.classpath.awt.gtk.portable.native.sync"); + + if (portNatSyncProp == null) + portableNativeSync = -1; // unset + else if (Boolean.valueOf(portNatSyncProp).booleanValue()) + portableNativeSync = 1; // true + else + portableNativeSync = 0; // false + + gtkInit(portableNativeSync); } public GtkToolkit () { - main = new GtkMainThread (); systemClipboard = new GtkClipboard (); - GtkGenericPeer.enableQueue (q); } - + native public void beep (); native private void getScreenSizeDimensions (int[] xy); @@ -313,7 +326,7 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit "SansSerif" }); } - private class LRUCache extends java.util.LinkedHashMap + private class LRUCache extends LinkedHashMap { int max_entries; public LRUCache(int max) @@ -333,15 +346,18 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit public FontMetrics getFontMetrics (Font font) { - if (metricsCache.containsKey(font)) - return (FontMetrics) metricsCache.get(font); - else + synchronized (metricsCache) + { + if (metricsCache.containsKey(font)) + return (FontMetrics) metricsCache.get(font); + } + + FontMetrics m = new GdkFontMetrics (font); + synchronized (metricsCache) { - FontMetrics m; - m = new GdkFontMetrics (font); metricsCache.put(font, m); - return m; - } + } + return m; } public Image getImage (String filename) @@ -594,6 +610,14 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit protected EventQueue getSystemEventQueueImpl() { + synchronized (GtkToolkit.class) + { + if (q == null) + { + q = new EventQueue(); + GtkGenericPeer.enableQueue (q); + } + } return q; } @@ -609,19 +633,37 @@ public class GtkToolkit extends gnu.java.awt.ClasspathToolkit throw new Error("not implemented"); } + public Rectangle getBounds() + { + int[] dims = new int[2]; + getScreenSizeDimensions(dims); + return new Rectangle(0, 0, dims[0], dims[1]); + } + // ClasspathToolkit methods public GraphicsEnvironment getLocalGraphicsEnvironment() { - GraphicsEnvironment ge; - ge = new GdkGraphicsEnvironment (); - return ge; + return new GdkGraphicsEnvironment(this); + } + + public Font createFont(int format, InputStream stream) + { + throw new UnsupportedOperationException(); + } + + public RobotPeer createRobot (GraphicsDevice screen) throws AWTException + { + return new GdkRobotPeer (screen); } - public Font createFont(int format, java.io.InputStream stream) + public void registerImageIOSpis(IIORegistry reg) { - throw new java.lang.UnsupportedOperationException (); + GdkPixbufDecoder.registerSpis(reg); } + public native boolean nativeQueueEmpty(); + public native void wakeNativeQueue(); + public native void iterateNativeQueue(EventQueue locked, boolean block); } // class GtkToolkit diff --git a/libjava/gnu/java/awt/peer/gtk/GtkWindowPeer.java b/libjava/gnu/java/awt/peer/gtk/GtkWindowPeer.java index c61eecd5aa5..1d6e253b072 100644 --- a/libjava/gnu/java/awt/peer/gtk/GtkWindowPeer.java +++ b/libjava/gnu/java/awt/peer/gtk/GtkWindowPeer.java @@ -39,7 +39,6 @@ exception statement from your version. */ package gnu.java.awt.peer.gtk; import java.awt.Component; -import java.awt.Dimension; import java.awt.Frame; import java.awt.Window; import java.awt.event.WindowEvent; @@ -166,10 +165,12 @@ public class GtkWindowPeer extends GtkContainerPeer || frame_y != awtComponent.getY() || frame_width != awtComponent.getWidth() || frame_height != awtComponent.getHeight()) - setBoundsCallback ((Window) awtComponent, - frame_x, frame_y, frame_width, frame_height); + { + setBoundsCallback ((Window) awtComponent, + frame_x, frame_y, frame_width, frame_height); - awtComponent.validate(); + awtComponent.validate(); + } } native void nativeSetVisible (boolean b); @@ -192,7 +193,7 @@ public class GtkWindowPeer extends GtkContainerPeer // Post a WINDOW_OPENED event the first time this window is shown. if (!hasBeenShown) { - q.postEvent (new WindowEvent ((Window) awtComponent, id, + q().postEvent (new WindowEvent ((Window) awtComponent, id, opposite)); hasBeenShown = true; } @@ -201,12 +202,12 @@ public class GtkWindowPeer extends GtkContainerPeer { if (oldState != newState) { - q.postEvent (new WindowEvent ((Window) awtComponent, id, opposite, + q().postEvent (new WindowEvent ((Window) awtComponent, id, opposite, oldState, newState)); oldState = newState; } } else - q.postEvent (new WindowEvent ((Window) awtComponent, id, opposite)); + q().postEvent (new WindowEvent ((Window) awtComponent, id, opposite)); } } |