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: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57:
58:
64: public class ComponentGraphics extends CairoGraphics2D
65: {
66: private static final boolean hasXRenderExtension = hasXRender();
67:
68: private GtkComponentPeer component;
69: protected long cairo_t;
70:
71: private static ThreadLocal hasLock = new ThreadLocal();
72: private static Integer ONE = Integer.valueOf(1);
73:
74: private void lock()
75: {
76: Integer i = (Integer) hasLock.get();
77: if (i == null)
78: {
79: start_gdk_drawing();
80: hasLock.set(ONE);
81: }
82: else
83: hasLock.set(Integer.valueOf(i.intValue() + 1));
84: }
85:
86: private void unlock()
87: {
88: Integer i = (Integer) hasLock.get();
89: if (i == null)
90: throw new IllegalStateException();
91: if (i == ONE)
92: {
93: hasLock.set(null);
94: end_gdk_drawing();
95: }
96: else
97: hasLock.set(Integer.valueOf(i.intValue() - 1));
98: }
99:
100: ComponentGraphics()
101: {
102: }
103:
104: private ComponentGraphics(GtkComponentPeer component)
105: {
106: this.component = component;
107: cairo_t = initState(component);
108: setup( cairo_t );
109: Rectangle bounds = component.awtComponent.getBounds();
110: setClip( new Rectangle( 0, 0, bounds.width, bounds.height) );
111: setBackground(component.awtComponent.getBackground());
112: setColor(component.awtComponent.getForeground());
113: }
114:
115: private ComponentGraphics(ComponentGraphics cg)
116: {
117: component = cg.component;
118: cairo_t = initState(component);
119: copy( cg, cairo_t );
120: Rectangle bounds = component.awtComponent.getBounds();
121: setClip( new Rectangle( 0, 0, bounds.width, bounds.height) );
122: setBackground(component.awtComponent.getBackground());
123: setColor(component.awtComponent.getForeground());
124: }
125:
126:
129: private native long initState(GtkComponentPeer component);
130:
131:
135: public void dispose()
136: {
137: super.dispose();
138: disposeSurface(nativePointer);
139: }
140:
141:
144: private native void disposeSurface(long nativePointer);
145:
146:
149: protected native long initFromVolatile( long pixmapPtr, int width, int height);
150:
151:
154: private native void start_gdk_drawing();
155:
156:
159: private native void end_gdk_drawing();
160:
161:
164: public static native boolean hasXRender();
165:
166:
170: private static native Pointer nativeGrab(GtkComponentPeer component);
171:
172: private native void copyAreaNative(GtkComponentPeer component, int x, int y,
173: int width, int height, int dx, int dy);
174:
175: private native void drawVolatile(GtkComponentPeer component,
176: long vimg, int x, int y,
177: int width, int height, int cx, int cy,
178: int cw, int ch);
179:
180:
183: public static GtkImage grab( GtkComponentPeer component )
184: {
185: return new GtkImage( nativeGrab( component ) );
186: }
187:
188:
192: public static Graphics2D getComponentGraphics(GtkComponentPeer component)
193: {
194: if( hasXRenderExtension )
195: return new ComponentGraphics(component);
196:
197: Rectangle r = component.awtComponent.getBounds();
198: return new ComponentGraphicsCopy(r.width, r.height, component);
199: }
200:
201: public GraphicsConfiguration getDeviceConfiguration()
202: {
203: return component.getGraphicsConfiguration();
204: }
205:
206: public Graphics create()
207: {
208: return new ComponentGraphics(this);
209: }
210:
211: protected Rectangle2D getRealBounds()
212: {
213: return component.awtComponent.getBounds();
214: }
215:
216: public void copyAreaImpl(int x, int y, int width, int height, int dx, int dy)
217: {
218: copyAreaNative(component, x, y, width, height, dx, dy);
219: }
220:
221:
225: public void draw(Shape s)
226: {
227: lock();
228: try
229: {
230: super.draw(s);
231: }
232: finally
233: {
234: unlock();
235: }
236: }
237:
238: public void fill(Shape s)
239: {
240: lock();
241: try
242: {
243: super.fill(s);
244: }
245: finally
246: {
247: unlock();
248: }
249: }
250:
251: public void drawRenderedImage(RenderedImage image, AffineTransform xform)
252: {
253: lock();
254: try
255: {
256: super.drawRenderedImage(image, xform);
257: }
258: finally
259: {
260: unlock();
261: }
262: }
263:
264: protected boolean drawImage(Image img, AffineTransform xform,
265: Color bgcolor, ImageObserver obs)
266: {
267: boolean rv;
268: lock();
269: try
270: {
271: rv = super.drawImage(img, xform, bgcolor, obs);
272: }
273: finally
274: {
275: unlock();
276: }
277: return rv;
278: }
279:
280: public void drawGlyphVector(GlyphVector gv, float x, float y)
281: {
282: lock();
283: try
284: {
285: super.drawGlyphVector(gv, x, y);
286: }
287: finally
288: {
289: unlock();
290: }
291: }
292:
293: public boolean drawImage(Image img, int x, int y, ImageObserver observer)
294: {
295:
296:
297:
298: if (img instanceof GtkVolatileImage)
299: {
300: GtkVolatileImage vimg = (GtkVolatileImage) img;
301: int type = transform.getType();
302: if ((type == AffineTransform.TYPE_IDENTITY
303: || type == AffineTransform.TYPE_TRANSLATION)
304: && (clip == null || clip instanceof Rectangle2D))
305: {
306: Rectangle2D r = (Rectangle2D) clip;
307: if (r == null)
308: r = getRealBounds();
309: x += transform.getTranslateX();
310: y += transform.getTranslateY();
311: drawVolatile(component, vimg.nativePointer,
312: x, y, vimg.width, vimg.height,
313: (int) (r.getX() + transform.getTranslateX()),
314: (int) (r.getY() + transform.getTranslateY()),
315: (int) r.getWidth(),
316: (int) r.getHeight());
317: return true;
318: }
319: else
320: return super.drawImage(vimg.getSnapshot(), x, y, observer);
321: }
322:
323: BufferedImage bimg;
324: if (img instanceof BufferedImage)
325: bimg = (BufferedImage) img;
326: else
327: {
328: ImageProducer source = img.getSource();
329: if (source == null)
330: return false;
331: bimg = (BufferedImage) Toolkit.getDefaultToolkit().createImage(source);
332: }
333: return super.drawImage(bimg, x, y, observer);
334: }
335:
336: public boolean drawImage(Image img, int x, int y, int width, int height,
337: ImageObserver observer)
338: {
339:
340:
341:
342: if (img instanceof GtkVolatileImage
343: && (clip == null || clip instanceof Rectangle2D))
344: {
345: GtkVolatileImage vimg = (GtkVolatileImage) img;
346: int type = transform.getType();
347: if ((type == AffineTransform.TYPE_IDENTITY
348: || type == AffineTransform.TYPE_TRANSLATION)
349: && (clip == null || clip instanceof Rectangle2D))
350: {
351: Rectangle2D r = (Rectangle2D) clip;
352: if (r == null)
353: r = getRealBounds();
354: x += transform.getTranslateX();
355: y += transform.getTranslateY();
356: drawVolatile(component, vimg.nativePointer,
357: x, y, width, height,
358: (int) (r.getX() + transform.getTranslateX()),
359: (int) (r.getY() + transform.getTranslateY()),
360: (int) r.getWidth(),
361: (int) r.getHeight());
362: return true;
363: }
364: else
365: return super.drawImage(vimg.getSnapshot(), x, y,
366: width, height, observer);
367: }
368:
369: BufferedImage bimg;
370: if (img instanceof BufferedImage)
371: bimg = (BufferedImage) img;
372: else
373: {
374: ImageProducer source = img.getSource();
375: if (source == null)
376: return false;
377: bimg = (BufferedImage) Toolkit.getDefaultToolkit().createImage(source);
378: }
379: return super.drawImage(bimg, x, y, width, height, observer);
380: }
381:
382: public void drawLine(int x1, int y1, int x2, int y2)
383: {
384: lock();
385: try
386: {
387: super.drawLine(x1, y1, x2, y2);
388: }
389: finally
390: {
391: unlock();
392: }
393: }
394:
395: public void drawRect(int x, int y, int width, int height)
396: {
397: lock();
398: try
399: {
400: super.drawRect(x, y, width, height);
401: }
402: finally
403: {
404: unlock();
405: }
406: }
407:
408: public void fillRect(int x, int y, int width, int height)
409: {
410: lock();
411: try
412: {
413: super.fillRect(x, y, width, height);
414: }
415: finally
416: {
417: unlock();
418: }
419: }
420:
421: public void setClip(Shape s)
422: {
423: lock();
424: try
425: {
426: super.setClip(s);
427: }
428: finally
429: {
430: unlock();
431: }
432: }
433:
434: }