1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51:
52:
57: public class CairoSurface extends DataBuffer
58: {
59: int width = -1, height = -1;
60:
61:
64: long surfacePointer;
65:
66:
69: long bufferPointer;
70:
71:
72: static ColorModel nativeModel = new DirectColorModel(32,
73: 0x00FF0000,
74: 0x0000FF00,
75: 0x000000FF,
76: 0xFF000000);
77:
78:
83: private native void create(int width, int height, int stride);
84:
85:
88: private native void destroy(long surfacePointer, long bufferPointer);
89:
90:
93: private native int nativeGetElem(long bufferPointer, int i);
94:
95:
98: private native void nativeSetElem(long bufferPointer, int i, int val);
99:
100:
104: public native void nativeDrawSurface(long surfacePointer, long contextPointer,
105: double[] i2u, double alpha);
106:
107: public void drawSurface(long contextPointer, double[] i2u, double alpha)
108: {
109: nativeDrawSurface(surfacePointer, contextPointer, i2u, alpha);
110: }
111:
112:
115: native int[] nativeGetPixels(long bufferPointer, int size);
116:
117: public int[] getPixels(int size)
118: {
119: return nativeGetPixels(bufferPointer, size);
120: }
121:
122:
125: native void nativeSetPixels(long bufferPointer, int[] pixels);
126:
127: public void setPixels(int[] pixels)
128: {
129: nativeSetPixels(bufferPointer, pixels);
130: }
131:
132: native long getFlippedBuffer(long bufferPointer, int size);
133:
134:
139: public CairoSurface(int width, int height)
140: {
141: super(DataBuffer.TYPE_INT, width * height);
142:
143: if(width <= 0 || height <= 0)
144: throw new IllegalArgumentException("Image must be at least 1x1 pixels.");
145:
146: this.width = width;
147: this.height = height;
148:
149: create(width, height, width);
150:
151: if(surfacePointer == 0 || bufferPointer == 0)
152: throw new Error("Could not allocate bitmap.");
153: }
154:
155:
159: CairoSurface(GtkImage image)
160: {
161: super(DataBuffer.TYPE_INT, image.width * image.height);
162:
163: if(image.width <= 0 || image.height <= 0)
164: throw new IllegalArgumentException("Image must be at least 1x1 pixels.");
165:
166: width = image.width;
167: height = image.height;
168:
169: create(width, height, width);
170:
171: if(surfacePointer == 0 || bufferPointer == 0)
172: throw new Error("Could not allocate bitmap.");
173:
174:
175: int[] data = image.getPixels();
176:
177:
178: if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN)
179: {
180: for (int i = 0; i < data.length; i++ )
181: {
182:
183: int alpha = data[i] & 0xFF;
184: if( alpha == 0 )
185: data[i] = 0;
186: else
187: {
188:
189: data[i] = (data[i] >>> 8) | (alpha << 24);
190: }
191: }
192: }
193: else
194: {
195: for (int i = 0; i < data.length; i++ )
196: {
197:
198: int alpha = data[i] & 0xFF000000;
199: if( alpha == 0 )
200: data[i] = 0;
201: else
202: {
203: int b = (data[i] & 0xFF0000) >> 16;
204: int g = (data[i] & 0xFF00);
205: int r = (data[i] & 0xFF) << 16;
206:
207: data[i] = alpha | r | g | b;
208: }
209: }
210: }
211:
212: setPixels( data );
213: }
214:
215:
218: public void dispose()
219: {
220: if(surfacePointer != 0)
221: destroy(surfacePointer, bufferPointer);
222: }
223:
224:
227: protected void finalize()
228: {
229: dispose();
230: }
231:
232:
235: public GtkImage getGtkImage()
236: {
237: return new GtkImage( width, height,
238: getFlippedBuffer(bufferPointer, width * height ));
239: }
240:
241:
244: public static BufferedImage getBufferedImage(int width, int height)
245: {
246: return getBufferedImage(new CairoSurface(width, height));
247: }
248:
249:
253: public static BufferedImage getBufferedImage(GtkImage image)
254: {
255: return getBufferedImage(new CairoSurface(image));
256: }
257:
258:
261: public static BufferedImage getBufferedImage(CairoSurface surface)
262: {
263: WritableRaster raster = Raster.createPackedRaster
264: (surface, surface.width, surface.height, surface.width,
265: new int[]{ 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 },
266: new Point(0,0));
267:
268: return new BufferedImage(nativeModel, raster, true, new Hashtable());
269: }
270:
271:
274: public int getElem(int bank, int i)
275: {
276: if(bank != 0 || i < 0 || i >= width*height)
277: throw new IndexOutOfBoundsException(i+" size: "+width*height);
278: return nativeGetElem(bufferPointer, i);
279: }
280:
281:
284: public void setElem(int bank, int i, int val)
285: {
286: if(bank != 0 || i < 0 || i >= width*height)
287: throw new IndexOutOfBoundsException(i+" size: "+width*height);
288: nativeSetElem(bufferPointer, i, val);
289: }
290:
291:
294: public Graphics2D getGraphics()
295: {
296: return new CairoSurfaceGraphics(this);
297: }
298:
299:
300:
304: native long nativeNewCairoContext(long surfacePointer);
305:
306: public long newCairoContext()
307: {
308: return nativeNewCairoContext(surfacePointer);
309: }
310:
311:
315: native void copyAreaNative2(long bufferPointer, int x, int y, int width,
316: int height, int dx, int dy, int stride);
317: public void copyAreaNative(int x, int y, int width,
318: int height, int dx, int dy, int stride)
319: {
320: copyAreaNative2(bufferPointer, x, y, width, height, dx, dy, stride);
321: }
322: }