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/] [CairoSurface.java] - Blame information for rev 769

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 769 jeremybenn
/* CairoSurface.java
2
   Copyright (C) 2006, 2007 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 gnu.java.awt.Buffers;
42
 
43
import java.awt.Graphics2D;
44
import java.awt.Point;
45
import java.awt.Rectangle;
46
import java.awt.color.ColorSpace;
47
import java.awt.image.BufferedImage;
48
import java.awt.image.ColorModel;
49
import java.awt.image.DataBuffer;
50
import java.awt.image.DataBufferInt;
51
import java.awt.image.DirectColorModel;
52
import java.awt.image.Raster;
53
import java.awt.image.RasterFormatException;
54
import java.awt.image.SampleModel;
55
import java.awt.image.SinglePixelPackedSampleModel;
56
import java.awt.image.WritableRaster;
57
import java.nio.ByteOrder;
58
import java.util.Arrays;
59
import java.util.Hashtable;
60
 
61
/**
62
 * CairoSurface - wraps a Cairo surface.
63
 *
64
 * @author Sven de Marothy
65
 */
66
public class CairoSurface extends WritableRaster
67
{
68
  int width = -1, height = -1;
69
 
70
  /**
71
   * The native pointer to the Cairo surface.
72
   */
73
  long surfacePointer;
74
 
75
  /**
76
   * Whether the data buffer is shared between java and cairo.
77
   */
78
  boolean sharedBuffer;
79
 
80
  // FIXME: use only the cairoCM_pre colormodel
81
  // since that's what Cairo really uses (is there a way to do this cheaply?
82
  // we use a non-multiplied model most of the time to avoid costly coercion
83
  // operations...)
84
  static ColorModel cairoColorModel = new DirectColorModel(32, 0x00FF0000,
85
                                                           0x0000FF00,
86
                                                           0x000000FF,
87
                                                           0xFF000000);
88
 
89
  static ColorModel cairoCM_pre = new DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
90
                                                       32, 0x00FF0000,
91
                                                       0x0000FF00,
92
                                                       0x000000FF,
93
                                                       0xFF000000,
94
                                                       true,
95
                                                       Buffers.smallestAppropriateTransferType(32));
96
 
97
  // This CM corresponds to the CAIRO_FORMAT_RGB24 type in Cairo
98
  static ColorModel cairoCM_opaque = new DirectColorModel(24, 0x00FF0000,
99
                                                          0x0000FF00,
100
                                                          0x000000FF);
101
  /**
102
   * Allocates and clears the buffer and creates the cairo surface.
103
   * @param width - the image size
104
   * @param height - the image size
105
   * @param stride - the buffer row stride. (in ints)
106
   */
107
  private native void create(int width, int height, int stride, int[] buf);
108
 
109
  /**
110
   * Destroys the cairo surface and frees the buffer.
111
   */
112
  private native void destroy(long surfacePointer, int[] buf);
113
 
114
  /**
115
   * Draws this image to a given CairoGraphics context,
116
   * with an affine transform given by i2u.
117
   */
118
  public native void nativeDrawSurface(long surfacePointer, long contextPointer,
119
                                       double[] i2u, double alpha,
120
                                       int interpolation);
121
 
122
  /**
123
   * Synchronizes the image's data buffers, copying any changes made in the
124
   * Java array into the native array.
125
   *
126
   * This method should only be called if (sharedBuffers == false).
127
   */
128
  native void syncNativeToJava(long surfacePointer, int[] buffer);
129
 
130
  /**
131
   * Synchronizes the image's data buffers, copying any changes made in the
132
   * native array into the Java array.
133
   *
134
   * This method should only be called if (sharedBuffers == false).
135
   */
136
  native void syncJavaToNative(long surfacePointer, int[] buffer);
137
 
138
  /**
139
   * Return the buffer, with the sample values of each pixel reversed
140
   * (ie, in ABGR instead of ARGB).
141
   *
142
   * @return A pointer to a flipped buffer.  The memory is allocated in native
143
   *        code, and must be explicitly freed when it is no longer needed.
144
   */
145
  native long getFlippedBuffer(long surfacePointer);
146
 
147
  /**
148
   * Create a cairo_surface_t with specified width and height.
149
   * The format will be ARGB32 with premultiplied alpha and native bit
150
   * and word ordering.
151
   */
152
  public CairoSurface(int width, int height)
153
  {
154
    this(0, 0, width, height);
155
  }
156
 
157
  public CairoSurface(int x, int y, int width, int height)
158
  {
159
    super(createCairoSampleModel(width, height), null, new Point(x, y));
160
 
161
    if(width <= 0 || height <= 0)
162
      throw new IllegalArgumentException("Image must be at least 1x1 pixels.");
163
 
164
    this.width = width;
165
    this.height = height;
166
    dataBuffer = new DataBufferInt(width * height);
167
    create(width, height, width, getData());
168
 
169
    if(surfacePointer == 0)
170
      throw new Error("Could not allocate bitmap.");
171
  }
172
 
173
  /**
174
   * Create a Cairo Surface that is a subimage of another Cairo Surface
175
   */
176
  public CairoSurface(SampleModel sm, CairoSurface parent, Rectangle bounds,
177
                      Point origin)
178
  {
179
    super(sm, parent.dataBuffer, bounds, origin, parent);
180
 
181
    this.width = super.width;
182
    this.height = super.height;
183
    this.surfacePointer = parent.surfacePointer;
184
    this.sharedBuffer = parent.sharedBuffer;
185
    this.dataBuffer = parent.dataBuffer;
186
  }
187
 
188
  /**
189
   * Create a cairo_surface_t from a GtkImage instance.
190
   * (data is copied, not shared)
191
   */
192
  CairoSurface(GtkImage image)
193
  {
194
    this(image.width, image.height);
195
 
196
    // Copy the pixel data from the GtkImage.
197
    int[] data = image.getPixels();
198
 
199
    // Swap ordering from GdkPixbuf to Cairo
200
    if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN)
201
      {
202
        for (int i = 0; i < data.length; i++ )
203
          {
204
            // On a big endian system we get a RRGGBBAA data array.
205
            int alpha = data[i] & 0xFF;
206
            if( alpha == 0 ) // I do not know why we need this, but it works.
207
              data[i] = 0;
208
            else
209
              {
210
                // Cairo needs a ARGB32 native array.
211
                data[i] = (data[i] >>> 8) | (alpha << 24);
212
              }
213
          }
214
      }
215
    else
216
      {
217
        for (int i = 0; i < data.length; i++ )
218
          {
219
            // On a little endian system we get a AABBGGRR data array.
220
            int alpha = data[i] & 0xFF000000;
221
            if( alpha == 0 ) // I do not know why we need this, but it works.
222
              data[i] = 0;
223
            else
224
              {
225
                int b = (data[i] & 0xFF0000) >> 16;
226
                int g = (data[i] & 0xFF00);
227
                int r = (data[i] & 0xFF) << 16;
228
                // Cairo needs a ARGB32 native array.
229
                data[i] = alpha | r | g | b;
230
              }
231
          }
232
      }
233
 
234
    System.arraycopy(data, 0, getData(), 0, data.length);
235
  }
236
 
237
  /**
238
   * Dispose of the native data.
239
   */
240
  public void dispose()
241
  {
242
    if(surfacePointer != 0 && parent == null)
243
      destroy(surfacePointer, getData());
244
  }
245
 
246
  /**
247
   * Call dispose() to clean up any native resources allocated.
248
   */
249
  protected void finalize()
250
  {
251
    dispose();
252
  }
253
 
254
  /**
255
   * Return a GtkImage from this Cairo surface.
256
   */
257
  public GtkImage getGtkImage()
258
  {
259
    return new GtkImage(width, height, getFlippedBuffer(surfacePointer));
260
  }
261
 
262
  /**
263
   * Convenience method to quickly grab the data array backing this Raster.
264
   *
265
   * @return The array behind the databuffer.
266
   */
267
  public int[] getData()
268
  {
269
    return ((DataBufferInt)dataBuffer).getData();
270
  }
271
 
272
  /**
273
   * Returns a BufferedImage backed by a Cairo surface.
274
   */
275
  public static BufferedImage getBufferedImage(int width, int height)
276
  {
277
    return getBufferedImage(new CairoSurface(width, height));
278
  }
279
 
280
  /**
281
   * Returns a BufferedImage backed by a Cairo surface,
282
   * created from a GtkImage.
283
   */
284
  public static BufferedImage getBufferedImage(GtkImage image)
285
  {
286
    return getBufferedImage(new CairoSurface(image));
287
  }
288
 
289
  /**
290
   * Returns a BufferedImage backed by a Cairo surface.
291
   */
292
  public static BufferedImage getBufferedImage(CairoSurface surface)
293
  {
294
    return new BufferedImage(cairoColorModel, surface,
295
                             cairoColorModel.isAlphaPremultiplied(),
296
                             new Hashtable());
297
  }
298
 
299
  /**
300
   * Return a Graphics2D drawing to the CairoSurface.
301
   */
302
  public Graphics2D getGraphics()
303
  {
304
    return new CairoSurfaceGraphics(this);
305
  }
306
 
307
  ///// Methods used by CairoSurfaceGraphics /////
308
  /**
309
   * Creates a cairo_t drawing context, returns the pointer as a long.
310
   * Used by CairoSurfaceGraphics.
311
   */
312
  native long nativeNewCairoContext(long surfacePointer);
313
 
314
  public long newCairoContext()
315
  {
316
    return nativeNewCairoContext(surfacePointer);
317
  }
318
 
319
  /**
320
   * Copy a portion of this surface to another area on the surface.  The given
321
   * parameters must be within bounds - count on a segfault otherwise.
322
   *
323
   * @param x The x coordinate of the area to be copied from.
324
   * @param y The y coordinate of the area to be copied from.
325
   * @param width The width of the area to be copied.
326
   * @param height The height of the area to be copied.
327
   * @param dx The destination x coordinate.
328
   * @param dy The destination y coordinate.
329
   * @param stride The scanline stride.
330
   */
331
  public void copyAreaNative(int x, int y, int width,
332
                             int height, int dx, int dy, int stride)
333
  {
334
    copyAreaNative2(surfacePointer, x, y, width, height, dx, dy, stride);
335
  }
336
  native void copyAreaNative2(long surfacePointer,
337
                              int x, int y, int width, int height,
338
                              int dx, int dy, int stride);
339
 
340
  /**
341
   * Creates a SampleModel that matches Cairo's native format
342
   */
343
  protected static SampleModel createCairoSampleModel(int w, int h)
344
  {
345
    return new SinglePixelPackedSampleModel(DataBuffer.TYPE_INT, w, h,
346
                                            new int[]{0x00FF0000, 0x0000FF00,
347
                                                      0x000000FF, 0xFF000000});
348
  }
349
 
350
  /**
351
   * Returns whether this ColorModel is compatible with Cairo's native types.
352
   *
353
   * @param cm The color model to check.
354
   * @return Whether it is compatible.
355
   */
356
  public static boolean isCompatibleColorModel(ColorModel cm)
357
  {
358
    return (cm.equals(cairoCM_pre) || cm.equals(cairoCM_opaque) ||
359
            cm.equals(cairoColorModel));
360
  }
361
 
362
  /**
363
   * Returns whether this SampleModel is compatible with Cairo's native types.
364
   *
365
   * @param sm The sample model to check.
366
   * @return Whether it is compatible.
367
   */
368
  public static boolean isCompatibleSampleModel(SampleModel sm)
369
  {
370
    return (sm instanceof SinglePixelPackedSampleModel
371
        && sm.getDataType() == DataBuffer.TYPE_INT
372
        && Arrays.equals(((SinglePixelPackedSampleModel)sm).getBitMasks(),
373
                         new int[]{0x00FF0000, 0x0000FF00,
374
                                   0x000000FF, 0xFF000000}));
375
  }
376
 
377
  ///// Methods interhited from Raster and WritableRaster /////
378
  public Raster createChild(int parentX, int parentY, int width, int height,
379
                            int childMinX, int childMinY, int[] bandList)
380
  {
381
    return createWritableChild(parentX, parentY, width, height,
382
                               childMinX, childMinY, bandList);
383
  }
384
 
385
  public WritableRaster createCompatibleWritableRaster()
386
  {
387
    return new CairoSurface(width, height);
388
  }
389
 
390
  public WritableRaster createCompatibleWritableRaster (int x, int y,
391
                                                        int w, int h)
392
  {
393
    return new CairoSurface(x, y, w, h);
394
  }
395
 
396
  public Raster createTranslatedChild(int childMinX, int childMinY)
397
  {
398
    return createWritableTranslatedChild(childMinX, childMinY);
399
  }
400
 
401
  public WritableRaster createWritableChild(int parentX, int parentY,
402
                                            int w, int h, int childMinX,
403
                                            int childMinY, int[] bandList)
404
  {
405
    if (parentX < minX || parentX + w > minX + width
406
        || parentY < minY || parentY + h > minY + height)
407
      throw new RasterFormatException("Child raster extends beyond parent");
408
 
409
    SampleModel sm = (bandList == null) ?
410
      sampleModel :
411
      sampleModel.createSubsetSampleModel(bandList);
412
 
413
    return new CairoSurface(sm, this,
414
                            new Rectangle(childMinX, childMinY, w, h),
415
                            new Point(sampleModelTranslateX + childMinX - parentX,
416
                                      sampleModelTranslateY + childMinY - parentY));
417
  }
418
 
419
  public WritableRaster createWritableTranslatedChild(int x, int y)
420
  {
421
    int tcx = sampleModelTranslateX - minX + x;
422
    int tcy = sampleModelTranslateY - minY + y;
423
 
424
    return new CairoSurface(sampleModel, this,
425
                      new Rectangle(x, y, width, height),
426
                      new Point(tcx, tcy));
427
  }
428
}

powered by: WebSVN 2.1.0

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