Remove old autovect-branch by moving to "dead" directory.
[official-gcc.git] / old-autovect-branch / libjava / classpath / gnu / java / awt / peer / qt / QtImage.java
blob9095464357068564295494fab40eddf04971d6c2
1 /* QtImage.java --
2 Copyright (C) 2005 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package gnu.java.awt.peer.qt;
40 import java.awt.Graphics;
41 import java.awt.Color;
42 import java.awt.Image;
43 import java.awt.image.ColorModel;
44 import java.awt.image.DirectColorModel;
45 import java.awt.image.MemoryImageSource;
46 import java.awt.image.ImageConsumer;
47 import java.awt.image.ImageObserver;
48 import java.awt.image.ImageProducer;
49 import java.io.File;
50 import java.io.IOException;
51 import java.io.ByteArrayOutputStream;
52 import java.io.BufferedInputStream;
53 import java.net.URL;
54 import java.util.Hashtable;
55 import java.util.WeakHashMap;
56 import java.util.Vector;
58 /**
59 * QtImage - wraps a QImage
62 public class QtImage extends Image
64 int width = -1, height = -1;
66 /**
67 * Properties.
69 Hashtable props;
71 /**
72 * Loaded or not flag, for asynchronous compatibility.
74 boolean isLoaded;
76 /**
77 * Pointer to the QImage
79 long nativeObject;
81 /**
82 * Observer queue.
84 Vector observers;
86 /**
87 * Error flag for loading.
89 boolean errorLoading;
91 /**
92 * Original source, if created from an ImageProducer.
94 ImageProducer source;
97 * The 32-bit AARRGGBB format the uses.
99 static ColorModel nativeModel = new DirectColorModel(32,
100 0x00FF0000,
101 0x0000FF00,
102 0x000000FF,
103 0xFF000000);
105 * HashMap of Graphics objects painting on this Image.
107 WeakHashMap painters;
110 * Flags if this image is to be destroyed.
112 boolean killFlag;
115 * Clears the image to RGBA 0
117 public native void clear();
120 * Returns a copy of the pixel data as a java array.
122 private native int[] getPixels();
125 * Sets the pixel data from a java array.
127 private native void setPixels(int[] pixels);
130 * Loads an image
132 private native boolean loadImage(String name);
135 * Loads an image from data.
137 private native boolean loadImageFromData(byte[] data);
140 * Allocates a QImage
142 private native void createImage();
145 * Frees the above.
147 private synchronized native void freeImage();
150 * Sets the image to scaled copy of src image. hints are rendering hints.
152 private native void createScaledImage(QtImage src, int hints);
155 * Draws the image optionally composited.
157 native void drawPixels (QtGraphics gc,
158 int bg_red, int bg_green, int bg_blue,
159 int x, int y,
160 boolean composite);
162 * Draws the image, optionally scaled and composited.
164 private native void drawPixelsScaled (QtGraphics gc,
165 int bg_red, int bg_green, int bg_blue,
166 int x, int y, int width, int height,
167 boolean composite);
170 * Draws the image transformed.
172 private native void drawPixelsTransformed (QtGraphics gc, QMatrix transform);
175 * Draws the image scaled flipped and optionally composited.
177 native void drawPixelsScaledFlipped (QtGraphics gc,
178 int bg_red, int bg_green,
179 int bg_blue,
180 boolean flipX, boolean flipY,
181 int srcX, int srcY,
182 int srcWidth, int srcHeight,
183 int dstX, int dstY,
184 int dstWidth, int dstHeight,
185 boolean composite);
188 * Creates the image from an ImageProducer. May result in an error image.
190 public QtImage (ImageProducer producer)
192 killFlag = false;
193 isLoaded = false;
194 observers = new Vector();
195 source = producer;
196 errorLoading = false;
197 if( producer != null )
198 source.startProduction(new QtImageConsumer(this, source));
202 * Creates the image from a URL. May result in an error image.
204 public QtImage (URL url)
206 killFlag = false;
207 isLoaded = false;
208 observers = new Vector();
209 errorLoading = false;
210 if( url == null)
211 return;
212 ByteArrayOutputStream baos = new ByteArrayOutputStream( 5000 );
215 BufferedInputStream bis = new BufferedInputStream(url.openStream());
217 byte[] buf = new byte[5000];
218 int n = 0;
220 while ( (n = bis.read( buf )) != -1 )
221 baos.write(buf, 0, n);
222 bis.close();
224 catch(IOException e)
226 throw new IllegalArgumentException("Couldn't load image.");
228 if ( loadImageFromData( baos.toByteArray() ) != true )
229 throw new IllegalArgumentException("Couldn't load image.");
231 isLoaded = true;
232 observers = null;
233 props = new Hashtable();
237 * Constructs a QtImage by loading a given file.
239 * @throws IllegalArgumentException if the image could not be loaded.
241 public QtImage (String filename)
243 killFlag = false;
244 File f = new File(filename);
245 observers = null;
246 props = new Hashtable();
249 String fn = f.getCanonicalPath();
250 if (loadImage( fn ) != true)
252 errorLoading = true;
253 isLoaded = false;
254 return;
257 catch(IOException e)
259 errorLoading = true;
260 isLoaded = false;
261 return;
263 errorLoading = false;
264 isLoaded = true;
268 * Constructs a QtImage from a byte array of an image file.
270 * @throws IllegalArgumentException if the image could not be loaded.
272 public QtImage (byte[] data)
274 if (loadImageFromData(data) != true)
275 throw new IllegalArgumentException("Couldn't load image.");
277 killFlag = false;
278 isLoaded = true;
279 observers = null;
280 errorLoading = false;
281 props = new Hashtable();
285 * Constructs an empty QtImage.
287 public QtImage (int width, int height)
289 this.width = width;
290 this.height = height;
291 props = new Hashtable();
292 isLoaded = true;
293 killFlag = false;
294 observers = null;
295 errorLoading = false;
296 createImage();
297 clear();
301 * Constructs a scaled version of the src bitmap, using Qt
303 private QtImage (QtImage src, int width, int height, int hints)
305 this.width = width;
306 this.height = height;
307 props = new Hashtable();
308 isLoaded = true;
309 killFlag = false;
310 observers = null;
311 errorLoading = false;
313 createScaledImage(src, hints);
317 * Callback from the image consumer.
319 public void setImage(int width, int height,
320 int[] pixels, Hashtable properties)
322 this.width = width;
323 this.height = height;
324 props = (properties != null) ? properties : new Hashtable();
326 if (width <= 0 || height <= 0 || pixels == null)
328 errorLoading = true;
329 return;
332 isLoaded = true;
333 deliver();
334 createImage();
335 setPixels(pixels);
338 // java.awt.Image methods ////////////////////////////////////////////////
340 public int getWidth (ImageObserver observer)
342 if (addObserver(observer))
343 return -1;
345 return width;
348 public int getHeight (ImageObserver observer)
350 if (addObserver(observer))
351 return -1;
353 return height;
356 public Object getProperty (String name, ImageObserver observer)
358 if (addObserver(observer))
359 return UndefinedProperty;
361 Object value = props.get (name);
362 return (value == null) ? UndefinedProperty : value;
366 * Returns the source of this image.
368 public ImageProducer getSource ()
370 if (!isLoaded)
371 return null;
372 return new MemoryImageSource(width, height, nativeModel, getPixels(),
373 0, width);
376 void putPainter(QtImageGraphics g)
378 if( painters == null )
379 painters = new WeakHashMap();
380 painters.put( g, "dummy" );
383 void removePainter(QtImageGraphics g)
385 painters.remove( g );
386 if( killFlag && painters.isEmpty() )
387 freeImage();
391 * Creates a Graphics context for this image.
393 public Graphics getGraphics ()
395 if (!isLoaded || killFlag)
396 return null;
398 return new QtImageGraphics(this);
402 * Creates a Graphics context for this image.
404 Graphics getDirectGraphics(QtComponentPeer peer)
406 if (!isLoaded)
407 return null;
409 return new QtImageDirectGraphics(this, peer);
413 * Returns a scaled instance of this image.
415 public Image getScaledInstance(int width,
416 int height,
417 int hints)
419 if (width <= 0 || height <= 0)
420 throw new IllegalArgumentException("Width and height of scaled bitmap"+
421 "must be >= 0");
423 return new QtImage(this, width, height, hints);
427 * If the image is loaded and comes from an ImageProducer,
428 * regenerate the image from there.
430 * I have no idea if this is ever actually used. Since QtImage can't be
431 * instantiated directly, how is the user to know if it was created from
432 * an ImageProducer or not?
434 public synchronized void flush ()
436 if (isLoaded && source != null)
438 observers = new Vector();
439 isLoaded = false;
440 freeImage();
441 source.startProduction(new QtImageConsumer(this, source));
445 public void finalize()
447 dispose();
450 public void dispose()
452 if (isLoaded)
454 if( painters == null || painters.isEmpty() )
455 freeImage();
456 else
457 killFlag = true; // can't destroy image yet.
458 // Do so when all painters are gone.
463 * Returns the image status, used by QtToolkit
465 public int checkImage (ImageObserver observer)
467 if (addObserver(observer))
469 if (errorLoading == true)
470 return ImageObserver.ERROR;
471 else
472 return 0;
475 return ImageObserver.ALLBITS | ImageObserver.WIDTH | ImageObserver.HEIGHT;
478 // Drawing methods ////////////////////////////////////////////////
481 * Draws an image with eventual scaling/transforming.
483 public boolean drawImage (QtGraphics g, QMatrix matrix,
484 ImageObserver observer)
486 if (addObserver(observer))
487 return false;
489 drawPixelsTransformed (g, matrix);
491 return true;
495 * Draws an image to the QtGraphics context, at (x,y) with optional
496 * compositing with a background color.
498 public boolean drawImage (QtGraphics g, int x, int y,
499 Color bgcolor, ImageObserver observer)
501 if (addObserver(observer))
502 return false;
504 if(bgcolor != null)
505 drawPixels(g, bgcolor.getRed (), bgcolor.getGreen (),
506 bgcolor.getBlue (), x, y, true);
507 else
508 drawPixels(g, 0, 0, 0, x, y, false);
510 return true;
514 * Draws an image to the QtGraphics context, at (x,y) scaled to
515 * width and height, with optional compositing with a background color.
517 public boolean drawImage (QtGraphics g, int x, int y, int width, int height,
518 Color bgcolor, ImageObserver observer)
520 if (addObserver(observer))
521 return false;
523 if(bgcolor != null)
524 drawPixelsScaled(g, bgcolor.getRed (), bgcolor.getGreen (),
525 bgcolor.getBlue (), x, y, width, height, true);
526 else
527 drawPixelsScaled(g, 0, 0, 0, x, y, width, height, false);
529 return true;
533 * Draws an image with eventual scaling/transforming.
535 public boolean drawImage (QtGraphics g, int dx1, int dy1, int dx2, int dy2,
536 int sx1, int sy1, int sx2, int sy2,
537 Color bgcolor, ImageObserver observer)
539 if (addObserver(observer))
540 return false;
542 boolean flipX = (dx1 > dx2)^(sx1 > sx2);
543 boolean flipY = (dy1 > dy2)^(sy1 > sy2);
544 int dstWidth = Math.abs (dx2 - dx1);
545 int dstHeight = Math.abs (dy2 - dy1);
546 int srcWidth = Math.abs (sx2 - sx1);
547 int srcHeight = Math.abs (sy2 - sy1);
548 int srcX = (sx1 < sx2) ? sx1 : sx2;
549 int srcY = (sy1 < sy2) ? sy1 : sy2;
550 int dstX = (dx1 < dx2) ? dx1 : dx2;
551 int dstY = (dy1 < dy2) ? dy1 : dy2;
553 // Clipping. This requires the dst to be scaled as well,
554 if (srcWidth > width)
556 dstWidth = (int)((double)dstWidth*((double)width/(double)srcWidth));
557 srcWidth = width - srcX;
560 if (srcHeight > height)
562 dstHeight = (int)((double)dstHeight*((double)height/(double)srcHeight));
563 srcHeight = height - srcY;
566 if (srcWidth + srcX > width)
568 dstWidth = (int)((double)dstWidth * (double)(width - srcX)/(double)srcWidth);
569 srcWidth = width - srcX;
572 if (srcHeight + srcY > height)
574 dstHeight = (int)((double)dstHeight * (double)(width - srcY)/(double)srcHeight);
575 srcHeight = height - srcY;
578 if ( srcWidth <= 0 || srcHeight <= 0 || dstWidth <= 0 || dstHeight <= 0)
579 return true;
581 if(bgcolor != null)
582 drawPixelsScaledFlipped (g, bgcolor.getRed (), bgcolor.getGreen (),
583 bgcolor.getBlue (),
584 flipX, flipY,
585 srcX, srcY,
586 srcWidth, srcHeight,
587 dstX, dstY,
588 dstWidth, dstHeight,
589 true);
590 else
591 drawPixelsScaledFlipped (g, 0, 0, 0, flipX, flipY,
592 srcX, srcY, srcWidth, srcHeight,
593 dstX, dstY, dstWidth, dstHeight,
594 false);
595 return true;
598 public native void copyArea(int x, int y, int width, int height,
599 int dx, int dy);
601 // Private methods ////////////////////////////////////////////////
604 * Delivers notifications to all queued observers.
606 private void deliver()
608 int flags = ImageObserver.HEIGHT |
609 ImageObserver.WIDTH |
610 ImageObserver.PROPERTIES |
611 ImageObserver.ALLBITS;
613 if (observers != null)
614 for(int i=0; i < observers.size(); i++)
615 ((ImageObserver)observers.elementAt(i)).
616 imageUpdate(this, flags, 0, 0, width, height);
618 observers = null;
622 * Adds an observer, if we need to.
623 * @return true if an observer was added.
625 private boolean addObserver(ImageObserver observer)
627 if (!isLoaded)
629 if(observer != null)
630 if (!observers.contains (observer))
631 observers.addElement (observer);
632 return true;
634 return false;
637 public String toString()
639 return "QtImage [isLoaded="+isLoaded+", width="+width+", height="+height
640 +"]";