diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/gnu/java/awt/peer/qt/QtImage.java | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libjava/classpath/gnu/java/awt/peer/qt/QtImage.java')
-rw-r--r-- | libjava/classpath/gnu/java/awt/peer/qt/QtImage.java | 641 |
1 files changed, 641 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/java/awt/peer/qt/QtImage.java b/libjava/classpath/gnu/java/awt/peer/qt/QtImage.java new file mode 100644 index 000000000..b7e50ea25 --- /dev/null +++ b/libjava/classpath/gnu/java/awt/peer/qt/QtImage.java @@ -0,0 +1,641 @@ +/* QtImage.java -- + Copyright (C) 2005, 2006 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., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 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.qt; + +import java.awt.Graphics; +import java.awt.Color; +import java.awt.Image; +import java.awt.image.ColorModel; +import java.awt.image.DirectColorModel; +import java.awt.image.MemoryImageSource; +import java.awt.image.ImageObserver; +import java.awt.image.ImageProducer; +import java.io.File; +import java.io.IOException; +import java.io.ByteArrayOutputStream; +import java.io.BufferedInputStream; +import java.net.URL; +import java.util.Hashtable; +import java.util.WeakHashMap; +import java.util.Vector; + +/** + * QtImage - wraps a QImage + * + */ +public class QtImage extends Image +{ + int width = -1, height = -1; + + /** + * Properties. + */ + Hashtable props; + + /** + * Loaded or not flag, for asynchronous compatibility. + */ + boolean isLoaded; + + /** + * Pointer to the QImage + */ + long nativeObject; + + /** + * Observer queue. + */ + Vector observers; + + /** + * Error flag for loading. + */ + boolean errorLoading; + + /** + * Original source, if created from an ImageProducer. + */ + ImageProducer source; + + /* + * The 32-bit AARRGGBB format the uses. + */ + static ColorModel nativeModel = new DirectColorModel(32, + 0x00FF0000, + 0x0000FF00, + 0x000000FF, + 0xFF000000); + /** + * HashMap of Graphics objects painting on this Image. + */ + WeakHashMap painters; + + /** + * Flags if this image is to be destroyed. + */ + boolean killFlag; + + /** + * Clears the image to RGBA 0 + */ + public native void clear(); + + /** + * Returns a copy of the pixel data as a java array. + */ + private native int[] getPixels(); + + /** + * Sets the pixel data from a java array. + */ + private native void setPixels(int[] pixels); + + /** + * Loads an image + */ + private native boolean loadImage(String name); + + /** + * Loads an image from data. + */ + private native boolean loadImageFromData(byte[] data); + + /** + * Allocates a QImage + */ + private native void createImage(); + + /** + * Frees the above. + */ + private synchronized native void freeImage(); + + /** + * Sets the image to scaled copy of src image. hints are rendering hints. + */ + private native void createScaledImage(QtImage src, int hints); + + /** + * Draws the image optionally composited. + */ + native void drawPixels (QtGraphics gc, + int bg_red, int bg_green, int bg_blue, + int x, int y, + boolean composite); + /** + * Draws the image, optionally scaled and composited. + */ + private native void drawPixelsScaled (QtGraphics gc, + int bg_red, int bg_green, int bg_blue, + int x, int y, int width, int height, + boolean composite); + + /** + * Draws the image transformed. + */ + private native void drawPixelsTransformed (QtGraphics gc, QMatrix transform); + + /** + * Draws the image scaled flipped and optionally composited. + */ + native void drawPixelsScaledFlipped (QtGraphics gc, + int bg_red, int bg_green, + int bg_blue, + boolean flipX, boolean flipY, + int srcX, int srcY, + int srcWidth, int srcHeight, + int dstX, int dstY, + int dstWidth, int dstHeight, + boolean composite); + + /** + * Creates the image from an ImageProducer. May result in an error image. + */ + public QtImage (ImageProducer producer) + { + killFlag = false; + isLoaded = false; + observers = new Vector(); + source = producer; + errorLoading = false; + if( producer != null ) + source.startProduction(new QtImageConsumer(this, source)); + } + + /** + * Creates the image from a URL. May result in an error image. + */ + public QtImage (URL url) + { + killFlag = false; + isLoaded = false; + observers = new Vector(); + errorLoading = false; + if( url == null) + return; + ByteArrayOutputStream baos = new ByteArrayOutputStream( 5000 ); + try + { + BufferedInputStream bis = new BufferedInputStream(url.openStream()); + + byte[] buf = new byte[5000]; + int n = 0; + + while ( (n = bis.read( buf )) != -1 ) + baos.write(buf, 0, n); + bis.close(); + } + catch(IOException e) + { + throw new IllegalArgumentException("Couldn't load image."); + } + if ( loadImageFromData( baos.toByteArray() ) != true ) + throw new IllegalArgumentException("Couldn't load image."); + + isLoaded = true; + observers = null; + props = new Hashtable(); + } + + /** + * Constructs a QtImage by loading a given file. + * + * @throws IllegalArgumentException if the image could not be loaded. + */ + public QtImage (String filename) + { + killFlag = false; + File f = new File(filename); + observers = null; + props = new Hashtable(); + try + { + String fn = f.getCanonicalPath(); + if (loadImage( fn ) != true) + { + errorLoading = true; + isLoaded = false; + return; + } + } + catch(IOException e) + { + errorLoading = true; + isLoaded = false; + return; + } + errorLoading = false; + isLoaded = true; + } + + /** + * Constructs a QtImage from a byte array of an image file. + * + * @throws IllegalArgumentException if the image could not be loaded. + */ + public QtImage (byte[] data) + { + if (loadImageFromData(data) != true) + throw new IllegalArgumentException("Couldn't load image."); + + killFlag = false; + isLoaded = true; + observers = null; + errorLoading = false; + props = new Hashtable(); + } + + /** + * Constructs an empty QtImage. + */ + public QtImage (int width, int height) + { + this.width = width; + this.height = height; + props = new Hashtable(); + isLoaded = true; + killFlag = false; + observers = null; + errorLoading = false; + createImage(); + clear(); + } + + /** + * Constructs a scaled version of the src bitmap, using Qt + */ + private QtImage (QtImage src, int width, int height, int hints) + { + this.width = width; + this.height = height; + props = new Hashtable(); + isLoaded = true; + killFlag = false; + observers = null; + errorLoading = false; + + createScaledImage(src, hints); + } + + /** + * Callback from the image consumer. + */ + public void setImage(int width, int height, + int[] pixels, Hashtable properties) + { + this.width = width; + this.height = height; + props = (properties != null) ? properties : new Hashtable(); + + if (width <= 0 || height <= 0 || pixels == null) + { + errorLoading = true; + return; + } + + isLoaded = true; + deliver(); + createImage(); + setPixels(pixels); + } + + // java.awt.Image methods //////////////////////////////////////////////// + + public int getWidth (ImageObserver observer) + { + if (addObserver(observer)) + return -1; + + return width; + } + + public int getHeight (ImageObserver observer) + { + if (addObserver(observer)) + return -1; + + return height; + } + + public Object getProperty (String name, ImageObserver observer) + { + if (addObserver(observer)) + return UndefinedProperty; + + Object value = props.get (name); + return (value == null) ? UndefinedProperty : value; + } + + /** + * Returns the source of this image. + */ + public ImageProducer getSource () + { + if (!isLoaded) + return null; + return new MemoryImageSource(width, height, nativeModel, getPixels(), + 0, width); + } + + void putPainter(QtImageGraphics g) + { + if( painters == null ) + painters = new WeakHashMap(); + painters.put( g, "dummy" ); + } + + void removePainter(QtImageGraphics g) + { + painters.remove( g ); + if( killFlag && painters.isEmpty() ) + freeImage(); + } + + /** + * Creates a Graphics context for this image. + */ + public Graphics getGraphics () + { + if (!isLoaded || killFlag) + return null; + + return new QtImageGraphics(this); + } + + /** + * Creates a Graphics context for this image. + */ + Graphics getDirectGraphics(QtComponentPeer peer) + { + if (!isLoaded) + return null; + + return new QtImageDirectGraphics(this, peer); + } + + /** + * Returns a scaled instance of this image. + */ + public Image getScaledInstance(int width, + int height, + int hints) + { + if (width <= 0 || height <= 0) + throw new IllegalArgumentException("Width and height of scaled bitmap"+ + "must be >= 0"); + + return new QtImage(this, width, height, hints); + } + + /** + * If the image is loaded and comes from an ImageProducer, + * regenerate the image from there. + * + * I have no idea if this is ever actually used. Since QtImage can't be + * instantiated directly, how is the user to know if it was created from + * an ImageProducer or not? + */ + public synchronized void flush () + { + if (isLoaded && source != null) + { + observers = new Vector(); + isLoaded = false; + freeImage(); + source.startProduction(new QtImageConsumer(this, source)); + } + } + + public void finalize() + { + dispose(); + } + + public void dispose() + { + if (isLoaded) + { + if( painters == null || painters.isEmpty() ) + freeImage(); + else + killFlag = true; // can't destroy image yet. + // Do so when all painters are gone. + } + } + + /** + * Returns the image status, used by QtToolkit + */ + public int checkImage (ImageObserver observer) + { + if (addObserver(observer)) + { + if (errorLoading == true) + return ImageObserver.ERROR; + else + return 0; + } + + return ImageObserver.ALLBITS | ImageObserver.WIDTH | ImageObserver.HEIGHT; + } + + // Drawing methods //////////////////////////////////////////////// + + /** + * Draws an image with eventual scaling/transforming. + */ + public boolean drawImage (QtGraphics g, QMatrix matrix, + ImageObserver observer) + { + if (addObserver(observer)) + return false; + + drawPixelsTransformed (g, matrix); + + return true; + } + + /** + * Draws an image to the QtGraphics context, at (x,y) with optional + * compositing with a background color. + */ + public boolean drawImage (QtGraphics g, int x, int y, + Color bgcolor, ImageObserver observer) + { + if (addObserver(observer)) + return false; + + if(bgcolor != null) + drawPixels(g, bgcolor.getRed (), bgcolor.getGreen (), + bgcolor.getBlue (), x, y, true); + else + drawPixels(g, 0, 0, 0, x, y, false); + + return true; + } + + /** + * Draws an image to the QtGraphics context, at (x,y) scaled to + * width and height, with optional compositing with a background color. + */ + public boolean drawImage (QtGraphics g, int x, int y, int width, int height, + Color bgcolor, ImageObserver observer) + { + if (addObserver(observer)) + return false; + + if(bgcolor != null) + drawPixelsScaled(g, bgcolor.getRed (), bgcolor.getGreen (), + bgcolor.getBlue (), x, y, width, height, true); + else + drawPixelsScaled(g, 0, 0, 0, x, y, width, height, false); + + return true; + } + + /** + * Draws an image with eventual scaling/transforming. + */ + public boolean drawImage (QtGraphics g, int dx1, int dy1, int dx2, int dy2, + int sx1, int sy1, int sx2, int sy2, + Color bgcolor, ImageObserver observer) + { + if (addObserver(observer)) + return false; + + boolean flipX = (dx1 > dx2)^(sx1 > sx2); + boolean flipY = (dy1 > dy2)^(sy1 > sy2); + int dstWidth = Math.abs (dx2 - dx1); + int dstHeight = Math.abs (dy2 - dy1); + int srcWidth = Math.abs (sx2 - sx1); + int srcHeight = Math.abs (sy2 - sy1); + int srcX = (sx1 < sx2) ? sx1 : sx2; + int srcY = (sy1 < sy2) ? sy1 : sy2; + int dstX = (dx1 < dx2) ? dx1 : dx2; + int dstY = (dy1 < dy2) ? dy1 : dy2; + + // Clipping. This requires the dst to be scaled as well, + if (srcWidth > width) + { + dstWidth = (int)((double)dstWidth*((double)width/(double)srcWidth)); + srcWidth = width - srcX; + } + + if (srcHeight > height) + { + dstHeight = (int)((double)dstHeight*((double)height/(double)srcHeight)); + srcHeight = height - srcY; + } + + if (srcWidth + srcX > width) + { + dstWidth = (int)((double)dstWidth * (double)(width - srcX)/(double)srcWidth); + srcWidth = width - srcX; + } + + if (srcHeight + srcY > height) + { + dstHeight = (int)((double)dstHeight * (double)(width - srcY)/(double)srcHeight); + srcHeight = height - srcY; + } + + if ( srcWidth <= 0 || srcHeight <= 0 || dstWidth <= 0 || dstHeight <= 0) + return true; + + if(bgcolor != null) + drawPixelsScaledFlipped (g, bgcolor.getRed (), bgcolor.getGreen (), + bgcolor.getBlue (), + flipX, flipY, + srcX, srcY, + srcWidth, srcHeight, + dstX, dstY, + dstWidth, dstHeight, + true); + else + drawPixelsScaledFlipped (g, 0, 0, 0, flipX, flipY, + srcX, srcY, srcWidth, srcHeight, + dstX, dstY, dstWidth, dstHeight, + false); + return true; + } + + public native void copyArea(int x, int y, int width, int height, + int dx, int dy); + + // Private methods //////////////////////////////////////////////// + + /** + * Delivers notifications to all queued observers. + */ + private void deliver() + { + int flags = ImageObserver.HEIGHT | + ImageObserver.WIDTH | + ImageObserver.PROPERTIES | + ImageObserver.ALLBITS; + + if (observers != null) + for(int i=0; i < observers.size(); i++) + ((ImageObserver)observers.elementAt(i)). + imageUpdate(this, flags, 0, 0, width, height); + + observers = null; + } + + /** + * Adds an observer, if we need to. + * @return true if an observer was added. + */ + private boolean addObserver(ImageObserver observer) + { + if (!isLoaded) + { + if(observer != null) + if (!observers.contains (observer)) + observers.addElement (observer); + return true; + } + return false; + } + + public String toString() + { + return "QtImage [isLoaded="+isLoaded+", width="+width+", height="+height + +"]"; + } +} |