001: /*
002: * uDig - User Friendly Desktop Internet GIS client http://udig.refractions.net (C) 2004,
003: * Refractions Research Inc. This library is free software; you can redistribute it and/or modify it
004: * under the terms of the GNU Lesser General Public License as published by the Free Software
005: * Foundation; version 2.1 of the License. This library is distributed in the hope that it will be
006: * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
007: * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
008: */
009: package net.refractions.udig.ui.graphics;
010:
011: import java.awt.Dimension;
012: import java.awt.Point;
013: import java.awt.Shape;
014: import java.awt.geom.AffineTransform;
015: import java.awt.geom.PathIterator;
016: import java.awt.geom.Rectangle2D;
017: import java.awt.image.BufferedImage;
018: import java.awt.image.Raster;
019: import java.awt.image.RenderedImage;
020: import java.util.ArrayList;
021:
022: import org.eclipse.jface.resource.ImageDescriptor;
023: import org.eclipse.swt.SWT;
024: import org.eclipse.swt.graphics.Color;
025: import org.eclipse.swt.graphics.GC;
026: import org.eclipse.swt.graphics.Image;
027: import org.eclipse.swt.graphics.ImageData;
028: import org.eclipse.swt.graphics.PaletteData;
029: import org.eclipse.swt.graphics.Path;
030: import org.eclipse.swt.graphics.Rectangle;
031: import org.eclipse.swt.widgets.Display;
032:
033: /**
034: * A Graphics object that wraps SWT's GC object
035: *
036: * @author jeichar
037: * @since 0.3
038: */
039: public class NonAdvancedSWTGraphics implements ViewportGraphics {
040: /** The <code>TRANSPARENT</code> color */
041: public final static int TRANSPARENT = 0x220000 | 0x2200 | 0x22;
042:
043: private AffineTransform transform = new AffineTransform();
044:
045: private GC gc = null;
046:
047: private double[] current = new double[6];
048:
049: private double[] last = new double[6];
050:
051: private double[] move_to = new double[6];
052:
053: private Color fore = null;
054:
055: private Color back = null;
056:
057: private Display display;
058:
059: /**
060: * Construct <code>SWTGraphics</code>.
061: *
062: * @param Image
063: * image
064: * @param display
065: * The display object
066: */
067: public NonAdvancedSWTGraphics(Image image, Display display) {
068: this (new GC(image), display,
069: new Dimension(image.getImageData().width, image
070: .getImageData().height));
071: }
072:
073: /**
074: * Construct <code>SWTGraphics</code>.
075: *
076: * @param gc
077: * The GC object
078: * @param display
079: * The display object
080: */
081: public NonAdvancedSWTGraphics(GC gc, Display display,
082: Dimension displaySize) {
083: setGraphics(gc, display);
084: }
085:
086: void setGraphics(GC gc, Display display) {
087: this .gc = gc;
088: this .display = display;
089: if (back != null)
090: back.dispose();
091: back = new Color(display, 255, 255, 255);
092: gc.setBackground(back);
093: gc.setAdvanced(false);
094: }
095:
096: public void dispose() {
097: if (fore != null)
098: fore.dispose();
099: if (back != null)
100: back.dispose();
101: gc.dispose();
102: }
103:
104: /**
105: * @see net.refractions.udig.project.render.ViewportGraphics#draw(java.awt.Shape)
106: */
107: public void draw(Shape s) {
108: PathIterator p = s.getPathIterator(transform, 1);
109: boolean singlePoint = true;
110: if (p.isDone())
111: return;
112:
113: p.currentSegment(current);
114: move_to = current.clone();
115: p.next();
116: while (!p.isDone()) {
117: singlePoint = false;
118: last = current.clone();
119: switch (p.currentSegment(current)) {
120: case PathIterator.SEG_CLOSE:
121: gc.drawLine((int) current[0], (int) current[1],
122: (int) move_to[0], (int) move_to[1]);
123: break;
124: case PathIterator.SEG_LINETO:
125: gc.drawLine((int) last[0], (int) last[1],
126: (int) current[0], (int) current[1]);
127: break;
128: case PathIterator.SEG_MOVETO:
129: move_to = current;
130: break;
131: case PathIterator.SEG_QUADTO:
132: case PathIterator.SEG_CUBICTO:
133: default:
134: }
135: p.next();
136: }
137: if (singlePoint == true) {
138: gc.drawPoint((int) current[0], (int) current[1]);
139: }
140: }
141:
142: /**
143: * @see net.refractions.udig.project.render.ViewportGraphics#draw(java.awt.Shape)
144: */
145: public void fill(Shape s) {
146: gc.setBackground(fore);
147: PathIterator p = s.getPathIterator(transform);
148: ArrayList<Integer> pts = new ArrayList<Integer>();
149:
150: p.currentSegment(current);
151: pts.add((int) current[0]);
152: pts.add((int) current[1]);
153:
154: p.next();
155: while (!p.isDone()) {
156: switch (p.currentSegment(current)) {
157:
158: case PathIterator.SEG_LINETO:
159: p.currentSegment(current);
160:
161: pts.add((int) current[0]); // "line_to"
162: pts.add((int) current[1]); // "line_to"
163: break;
164:
165: case PathIterator.SEG_MOVETO:
166: case PathIterator.SEG_CLOSE: {
167: pts.add((int) current[0]);
168: pts.add((int) current[1]);
169: final int SIZE = pts.size();
170: int polygon[] = new int[SIZE];
171: for (int i = 0; i < SIZE; i++)
172: polygon[i] = pts.get(i);
173: gc.fillPolygon(polygon);
174:
175: pts.clear(); // closed we can start again now
176: }
177: break;
178:
179: case PathIterator.SEG_QUADTO:
180: case PathIterator.SEG_CUBICTO:
181: default:
182:
183: }
184: p.next();
185: }
186: gc.setBackground(fore);
187: }
188:
189: /**
190: * Sets an affine transformation for drawing shapes.
191: *
192: * @param t
193: * The transform.
194: */
195: public void setAffineTransform(AffineTransform t) {
196: this .transform = t;
197: }
198:
199: /**
200: * @see net.refractions.udig.project.render.ViewportGraphics#fillRect(int,
201: * int, int, int)
202: */
203: public void fillRect(int x, int y, int width, int height) {
204: int x2 = x + (int) transform.getTranslateX();
205: int y2 = y + (int) transform.getTranslateY();
206: gc.setBackground(fore);
207: gc.fillRectangle(new Rectangle(x2, y2, width, height));
208: gc.setBackground(back);
209: }
210:
211: /**
212: * @see net.refractions.udig.project.render.ViewportGraphics#setColor(java.awt.Color)
213: */
214: public void setColor(java.awt.Color c) {
215: Color color = new Color(display, c.getRed(), c.getGreen(), c
216: .getBlue());
217: gc.setForeground(color);
218: if (fore != null)
219: fore.dispose();
220: fore = color;
221: }
222:
223: /**
224: * This is hard because - background doesn't mean what we think it means.
225: *
226: * @see net.refractions.udig.project.render.ViewportGraphics#setBackground(java.awt.Color)
227: */
228: public void setBackground(java.awt.Color c) {
229: Color color = new Color(display, c.getRed(), c.getGreen(), c
230: .getBlue());
231: gc.setBackground(color);
232: if (back != null)
233: back.dispose();
234: back = color;
235: }
236:
237: /**
238: * @see net.refractions.udig.project.render.ViewportGraphics#setStroke(int,
239: * int)
240: */
241: public void setStroke(int style, int width) {
242: switch (style) {
243: case LINE_DASH: {
244: gc.setLineStyle(SWT.LINE_DASH);
245: break;
246: }
247: case LINE_DASHDOT: {
248: gc.setLineStyle(SWT.LINE_DASHDOT);
249: break;
250: }
251: case LINE_DASHDOTDOT: {
252: gc.setLineStyle(SWT.LINE_DASHDOTDOT);
253: break;
254: }
255: case LINE_DOT: {
256: gc.setLineStyle(SWT.LINE_DOT);
257: break;
258: }
259: case LINE_SOLID: {
260: gc.setLineStyle(SWT.LINE_SOLID);
261: break;
262: }
263: }
264: gc.setLineWidth(width);
265: }
266:
267: /**
268: * @see net.refractions.udig.project.render.ViewportGraphics#setClip(java.awt.Rectangle)
269: */
270: public void setClip(java.awt.Rectangle r) {
271: gc.setClipping(r.x, r.y, r.width, r.height);
272: }
273:
274: /**
275: * @see net.refractions.udig.project.render.ViewportGraphics#translate(java.awt.Point)
276: */
277: public void translate(Point offset) {
278: transform.translate(offset.x, offset.y);
279: }
280:
281: /**
282: * @see net.refractions.udig.project.render.ViewportGraphics#clearRect(int,
283: * int, int, int)
284: */
285: public void clearRect(int x, int y, int width, int height) {
286: Color c = gc.getForeground();
287: gc.setForeground(gc.getBackground());
288: gc.fillRectangle(x, y, width, height);
289: gc.setForeground(c);
290: }
291:
292: /**
293: * @see net.refractions.udig.project.render.ViewportGraphics#drawImage(javax.media.jai.PlanarImage,
294: * int, int)
295: */
296: public void drawImage(RenderedImage rimage, int x, int y) {
297: drawImage(rimage, 0, 0, rimage.getWidth(), rimage.getHeight(),
298: x, y, x + rimage.getWidth(), y + rimage.getHeight());
299: }
300:
301: public static Image createDefaultImage(Display display, int width,
302: int height) {
303: ImageData swtdata = null;
304: PaletteData palette;
305: int depth;
306:
307: depth = 24;
308: palette = new PaletteData(0xFF0000, 0xFF00, 0xFF);
309: swtdata = new ImageData(width, height, depth, palette);
310: swtdata.transparentPixel = -1;
311: swtdata.alpha = -1;
312: swtdata.alphaData = new byte[swtdata.data.length];
313: for (int i = 0; i < swtdata.alphaData.length; i++) {
314: swtdata.alphaData[i] = (byte) i;
315: }
316: return new Image(display, swtdata);
317:
318: }
319:
320: public static ImageDescriptor createImageDescriptor(
321: final RenderedImage image, final boolean transparent) {
322: return new ImageDescriptor() {
323: public ImageData getImageData() {
324: return createImageData(image, transparent);
325: }
326: };
327: }
328:
329: /** Create a buffered image that can be be coverted to SWTland later */
330: public static BufferedImage createBufferedImage(int w, int h) {
331: return new BufferedImage(w, h,
332: BufferedImage.TYPE_4BYTE_ABGR_PRE);
333: }
334:
335: public static Image createSWTImage(RenderedImage image,
336: boolean transparent) {
337: ImageData data = createImageData(image, transparent);
338:
339: return new org.eclipse.swt.graphics.Image(Display.getDefault(),
340: data);
341: }
342:
343: // optimized version that works if the image is rgb with a byte data buffer
344: public static ImageData createImageDataFromBytes(RenderedImage image) {
345: ImageData swtdata = null;
346: int width = image.getWidth();
347: int height = image.getHeight();
348: PaletteData palette;
349: int depth;
350: depth = 24;
351: palette = new PaletteData(0xFF0000, 0xFF00, 0xFF);
352: swtdata = new ImageData(width, height, depth, palette);
353:
354: Raster raster = image.getData();
355: raster.getDataElements(0, 0, width, height, swtdata.data);
356:
357: return swtdata;
358: }
359:
360: public static ImageData createImageData(RenderedImage image,
361: boolean transparent) {
362:
363: // if(
364: // image.getData().getDataBuffer().getDataType()==DataBuffer.TYPE_BYTE
365: // && !image.getColorModel().hasAlpha() )
366: // return createImageDataFromBytes(image);
367: ImageData swtdata = null;
368: int width = image.getWidth();
369: int height = image.getHeight();
370: PaletteData palette;
371: int depth;
372:
373: depth = 24;
374: palette = new PaletteData(0xFF0000, 0xFF00, 0xFF);
375: swtdata = new ImageData(width, height, depth, palette);
376: byte blueT = (byte) 255;
377: byte greenT = (byte) 255;
378: byte redT = (byte) 255;
379: if (transparent) {
380: swtdata.transparentPixel = TRANSPARENT;
381:
382: blueT = (byte) ((TRANSPARENT) & 0xFF);
383: greenT = (byte) ((TRANSPARENT >> 8) & 0xFF);
384: redT = (byte) ((TRANSPARENT >> 16) & 0xFF);
385: }
386: Raster raster = image.getData();
387: int numbands = raster.getNumBands();
388: int[] awtdata = raster.getPixels(0, 0, width, height,
389: new int[width * height * numbands]);
390: int step = swtdata.depth / 8;
391:
392: byte[] data = swtdata.data;
393: int baseindex = 0;
394: for (int y = 0; y < height; y++) {
395: int idx = ((0 + y) * swtdata.bytesPerLine) + (0 * step);
396:
397: for (int x = 0; x < width; x++) {
398: baseindex = (x + (y * width)) * numbands;
399:
400: if (numbands == 4 && awtdata[baseindex + 3] == 0) {
401: data[idx++] = blueT;
402: data[idx++] = greenT;
403: data[idx++] = redT;
404: } else {
405: data[idx++] = (byte) awtdata[baseindex];
406: data[idx++] = (byte) awtdata[baseindex + 1];
407: data[idx++] = (byte) awtdata[baseindex + 2];
408: }
409: }
410: }
411: return swtdata;
412: }
413:
414: public void drawString(String string, int x, int y, int alignx,
415: int aligny) {
416: org.eclipse.swt.graphics.Point text = gc.stringExtent(string);
417: int w = (int) text.x;
418: int h = (int) text.y;
419:
420: int x2 = (alignx == 0) ? x - w / 2 : (alignx > 0) ? x - w : x;
421: int y2 = (aligny == 0) ? y + h / 2 : (aligny > 0) ? y + h : y;
422:
423: gc.drawString(string, x2, y2, true);
424: }
425:
426: public void setTransform(AffineTransform transform) {
427: this .transform = transform;
428: }
429:
430: /**
431: * @see net.refractions.udig.ui.graphics.ViewportGraphics#drawImage(java.awt.Image,
432: * int, int)
433: *
434: * Current version can only draw Image if the image is an RenderedImage
435: */
436: public void drawImage(java.awt.Image image, int x, int y) {
437: RenderedImage rimage = (RenderedImage) image;
438: drawImage(rimage, x, y);
439: }
440:
441: /**
442: * @see net.refractions.udig.ui.graphics.ViewportGraphics#drawImage(java.awt.Image,
443: * int, int, int, int, int, int, int, int)
444: */
445: public void drawImage(java.awt.Image image, int dx1, int dy1,
446: int dx2, int dy2, int sx1, int sy1, int sx2, int sy2) {
447: RenderedImage rimage = (RenderedImage) image;
448: drawImage(rimage, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2);
449: }
450:
451: public void drawImage(RenderedImage rimage, int dx1, int dy1,
452: int dx2, int dy2, int sx1, int sy1, int sx2, int sy2) {
453: assert rimage != null;
454: Image swtImage = null;
455: try {
456: swtImage = createSWTImage(rimage, true);
457: int translatedX = (int) (dx1 + transform.getTranslateX());
458: int translatedY = (int) (dy1 + transform.getTranslateY());
459: int translatedWidth = (int) (transform.getScaleX() * (dx2 - dx1));
460: int translatedHeight = (int) (transform.getScaleY() * (dy2 - dy1));
461: if (swtImage != null) {
462: gc.drawImage(swtImage, sx1, sy1, sx2 - sx1, sy2 - sy1,
463: translatedX, translatedY, translatedWidth,
464: translatedHeight);
465: swtImage.dispose();
466: }
467: } finally {
468: if (swtImage != null)
469: swtImage.dispose();
470: }
471:
472: }
473:
474: public int getFontHeight() {
475: return gc.getFontMetrics().getHeight();
476: }
477:
478: public int stringWidth(String str) {
479: return -1;
480: }
481:
482: public int getFontAscent() {
483: return gc.getFontMetrics().getAscent();
484: }
485:
486: public Rectangle2D getStringBounds(String str) {
487: org.eclipse.swt.graphics.Point extent = gc.textExtent(str);
488:
489: return new java.awt.Rectangle(0, 0, extent.x, extent.y);
490: }
491:
492: public void drawLine(int x1, int y1, int x2, int y2) {
493: gc.drawLine(x1, y1, x2, y2);
494: }
495:
496: public void drawImage(Image image, int dx1, int dy1, int dx2,
497: int dy2, int sx1, int sy1, int sx2, int sy2) {
498: int translatedX = (int) (dx1 + transform.getTranslateX());
499: int translatedY = (int) (dy1 + transform.getTranslateY());
500: int translatedWidth = (int) (transform.getScaleX() * (dx2 - dx1));
501: int translatedHeight = (int) (transform.getScaleY() * (dy2 - dy1));
502: gc.drawImage(image, sx1, sy1, sx2 - sx1, sy2 - sy1,
503: translatedX, translatedY, translatedWidth,
504: translatedHeight);
505:
506: }
507:
508: public AffineTransform getTransform() {
509: return transform;
510: }
511:
512: public void drawPath(Path path) {
513: }
514:
515: public void fillPath(Path path) {
516: }
517:
518: public void drawRect(int x, int y, int width, int height) {
519: gc.drawRectangle(new Rectangle(x, y, width, height));
520: }
521:
522: public void drawOval(int x, int y, int width, int height) {
523: gc.drawOval(x, y, width, height);
524: }
525:
526: public void fillOval(int x, int y, int width, int height) {
527: gc.fillOval(x, y, width, height);
528: }
529:
530: public void drawImage(Image swtImage, int x, int y) {
531: gc.drawImage(swtImage, x, y);
532: }
533:
534: public Shape getClip() {
535: Rectangle clipping = gc.getClipping();
536: return new java.awt.Rectangle(clipping.x, clipping.y,
537: clipping.width, clipping.height);
538: }
539:
540: public void setClipBounds(java.awt.Rectangle newBounds) {
541: gc.setClipping(new Rectangle(newBounds.x, newBounds.y,
542: newBounds.width, newBounds.height));
543: }
544:
545: public java.awt.Color getBackgroundColor() {
546: return SWTGraphics.swt2awt(gc, gc.getBackground());
547: }
548:
549: public java.awt.Color getColor() {
550: return SWTGraphics.swt2awt(gc, gc.getForeground());
551: }
552:
553: public void drawRoundRect(int x, int y, int width, int height,
554: int arcWidth, int arcHeight) {
555: gc.drawRoundRectangle(x, y, width, height, arcWidth, arcHeight);
556: }
557:
558: public void fillRoundRect(int x, int y, int width, int height,
559: int arcWidth, int arcHeight) {
560: gc.setBackground(fore);
561: gc.fillRoundRectangle(x, y, width, height, arcWidth, arcHeight);
562: gc.setBackground(back);
563: }
564: }
|