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: import ;
58: import ;
59: import ;
60: import ;
61:
62:
65: public class CairoSurfaceGraphics extends CairoGraphics2D
66: {
67: protected CairoSurface surface;
68: private BufferedImage buffer;
69: private long cairo_t;
70:
71:
74: public CairoSurfaceGraphics(CairoSurface surface)
75: {
76: this.surface = surface;
77: cairo_t = surface.newCairoContext();
78: setup( cairo_t );
79: setClip(0, 0, surface.width, surface.height);
80: }
81:
82:
86: private CairoSurfaceGraphics(CairoSurfaceGraphics copyFrom)
87: {
88: surface = copyFrom.surface;
89: cairo_t = surface.newCairoContext();
90: copy( copyFrom, cairo_t );
91: }
92:
93: public Graphics create()
94: {
95: return new CairoSurfaceGraphics(this);
96: }
97:
98: public GraphicsConfiguration getDeviceConfiguration()
99: {
100: return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
101: }
102:
103: protected Rectangle2D getRealBounds()
104: {
105: return new Rectangle2D.Double(0.0, 0.0, surface.width, surface.height);
106: }
107:
108: public void copyAreaImpl(int x, int y, int width, int height, int dx, int dy)
109: {
110: surface.copyAreaNative(x, y, width, height, dx, dy, surface.width);
111: }
112:
113:
117: public void draw(Shape s)
118: {
119: if (!surface.sharedBuffer)
120: surface.syncJavaToNative(surface.surfacePointer, surface.getData());
121:
122:
123: Rectangle r = findStrokedBounds(s);
124: if (shiftDrawCalls)
125: {
126: r.width++;
127: r.height++;
128: }
129:
130:
131: if (comp == null || comp instanceof AlphaComposite)
132: super.draw(s);
133:
134: else
135: {
136: createBuffer();
137:
138: Graphics2D g2d = (Graphics2D)buffer.getGraphics();
139: g2d.setStroke(this.getStroke());
140: g2d.setColor(this.getColor());
141: g2d.setTransform(transform);
142: g2d.draw(s);
143:
144: drawComposite(r.getBounds2D(), null);
145: }
146:
147: if (!surface.sharedBuffer)
148: surface.syncNativeToJava(surface.surfacePointer, surface.getData());
149: }
150:
151: public void fill(Shape s)
152: {
153: if (!surface.sharedBuffer)
154: surface.syncJavaToNative(surface.surfacePointer, surface.getData());
155:
156: if (comp == null || comp instanceof AlphaComposite)
157: super.fill(s);
158:
159: else
160: {
161: createBuffer();
162:
163: Graphics2D g2d = (Graphics2D)buffer.getGraphics();
164: g2d.setPaint(this.getPaint());
165: g2d.setColor(this.getColor());
166: g2d.setTransform(transform);
167: g2d.fill(s);
168:
169: drawComposite(s.getBounds2D(), null);
170: }
171:
172: if (!surface.sharedBuffer)
173: surface.syncNativeToJava(surface.surfacePointer, surface.getData());
174: }
175:
176: public void drawRenderedImage(RenderedImage image, AffineTransform xform)
177: {
178: if (!surface.sharedBuffer)
179: surface.syncJavaToNative(surface.surfacePointer, surface.getData());
180:
181: if (comp == null || comp instanceof AlphaComposite)
182: super.drawRenderedImage(image, xform);
183:
184: else
185: {
186: createBuffer();
187:
188: Graphics2D g2d = (Graphics2D)buffer.getGraphics();
189: g2d.setRenderingHints(this.getRenderingHints());
190: g2d.setTransform(transform);
191: g2d.drawRenderedImage(image, xform);
192:
193: drawComposite(buffer.getRaster().getBounds(), null);
194: }
195:
196: if (!surface.sharedBuffer)
197: surface.syncNativeToJava(surface.surfacePointer, surface.getData());
198: }
199:
200: protected boolean drawImage(Image img, AffineTransform xform,
201: Color bgcolor, ImageObserver obs)
202: {
203: if (!surface.sharedBuffer)
204: surface.syncJavaToNative(surface.surfacePointer, surface.getData());
205:
206: boolean ret;
207: if (comp == null || comp instanceof AlphaComposite)
208: ret = super.drawImage(img, xform, bgcolor, obs);
209:
210: else
211: {
212:
213: if( !(img instanceof BufferedImage) )
214: {
215: ImageProducer source = img.getSource();
216: if (source == null)
217: return false;
218: img = Toolkit.getDefaultToolkit().createImage(source);
219: }
220: BufferedImage bImg = (BufferedImage) img;
221:
222:
223: Rectangle2D bounds = new Rectangle(bImg.getMinX(), bImg.getMinY(),
224: bImg.getWidth(), bImg.getHeight());
225: if (xform != null)
226: bounds = getTransformedBounds(bounds, xform);
227:
228:
229: createBuffer();
230:
231: Graphics2D g2d = (Graphics2D)buffer.getGraphics();
232: g2d.setRenderingHints(this.getRenderingHints());
233: g2d.drawImage(img, xform, obs);
234:
235:
236: ret = drawComposite(bounds, obs);
237: }
238:
239: if (!surface.sharedBuffer)
240: surface.syncNativeToJava(surface.surfacePointer, surface.getData());
241:
242: return ret;
243: }
244:
245: public void drawGlyphVector(GlyphVector gv, float x, float y)
246: {
247: if (!surface.sharedBuffer)
248: surface.syncJavaToNative(surface.surfacePointer, surface.getData());
249:
250: if (comp == null || comp instanceof AlphaComposite)
251: super.drawGlyphVector(gv, x, y);
252:
253: else
254: {
255: createBuffer();
256:
257: Graphics2D g2d = (Graphics2D)buffer.getGraphics();
258: g2d.setPaint(this.getPaint());
259: g2d.setStroke(this.getStroke());
260: g2d.drawGlyphVector(gv, x, y);
261:
262: Rectangle2D bounds = gv.getLogicalBounds();
263: bounds = new Rectangle2D.Double(x + bounds.getX(), y + bounds.getY(),
264: bounds.getWidth(), bounds.getHeight());
265: drawComposite(bounds, null);
266: }
267:
268: if (!surface.sharedBuffer)
269: surface.syncNativeToJava(surface.surfacePointer, surface.getData());
270: }
271:
272: private boolean drawComposite(Rectangle2D bounds, ImageObserver observer)
273: {
274:
275: bounds = getTransformedBounds(bounds, transform);
276:
277:
278: Rectangle2D devClip = this.getClipInDevSpace();
279: Rectangle2D.intersect(bounds, devClip, bounds);
280: devClip = new Rectangle(buffer.getMinX(), buffer.getMinY(),
281: buffer.getWidth(), buffer.getHeight());
282: Rectangle2D.intersect(bounds, devClip, bounds);
283:
284:
285:
286: double x = bounds.getX();
287: double y = bounds.getY();
288: double maxX = x + bounds.getWidth();
289: double maxY = y + bounds.getHeight();
290: x = Math.round(x);
291: y = Math.round(y);
292: bounds.setRect(x, y, Math.round(maxX - x), Math.round(maxY - y));
293:
294:
295: BufferedImage buffer2 = buffer;
296: if (!bounds.equals(buffer2.getRaster().getBounds()))
297: buffer2 = buffer2.getSubimage((int)bounds.getX(), (int)bounds.getY(),
298: (int)bounds.getWidth(),
299: (int)bounds.getHeight());
300:
301:
302: BufferedImage current = CairoSurface.getBufferedImage(surface);
303: current = current.getSubimage((int)bounds.getX(), (int)bounds.getY(),
304: (int)bounds.getWidth(),
305: (int)bounds.getHeight());
306:
307:
308: compCtx.compose(buffer2.getRaster(), current.getRaster(),
309: buffer2.getRaster());
310:
311:
312:
313: Composite oldcomp = comp;
314: setComposite(AlphaComposite.Src);
315:
316:
317:
318:
319: boolean rv = super.drawImage(buffer2,
320: AffineTransform.getTranslateInstance(bounds.getX(),
321: bounds.getY()),
322: null, null);
323: setComposite(oldcomp);
324: updateColor();
325: return rv;
326: }
327:
328: private void createBuffer()
329: {
330: if (buffer == null)
331: {
332: buffer = new BufferedImage(getBufferCM(),
333: surface.createCompatibleWritableRaster(),
334: getBufferCM().isAlphaPremultiplied(),
335: new Hashtable());
336: }
337: else
338: {
339: Graphics2D g2d = ((Graphics2D)buffer.getGraphics());
340:
341: g2d.setBackground(new Color(0,0,0,0));
342: g2d.clearRect(0, 0, buffer.getWidth(), buffer.getHeight());
343: }
344: }
345:
346: protected ColorModel getNativeCM()
347: {
348: return CairoSurface.cairoCM_pre;
349: }
350:
351: protected ColorModel getBufferCM()
352: {
353: return CairoSurface.cairoColorModel;
354: }
355: }