1:
37:
38: package ;
39:
40: import ;
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:
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67:
68: public class XGraphics2D
69: extends AbstractGraphics2D
70: {
71:
72:
77: private static final boolean RENDER_OPAQUE =
78: Boolean.getBoolean("escherpeer.renderopaque");
79:
80:
83: private Drawable xdrawable;
84:
85:
88: private GC xgc;
89:
90:
93: private boolean disposed;
94:
95:
98: private Color foreground;
99:
100: XGraphics2D(Drawable d)
101: {
102: super();
103: xdrawable = d;
104: xgc = new GC(d);
105: init();
106: disposed = false;
107:
108: }
109:
110: @Override
111: protected void rawDrawLine(int x0, int y0, int x1, int y1)
112: {
113: xdrawable.segment(xgc, x0, y0, x1, y1);
114: }
115:
116: @Override
117: protected void rawDrawRect(int x, int y, int w, int h)
118: {
119: xdrawable.rectangle(xgc, x, y, w, h, false);
120: }
121:
122: @Override
123: protected void rawFillRect(int x, int y, int w, int h)
124: {
125: xdrawable.rectangle(xgc, x, y, w, h, true);
126: }
127:
128:
133: protected ColorModel getColorModel()
134: {
135: return Toolkit.getDefaultToolkit().getColorModel();
136: }
137:
138:
143: protected ColorModel getDestinationColorModel()
144: {
145: return Toolkit.getDefaultToolkit().getColorModel();
146: }
147:
148:
153: protected Rectangle getDeviceBounds()
154: {
155: return new Rectangle(0, 0, xdrawable.width, xdrawable.height);
156: }
157:
158: public GraphicsConfiguration getDeviceConfiguration()
159: {
160:
161: throw new UnsupportedOperationException("Not yet implemented");
162: }
163:
164: public void dispose()
165: {
166: if (!disposed)
167: {
168: xgc.free();
169: xdrawable.display.flush();
170: disposed = true;
171: }
172: }
173:
174: public Graphics create()
175: {
176:
177:
178: XGraphics2D copy = (XGraphics2D) super.create();
179: copy.xgc = xgc.copy();
180: return copy;
181: }
182:
183: public void setClip(Shape c)
184: {
185: super.setClip(c);
186: if (c instanceof Rectangle)
187: {
188: Rectangle r = (Rectangle) c;
189: AffineTransform t = getTransform();
190: int translateX = (int) t.getTranslateX();
191:
192: int translateY = (int) t.getTranslateY();
193:
194:
195: gnu.x11.Rectangle clip = new gnu.x11.Rectangle(r.x, r.y, r.width,
196: r.height);
197: xgc.set_clip_rectangles(translateX, translateY,
198: new gnu.x11.Rectangle[]{clip}, GC.UN_SORTED);
199: }
200: }
201:
202:
216: protected void updateRaster(Raster raster, int x, int y, int w, int h)
217: {
218: if (w > 0 && h > 0)
219: {
220: ZPixmap zPixmap = new ZPixmap(xdrawable.display, w, h,
221: xdrawable.display.default_pixmap_format);
222: int[] pixel = null;
223: int x1 = x + w;
224: int y1 = y + h;
225: for (int tx = x; tx < x1; tx++)
226: {
227: for (int ty = y; ty < y1; ty++)
228: {
229: pixel = raster.getPixel(tx, ty, pixel);
230:
231:
232:
233:
234: zPixmap.set_red(tx - x, ty - y, pixel[0]);
235: zPixmap.set_green(tx - x, ty - y, pixel[1]);
236: zPixmap.set_blue(tx - x, ty - y, pixel[2]);
237: }
238: }
239: xdrawable.put_image(xgc, zPixmap, x, y);
240: }
241: }
242:
243: @Override
244: public void renderScanline(int y, ScanlineCoverage c)
245: {
246: if (y >= xdrawable.height)
247: return;
248:
249:
250: ScanlineCoverage.Iterator iter = c.iterate();
251: int coverageAlpha = 0;
252: int maxCoverage = c.getMaxCoverage();
253: while (iter.hasNext())
254: {
255: ScanlineCoverage.Range range = iter.next();
256:
257: coverageAlpha = range.getCoverage();
258: int x0 = range.getXPos();
259: int l = range.getLength();
260: if (coverageAlpha == c.getMaxCoverage())
261: {
262:
263: xdrawable.fill_rectangle(xgc, x0, y, l, 1);
264: }
265: else if (coverageAlpha > 0)
266: {
267:
268: int x1 = x0 + l;
269: x0 = Math.min(Math.max(0, x0), xdrawable.width - 1);
270: x1 = Math.min(Math.max(0, x1), xdrawable.width - 1);
271: if ((x1 - x0) < 1)
272: continue;
273: l = x1 - x0;
274: gnu.x11.image.ZPixmap existing = (ZPixmap)
275: xdrawable.image(x0, y, l, 1, 0xFFFFFFFF,
276: gnu.x11.image.Image.Format.ZPIXMAP);
277: for (int x = 0; x < l; x++)
278: {
279: Color col = getColor();
280: if (col == null)
281: {
282: col = Color.BLACK;
283: }
284: int red = col.getRed();
285: int green = col.getGreen();
286: int blue = col.getBlue();
287: int redOut = existing.get_red(x, 0);
288: int greenOut = existing.get_green(x, 0);
289: int blueOut = existing.get_blue(x, 0);
290: int outAlpha = maxCoverage - coverageAlpha;
291: redOut = redOut * outAlpha + red * coverageAlpha;
292: redOut = redOut / maxCoverage;
293: greenOut = greenOut * outAlpha + green * coverageAlpha;
294: greenOut = greenOut / maxCoverage;
295: blueOut = blueOut * outAlpha + blue * coverageAlpha;
296: blueOut = blueOut / maxCoverage;
297: existing.set(x, 0, redOut, greenOut, blueOut);
298: }
299: xdrawable.put_image(xgc, existing, x0, y);
300: }
301: }
302: }
303:
304: protected void init()
305: {
306: super.init();
307: }
308:
309: public void setPaint(Paint p)
310: {
311: super.setPaint(p);
312: if (p instanceof Color)
313: {
314:
315: Color c = (Color) p;
316:
327:
328:
329: xgc.set_foreground(c.getRGB());
330: foreground = c;
331: }
332: }
333:
334: protected void fillShape(Shape s, boolean isFont)
335: {
336: synchronized (xdrawable.display) {
337: super.fillShape(s, isFont);
338: }
339: }
340:
341: private static WeakHashMap<Image,ZPixmap> imageCache = new WeakHashMap<Image,ZPixmap>();
342:
343: protected boolean rawDrawImage(Image image, int x, int y, ImageObserver obs)
344: {
345: image = unwrap(image);
346: boolean ret;
347: if (image instanceof XImage)
348: {
349: XImage xImage = (XImage) image;
350: xdrawable.copy_area(xImage.pixmap, xgc, 0, 0, xImage.getWidth(obs),
351: xImage.getHeight(obs), x, y);
352: ret = true;
353: }
354: else if (image instanceof PixmapVolatileImage)
355: {
356: PixmapVolatileImage pvi = (PixmapVolatileImage) image;
357: xdrawable.copy_area(pvi.getPixmap(), xgc, 0, 0, pvi.getWidth(obs),
358: pvi.getHeight(obs), x, y);
359: ret = true;
360: }
361: else if (image instanceof BufferedImage)
362: {
363: BufferedImage bi = (BufferedImage) image;
364: DataBuffer db = bi.getRaster().getDataBuffer();
365: if (db instanceof ZPixmapDataBuffer)
366: {
367: ZPixmapDataBuffer zpmdb = (ZPixmapDataBuffer) db;
368: ZPixmap zpixmap = zpmdb.getZPixmap();
369: xdrawable.put_image(xgc, zpixmap, x, y);
370: ret = true;
371: }
372: else
373: {
374: int transparency = bi.getTransparency();
375: int w = bi.getWidth();
376: int h = bi.getHeight();
377: if (imageCache.containsKey(image))
378: {
379: ZPixmap zpixmap = imageCache.get(image);
380: xdrawable.put_image(xgc, zpixmap, x, y);
381: }
382: else if (transparency == Transparency.OPAQUE || RENDER_OPAQUE)
383: {
384: XGraphicsDevice gd = XToolkit.getDefaultDevice();
385: ZPixmap zpixmap = new ZPixmap(gd.getDisplay(), w, h);
386: for (int yy = 0; yy < h; yy++)
387: {
388: for (int xx = 0; xx < w; xx++)
389: {
390: int rgb = bi.getRGB(xx, yy);
391: zpixmap.set(xx, yy, rgb);
392: }
393: }
394: xdrawable.put_image(xgc, zpixmap, x, y);
395: imageCache.put(image, zpixmap);
396: } else {
397:
398:
399: Rectangle source =
400: new Rectangle(0, 0, xdrawable.width, xdrawable.height);
401: Rectangle target = new Rectangle(x, y, w, h);
402:
403: Rectangle destination = source.intersection(target);
404:
405: x = destination.x;
406: y = destination.y;
407: w = destination.width;
408: h = destination.height;
409:
410: ZPixmap zpixmap =
411: (ZPixmap) xdrawable.image(x, y, w, h,
412: 0xffffffff,
413: gnu.x11.image.Image.Format.ZPIXMAP);
414: for (int yy = 0; yy < h; yy++)
415: {
416: for (int xx = 0; xx < w; xx++)
417: {
418: int rgb = bi.getRGB(xx, yy);
419: int alpha = 0xff & (rgb >> 24);
420: if (alpha == 0)
421: {
422:
423: rgb = zpixmap.get_red(xx, yy) << 16
424: | zpixmap.get_green(xx, yy) << 8
425: | zpixmap.get_blue(xx, yy);
426: }
427: else if (alpha < 255)
428: {
429:
430: int red = 0xff & (rgb >> 16);
431: red = red * alpha
432: + (255 - alpha) * zpixmap.get_red(xx, yy);
433: red = red / 255;
434: int green = 0xff & (rgb >> 8);
435: green = green * alpha
436: + (255 - alpha) * zpixmap.get_green(xx, yy);
437: green = green / 255;
438: int blue = 0xff & rgb;
439: blue = blue * alpha
440: + (255 - alpha) * zpixmap.get_blue(xx, yy);
441: blue = blue / 255;
442: rgb = red << 16 | green << 8 | blue;
443: }
444:
445:
446: zpixmap.set(xx, yy, rgb);
447: }
448: }
449: xdrawable.put_image(xgc, zpixmap, x, y);
450:
451:
452: }
453: ret = true;
454: }
455: }
456: else
457: {
458: ret = super.rawDrawImage(image, x, y, obs);
459: }
460: return ret;
461: }
462:
463: public void setFont(Font f)
464: {
465: super.setFont(f);
466: FontPeer p = getFont().getPeer();
467: if (p instanceof XFontPeer)
468: {
469: XFontPeer xFontPeer = (XFontPeer) p;
470: xgc.set_font(xFontPeer.getXFont());
471: }
472: }
473:
474: public void drawString(String s, int x, int y)
475: {
476: FontPeer p = getFont().getPeer();
477: if (p instanceof XFontPeer)
478: {
479: int tx = (int) transform.getTranslateX();
480: int ty = (int) transform.getTranslateY();
481: xdrawable.text(xgc, x + tx, y + ty, s);
482: }
483: else
484: {
485: super.drawString(s, x, y);
486: }
487: }
488:
489:
497: private Image unwrap(Image im)
498: {
499: Image image = im;
500: if (image instanceof AsyncImage)
501: {
502: AsyncImage aIm = (AsyncImage) image;
503: image = aIm.getRealImage();
504: }
505: return image;
506: }
507:
508: }