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