1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
14 * @author Toni Kalajainen
\r
16 package org.simantics.g2d.chassis;
\r
18 import java.awt.Graphics2D;
\r
19 import java.awt.image.BufferedImage;
\r
21 import org.eclipse.swt.graphics.GC;
\r
22 import org.eclipse.swt.graphics.Image;
\r
23 import org.eclipse.swt.graphics.ImageData;
\r
24 import org.eclipse.swt.graphics.PaletteData;
\r
25 import org.eclipse.swt.widgets.Display;
\r
28 * Helper class allowing the use of Java 2D on SWT or Draw2D graphical
\r
30 * @author Yannick Saillet
\r
32 public class Graphics2DRenderer {
\r
33 private static final PaletteData PALETTE_DATA =
\r
34 new PaletteData(0xFF0000, 0xFF00, 0xFF);
\r
36 private BufferedImage awtImage;
\r
37 private Image swtImage;
\r
38 private ImageData swtImageData;
\r
39 private int[] awtPixels;
\r
41 /** RGB value to use as transparent color */
\r
42 private static final int TRANSPARENT_COLOR = 0x123456;
\r
45 * Prepare to render on a SWT graphics context.
\r
47 public void prepareRendering(GC gc) {
\r
48 org.eclipse.swt.graphics.Rectangle clip = gc.getClipping();
\r
49 prepareRendering(clip.x, clip.y, clip.width, clip.height);
\r
53 * Prepare the AWT offscreen image for the rendering of the rectangular
\r
54 * region given as parameter.
\r
56 private void prepareRendering(int clipX, int clipY, int clipW, int clipH) {
\r
57 // check that the offscreen images are initialized and large enough
\r
58 checkOffScreenImages(clipW, clipH);
\r
59 // fill the region in the AWT image with the transparent color
\r
60 java.awt.Graphics awtGraphics = awtImage.getGraphics();
\r
61 awtGraphics.setColor(new java.awt.Color(TRANSPARENT_COLOR));
\r
62 awtGraphics.fillRect(clipX, clipY, clipW, clipH);
\r
66 * Returns the Graphics2D context to use.
\r
68 public Graphics2D getGraphics2D() {
\r
69 if (awtImage == null) return null;
\r
70 return (Graphics2D) awtImage.getGraphics();
\r
74 * Complete the rendering by flushing the 2D renderer on a SWT graphical
\r
77 public void render(GC gc) {
\r
78 if (awtImage == null) return;
\r
80 org.eclipse.swt.graphics.Rectangle clip = gc.getClipping();
\r
81 transferPixels(clip.x, clip.y, clip.width, clip.height);
\r
82 gc.drawImage(swtImage, clip.x, clip.y, clip.width, clip.height,
\r
83 clip.x, clip.y, clip.width, clip.height);
\r
87 * Transfer a rectangular region from the AWT image to the SWT image.
\r
89 private void transferPixels(int clipX, int clipY, int clipW, int clipH) {
\r
90 int step = swtImageData.depth / 8;
\r
91 byte[] data = swtImageData.data;
\r
92 awtImage.getRGB(clipX, clipY, clipW, clipH, awtPixels, 0, clipW);
\r
93 for (int i = 0; i < clipH; i++) {
\r
94 int idx = (clipY + i) * swtImageData.bytesPerLine + clipX * step;
\r
95 for (int j = 0; j < clipW; j++) {
\r
96 int rgb = awtPixels[j + i * clipW];
\r
97 for (int k = swtImageData.depth - 8; k >= 0; k -= 8) {
\r
98 data[idx++] = (byte) ((rgb >> k) & 0xFF);
\r
102 if (swtImage != null) swtImage.dispose();
\r
103 swtImage = new Image(Display.getDefault(), swtImageData);
\r
107 * Dispose the resources attached to this 2D renderer.
\r
109 public void dispose() {
\r
110 if (awtImage != null) awtImage.flush();
\r
111 if (swtImage != null) swtImage.dispose();
\r
113 swtImageData = null;
\r
118 * Ensure that the offscreen images are initialized and are at least
\r
119 * as large as the size given as parameter.
\r
121 private void checkOffScreenImages(int width, int height) {
\r
122 int currentImageWidth = 0;
\r
123 int currentImageHeight = 0;
\r
124 if (swtImage != null) {
\r
125 currentImageWidth = swtImage.getImageData().width;
\r
126 currentImageHeight = swtImage.getImageData().height;
\r
129 // if the offscreen images are too small, recreate them
\r
130 if (width > currentImageWidth || height > currentImageHeight) {
\r
132 width = Math.max(width, currentImageWidth);
\r
133 height = Math.max(height, currentImageHeight);
\r
134 awtImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
\r
135 swtImageData = new ImageData(width, height, 24, PALETTE_DATA);
\r
136 swtImageData.transparentPixel = TRANSPARENT_COLOR;
\r
137 awtPixels = new int[width * height];
\r