From 7e19ed027af34eb66eb263878bc802e6ec789818 Mon Sep 17 00:00:00 2001 From: Mario Torre Date: Sun, 15 Jun 2008 18:14:54 +0000 Subject: 2008-06-15 Mario Torre * gnu/java/awt/java2d/AbstractGraphics2D.java (setColor): delegate to setPaint. (setPaint): fix to set paint context and foreground color. (imageCache): new field. (drawImage): new codepath for scaling images. (prepareImage): new method. (getPaintContext): set paintContext appropriately. * gnu/java/awt/java2d/RasterGraphics.java (renderScanline): new method, override from superclass to detect correct value of y while rendering the scanline. * gnu/java/awt/java2d/ScanlineConverter.java (renderShape): revert previous patch. * gnu/java/awt/peer/x/XEventPump.java (findMouseEventTarget): new method. (handleButtonPress): use of findMouseEventTarget to detect the correct target. (handleButtonRelease): likewise. * gnu/java/awt/peer/x/XGraphics2D.java (rawDrawImage): clip the target image so that it is completely contained in the destination pixmaps, as per X11 specification. * gnu/java/awt/peer/x/XToolkit.java (createTextField): method implemented. (createButton): likewise. (prepareImage): likewise. (createLabel): likewise. (checkImage): likewise. (createTextArea): likewise. (createCheckbox): likewise. (checkHeadLess): new method. * gnu/javax/imageio/bmp/BMPImageWriter.java (write): don't close the stream. * gnu/javax/imageio/bmp/BMPImageWriterSpi.java (names): added new names to the list of known names for BMP. * java/awt/image/WritableRaster.java (createWritableTranslatedChild): * javax/imageio/ImageIO.java (write): call dispose on ImageWriter after writing of the image. --- gnu/java/awt/java2d/AbstractGraphics2D.java | 128 +++++++++++++++++++++------- 1 file changed, 96 insertions(+), 32 deletions(-) (limited to 'gnu/java/awt/java2d/AbstractGraphics2D.java') diff --git a/gnu/java/awt/java2d/AbstractGraphics2D.java b/gnu/java/awt/java2d/AbstractGraphics2D.java index 52a9433c5..850465938 100644 --- a/gnu/java/awt/java2d/AbstractGraphics2D.java +++ b/gnu/java/awt/java2d/AbstractGraphics2D.java @@ -46,6 +46,7 @@ import java.awt.BasicStroke; import java.awt.Color; import java.awt.Composite; import java.awt.CompositeContext; +import java.awt.Dimension; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; @@ -75,9 +76,12 @@ import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.awt.image.ColorModel; import java.awt.image.DataBuffer; +import java.awt.image.FilteredImageSource; import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; import java.awt.image.Raster; import java.awt.image.RenderedImage; +import java.awt.image.ReplicateScaleFilter; import java.awt.image.SampleModel; import java.awt.image.WritableRaster; import java.awt.image.renderable.RenderableImage; @@ -86,6 +90,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.LinkedList; import java.util.Map; +import java.util.WeakHashMap; /** * This is a 100% Java implementation of the Java2D rendering pipeline. It is @@ -154,7 +159,14 @@ public abstract class AbstractGraphics2D extends Graphics2D implements Cloneable, Pixelizer { - + /** + * Caches scaled versions of an image. + * + * @see #drawImage(Image, int, int, int, int, ImageObserver) + */ + protected static final WeakHashMap> imageCache = + new WeakHashMap>(); + /** * Wether we use anti aliasing for rendering text by default or not. */ @@ -636,14 +648,29 @@ public abstract class AbstractGraphics2D if (p != null) { paint = p; - + if (! (paint instanceof Color)) - isOptimized = false; + { + isOptimized = false; + } else { + this.foreground = (Color) paint; + isForegroundColorNull = false; updateOptimization(); } } + else + { + this.foreground = Color.BLACK; + isForegroundColorNull = true; + } + + // free resources if needed, then put the paint context to null + if (this.paintContext != null) + this.paintContext.dispose(); + + this.paintContext = null; } /** @@ -1080,23 +1107,8 @@ public abstract class AbstractGraphics2D * @param color the foreground to set */ public void setColor(Color color) - { - if (color == null) - { - this.foreground = Color.BLACK; - isForegroundColorNull = true; - } - else - { - this.foreground = color; - isForegroundColorNull = false; - } - - // free resources if needed, then put the paint context to null - if (this.paintContext != null) - this.paintContext.dispose(); - - this.paintContext = null; + { + this.setPaint(color); } public void setPaintMode() @@ -1493,11 +1505,19 @@ public abstract class AbstractGraphics2D ImageObserver observer) { AffineTransform t = new AffineTransform(); - t.translate(x, y); - double scaleX = (double) width / (double) image.getWidth(observer); - double scaleY = (double) height / (double) image.getHeight(observer); - t.scale(scaleX, scaleY); - return drawImage(image, t, observer); + int imWidth = image.getWidth(observer); + int imHeight = image.getHeight(observer); + if (imWidth == width && imHeight == height) + { + // No need to scale, fall back to non-scaling loops. + return drawImage(image, x, y, observer); + } + else + { + Image scaled = prepareImage(image, width, height); + // Ideally, this should notify the observer about the scaling progress. + return drawImage(scaled, x, y, observer); + } } /** @@ -2015,16 +2035,60 @@ public abstract class AbstractGraphics2D { if (this.paintContext == null) { - return this.foreground.createContext(getColorModel(), - getDeviceBounds(), - getClipBounds(), - getTransform(), - getRenderingHints()); + this.paintContext = + this.foreground.createContext(getColorModel(), + getDeviceBounds(), + getClipBounds(), + getTransform(), + getRenderingHints()); } - else + + return this.paintContext; + } + + /** + * Scales an image to the specified width and height. This should also + * be used to implement + * {@link Toolkit#prepareImage(Image, int, int, ImageObserver)}. + * This uses {@link Toolkit#createImage(ImageProducer)} to create the actual + * image. + * + * @param image the image to prepare + * @param w the width + * @param h the height + * + * @return the scaled image + */ + public static Image prepareImage(Image image, int w, int h) + { + // Try to find cached scaled image. + HashMap scaledTable = imageCache.get(image); + Dimension size = new Dimension(w, h); + Image scaled = null; + if (scaledTable != null) + { + scaled = scaledTable.get(size); + } + if (scaled == null) { - return this.paintContext; + // No cached scaled image. Start scaling image now. + ImageProducer source = image.getSource(); + ReplicateScaleFilter scaler = new ReplicateScaleFilter(w, h); + FilteredImageSource filteredSource = + new FilteredImageSource(source, scaler); + // Ideally, this should asynchronously scale the image. + Image scaledImage = + Toolkit.getDefaultToolkit().createImage(filteredSource); + scaled = scaledImage; + // Put scaled image in cache. + if (scaledTable == null) + { + scaledTable = new HashMap(); + imageCache.put(image, scaledTable); + } + scaledTable.put(size, scaledImage); } + return scaled; } } -- cgit v1.2.1