OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [gnu/] [java/] [awt/] [peer/] [gtk/] [GtkImage.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* GtkImage.java
2
   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
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.
10
 
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.
15
 
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.
20
 
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.
25
 
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. */
37
 
38
 
39
package gnu.java.awt.peer.gtk;
40
 
41
import java.awt.Graphics;
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.ImageObserver;
47
import java.awt.image.ImageProducer;
48
import java.io.File;
49
import java.io.IOException;
50
import java.util.Hashtable;
51
import java.util.Vector;
52
import java.io.ByteArrayOutputStream;
53
import java.io.BufferedInputStream;
54
import java.net.URL;
55
import gnu.classpath.Pointer;
56
 
57
/**
58
 * GtkImage - wraps a GdkPixbuf.
59
 *
60
 * A GdkPixbuf is 'on-screen' and the gdk cannot draw to it,
61
 * this is used for the other constructors (and other createImage methods), and
62
 * corresponds to the Image implementations returned by the Toolkit.createImage
63
 * methods, and is basically immutable.
64
 *
65
 * @author Sven de Marothy
66
 */
67
public class GtkImage extends Image
68
{
69
  int width = -1, height = -1;
70
 
71
  /**
72
   * Properties.
73
   */
74
  Hashtable<?,?> props;
75
 
76
  /**
77
   * Loaded or not flag, for asynchronous compatibility.
78
   */
79
  boolean isLoaded;
80
 
81
  /**
82
   * Pointer to the GdkPixbuf -
83
   * don't change the name without changing the native code.
84
   */
85
  Pointer pixbuf;
86
 
87
  /**
88
   * Observer queue.
89
   */
90
  Vector<ImageObserver> observers;
91
 
92
  /**
93
   * Error flag for loading.
94
   */
95
  boolean errorLoading;
96
 
97
  /**
98
   * Original source, if created from an ImageProducer.
99
   */
100
  ImageProducer source;
101
 
102
  /*
103
   * The 32-bit AABBGGRR format the GDK uses.
104
   */
105
  static ColorModel nativeModel = new DirectColorModel(32,
106
                                                       0x000000FF,
107
                                                       0x0000FF00,
108
                                                       0x00FF0000,
109
                                                       0xFF000000);
110
 
111
  /**
112
   * The singleton GtkImage that is returned on errors by GtkToolkit.
113
   */
114
  private static GtkImage errorImage;
115
 
116
  /**
117
   * Lock that should be held for all gdkpixbuf operations. We don't use
118
   * the global gdk_threads_enter/leave functions in most places since
119
   * most gdkpixbuf operations can be done in parallel to drawing and
120
   * manipulating gtk widgets.
121
   */
122
  static Object pixbufLock = new Object();
123
 
124
  /**
125
   * Allocate a PixBuf from a given ARGB32 buffer pointer.
126
   */
127
  private native void initFromBuffer( long bufferPointer );
128
 
129
  /**
130
   * Returns a copy of the pixel data as a java array.
131
   * Should be called with the pixbufLock held.
132
   */
133
  native int[] getPixels();
134
 
135
  /**
136
   * Sets the pixel data from a java array.
137
   * Should be called with the pixbufLock held.
138
   */
139
  private native void setPixels(int[] pixels);
140
 
141
  /**
142
   * Loads an image using gdk-pixbuf from a file.
143
   * Should be called with the pixbufLock held.
144
   */
145
  private native boolean loadPixbuf(String name);
146
 
147
  /**
148
   * Loads an image using gdk-pixbuf from data.
149
   * Should be called with the pixbufLock held.
150
   */
151
  private native boolean loadImageFromData(byte[] data);
152
 
153
  /**
154
   * Allocates a Gtk Pixbuf
155
   * Should be called with the pixbufLock held.
156
   */
157
  private native void createPixbuf();
158
 
159
  /**
160
   * Frees the above.
161
   * Should be called with the pixbufLock held.
162
   */
163
  private native void freePixbuf();
164
 
165
  /**
166
   * Sets the pixbuf to scaled copy of src image. hints are rendering hints.
167
   * Should be called with the pixbufLock held.
168
   */
169
  private native void createScaledPixbuf(GtkImage src, int hints);
170
 
171
  /**
172
   * Constructs a GtkImage from an ImageProducer. Asynchronity is handled in
173
   * the following manner:
174
   * A GtkImageConsumer gets the image data, and calls setImage() when
175
   * completely finished. The GtkImage is not considered loaded until the
176
   * GtkImageConsumer is completely finished. We go for all "all or nothing".
177
   */
178
  public GtkImage (ImageProducer producer)
179
  {
180
    isLoaded = false;
181
    observers = new Vector<ImageObserver>();
182
    source = producer;
183
    errorLoading = false;
184
    source.startProduction(new GtkImageConsumer(this, source));
185
  }
186
 
187
  /**
188
   * Constructs a blank GtkImage.  This is called when
189
   * GtkToolkit.createImage (String) is called with an empty string
190
   * argument ("").  A blank image is loaded immediately upon
191
   * construction and has width -1 and height -1.
192
   */
193
  public GtkImage ()
194
  {
195
    isLoaded = true;
196
    observers = null;
197
    props = new Hashtable<String,Object>();
198
    errorLoading = false;
199
  }
200
 
201
  /**
202
   * Constructs a GtkImage by loading a given file.
203
   *
204
   * @throws IllegalArgumentException if the image could not be loaded.
205
   */
206
  public GtkImage (String filename)
207
  {
208
    File f = new File(filename);
209
    try
210
      {
211
        String path = f.getCanonicalPath();
212
        synchronized(pixbufLock)
213
          {
214
            if (loadPixbuf(f.getCanonicalPath()) != true)
215
              throw new IllegalArgumentException("Couldn't load image: "
216
                                                 + filename);
217
          }
218
      }
219
    catch(IOException e)
220
      {
221
        IllegalArgumentException iae;
222
        iae = new IllegalArgumentException("Couldn't load image: "
223
                                           + filename);
224
        iae.initCause(e);
225
        throw iae;
226
      }
227
 
228
    isLoaded = true;
229
    observers = null;
230
    props = new Hashtable<String,Object>();
231
  }
232
 
233
  /**
234
   * Constructs a GtkImage from a byte array of an image file.
235
   *
236
   * @throws IllegalArgumentException if the image could not be
237
   * loaded.
238
   */
239
  public GtkImage (byte[] data)
240
  {
241
    synchronized(pixbufLock)
242
      {
243
        if (loadImageFromData (data) != true)
244
          throw new IllegalArgumentException ("Couldn't load image.");
245
      }
246
 
247
    isLoaded = true;
248
    observers = null;
249
    props = new Hashtable<String,Object>();
250
    errorLoading = false;
251
  }
252
 
253
  /**
254
   * Constructs a GtkImage from a URL. May result in an error image.
255
   */
256
  public GtkImage (URL url)
257
  {
258
    isLoaded = false;
259
    observers = new Vector<ImageObserver>();
260
    errorLoading = false;
261
    if( url == null)
262
      return;
263
    ByteArrayOutputStream baos = new ByteArrayOutputStream (5000);
264
    try
265
      {
266
        BufferedInputStream bis = new BufferedInputStream (url.openStream());
267
 
268
        byte[] buf = new byte[5000];
269
        int n = 0;
270
 
271
        while ((n = bis.read(buf)) != -1)
272
          baos.write(buf, 0, n);
273
        bis.close();
274
      }
275
    catch(IOException e)
276
      {
277
        throw new IllegalArgumentException ("Couldn't load image.");
278
      }
279
    byte[] array = baos.toByteArray();
280
    synchronized(pixbufLock)
281
      {
282
        if (loadImageFromData(array) != true)
283
          throw new IllegalArgumentException ("Couldn't load image.");
284
      }
285
 
286
    isLoaded = true;
287
    observers = null;
288
    props = new Hashtable<String,Object>();
289
  }
290
 
291
  /**
292
   * Constructs a scaled version of the src bitmap, using the GDK.
293
   */
294
  private GtkImage (GtkImage src, int width, int height, int hints)
295
  {
296
    this.width = width;
297
    this.height = height;
298
    props = new Hashtable<String,Object>();
299
    isLoaded = true;
300
    observers = null;
301
 
302
    // Use the GDK scaling method.
303
    synchronized(pixbufLock)
304
      {
305
        createScaledPixbuf(src, hints);
306
      }
307
  }
308
 
309
  /**
310
   * Package private constructor to create a GtkImage from a given
311
   * PixBuf pointer.
312
   */
313
  GtkImage (Pointer pixbuf)
314
  {
315
    this.pixbuf = pixbuf;
316
    synchronized(pixbufLock)
317
      {
318
        createFromPixbuf();
319
      }
320
    isLoaded = true;
321
    observers = null;
322
    props = new Hashtable<String,Object>();
323
  }
324
 
325
  /**
326
   * Wraps a buffer with a GtkImage.
327
   *
328
   * @param bufferPointer a pointer to an ARGB32 buffer
329
   */
330
  GtkImage(int width, int height, long bufferPointer)
331
  {
332
    this.width = width;
333
    this.height = height;
334
    props = new Hashtable<String,Object>();
335
    isLoaded = true;
336
    observers = null;
337
    initFromBuffer( bufferPointer );
338
  }
339
 
340
  /**
341
   * Returns an empty GtkImage with the errorLoading flag set.
342
   * Called from GtkToolKit when some error occured, but an image needs
343
   * to be returned anyway.
344
   */
345
  static synchronized GtkImage getErrorImage()
346
  {
347
    if (errorImage == null)
348
      {
349
        errorImage = new GtkImage();
350
        errorImage.errorLoading = true;
351
      }
352
    return errorImage;
353
  }
354
 
355
  /**
356
   * Native helper function for constructor that takes a pixbuf Pointer.
357
   * Should be called with the pixbufLock held.
358
   */
359
  private native void createFromPixbuf();
360
 
361
  /**
362
   * Callback from the image consumer.
363
   */
364
  public void setImage(int width, int height,
365
                       int[] pixels, Hashtable<?,?> properties)
366
  {
367
    this.width = width;
368
    this.height = height;
369
    props = (properties != null) ? properties : new Hashtable<String,Object>();
370
 
371
    if (width <= 0 || height <= 0 || pixels == null)
372
      {
373
        errorLoading = true;
374
        return;
375
      }
376
 
377
    synchronized(pixbufLock)
378
      {
379
        createPixbuf();
380
        setPixels(pixels);
381
      }
382
    isLoaded = true;
383
    deliver();
384
  }
385
 
386
  // java.awt.Image methods ////////////////////////////////////////////////
387
 
388
  public synchronized int getWidth (ImageObserver observer)
389
  {
390
    if (addObserver(observer))
391
      return -1;
392
 
393
    return width;
394
  }
395
 
396
  public synchronized int getHeight (ImageObserver observer)
397
  {
398
    if (addObserver(observer))
399
      return -1;
400
 
401
    return height;
402
  }
403
 
404
  public synchronized Object getProperty (String name, ImageObserver observer)
405
  {
406
    if (addObserver(observer))
407
      return UndefinedProperty;
408
 
409
    Object value = props.get (name);
410
    return (value == null) ? UndefinedProperty : value;
411
  }
412
 
413
  /**
414
   * Returns the source of this image.
415
   */
416
  public ImageProducer getSource ()
417
  {
418
    if (!isLoaded)
419
      return null;
420
 
421
    int[] pixels;
422
    synchronized (pixbufLock)
423
      {
424
        if (!errorLoading)
425
          pixels = getPixels();
426
        else
427
          return null;
428
      }
429
    return new MemoryImageSource(width, height, nativeModel, pixels,
430
                                 0, width);
431
  }
432
 
433
  /**
434
   * Does nothing. Should not be called.
435
   */
436
  public Graphics getGraphics ()
437
  {
438
    throw new IllegalAccessError("This method only works for off-screen"
439
                                 +" Images.");
440
  }
441
 
442
  /**
443
   * Returns a scaled instance of this pixbuf.
444
   */
445
  public Image getScaledInstance(int width,
446
                                 int height,
447
                                 int hints)
448
  {
449
    if (width <= 0 || height <= 0)
450
      throw new IllegalArgumentException("Width and height of scaled bitmap"
451
                                         + "must be >= 0");
452
 
453
    return new GtkImage(this, width, height, hints);
454
  }
455
 
456
  /**
457
   * If the image is loaded and comes from an ImageProducer,
458
   * regenerate the image from there.
459
   *
460
   * I have no idea if this is ever actually used. Since GtkImage can't be
461
   * instantiated directly, how is the user to know if it was created from
462
   * an ImageProducer or not?
463
   */
464
  public synchronized void flush ()
465
  {
466
    if (isLoaded && source != null)
467
      {
468
        observers = new Vector<ImageObserver>();
469
        isLoaded = false;
470
        synchronized(pixbufLock)
471
          {
472
            freePixbuf();
473
          }
474
        source.startProduction(new GtkImageConsumer(this, source));
475
      }
476
  }
477
 
478
  public void finalize()
479
  {
480
    if (isLoaded)
481
      {
482
        synchronized(pixbufLock)
483
          {
484
            freePixbuf();
485
          }
486
      }
487
  }
488
 
489
  /**
490
   * Returns the image status, used by GtkToolkit
491
   */
492
  public int checkImage (ImageObserver observer)
493
  {
494
    if (addObserver(observer))
495
      {
496
        if (errorLoading == true)
497
          return ImageObserver.ERROR;
498
        else
499
          return 0;
500
      }
501
 
502
    return ImageObserver.ALLBITS | ImageObserver.WIDTH | ImageObserver.HEIGHT;
503
  }
504
 
505
 
506
  // Private methods ////////////////////////////////////////////////
507
 
508
  /**
509
   * Delivers notifications to all queued observers.
510
   */
511
  private void deliver()
512
  {
513
    int flags = ImageObserver.HEIGHT |
514
      ImageObserver.WIDTH |
515
      ImageObserver.PROPERTIES |
516
      ImageObserver.ALLBITS;
517
 
518
    if (observers != null)
519
      for(int i=0; i < observers.size(); i++)
520
        ((ImageObserver)observers.elementAt(i)).imageUpdate(this, flags, 0, 0,
521
                                                            width, height);
522
 
523
    observers = null;
524
  }
525
 
526
  /**
527
   * Adds an observer, if we need to.
528
   * @return true if an observer was added.
529
   */
530
  private boolean addObserver(ImageObserver observer)
531
  {
532
    if (!isLoaded)
533
      {
534
        if(observer != null)
535
          if (!observers.contains (observer))
536
            observers.addElement (observer);
537
        return true;
538
      }
539
    return false;
540
  }
541
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.