]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.g2d/src/org/simantics/g2d/chassis/Graphics2DRenderer.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / chassis / Graphics2DRenderer.java
diff --git a/bundles/org.simantics.g2d/src/org/simantics/g2d/chassis/Graphics2DRenderer.java b/bundles/org.simantics.g2d/src/org/simantics/g2d/chassis/Graphics2DRenderer.java
new file mode 100644 (file)
index 0000000..4e0beba
--- /dev/null
@@ -0,0 +1,140 @@
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ *     VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+/*\r
+ *\r
+ * @author Toni Kalajainen\r
+ */\r
+package org.simantics.g2d.chassis;\r
+\r
+import java.awt.Graphics2D;\r
+import java.awt.image.BufferedImage;\r
+\r
+import org.eclipse.swt.graphics.GC;\r
+import org.eclipse.swt.graphics.Image;\r
+import org.eclipse.swt.graphics.ImageData;\r
+import org.eclipse.swt.graphics.PaletteData;\r
+import org.eclipse.swt.widgets.Display;\r
+\r
+/**\r
+ * Helper class allowing the use of Java 2D on SWT or Draw2D graphical\r
+ * context.\r
+ * @author Yannick Saillet\r
+ */\r
+public class Graphics2DRenderer {\r
+  private static final PaletteData PALETTE_DATA =\r
+    new PaletteData(0xFF0000, 0xFF00, 0xFF);\r
+\r
+  private BufferedImage awtImage;\r
+  private Image swtImage;\r
+  private ImageData swtImageData;\r
+  private int[] awtPixels;\r
+\r
+  /** RGB value to use as transparent color */\r
+  private static final int TRANSPARENT_COLOR = 0x123456;\r
+\r
+  /**\r
+   * Prepare to render on a SWT graphics context.\r
+   */\r
+  public void prepareRendering(GC gc) {\r
+    org.eclipse.swt.graphics.Rectangle clip = gc.getClipping();\r
+    prepareRendering(clip.x, clip.y, clip.width, clip.height);\r
+  }\r
+\r
+  /**\r
+   * Prepare the AWT offscreen image for the rendering of the rectangular\r
+   * region given as parameter.\r
+   */\r
+  private void prepareRendering(int clipX, int clipY, int clipW, int clipH) {\r
+    // check that the offscreen images are initialized and large enough\r
+    checkOffScreenImages(clipW, clipH);\r
+    // fill the region in the AWT image with the transparent color\r
+    java.awt.Graphics awtGraphics = awtImage.getGraphics();\r
+    awtGraphics.setColor(new java.awt.Color(TRANSPARENT_COLOR));\r
+    awtGraphics.fillRect(clipX, clipY, clipW, clipH);\r
+  }\r
+\r
+  /**\r
+   * Returns the Graphics2D context to use.\r
+   */\r
+  public Graphics2D getGraphics2D() {\r
+    if (awtImage == null) return null;\r
+    return (Graphics2D) awtImage.getGraphics();\r
+  }\r
+\r
+  /**\r
+   * Complete the rendering by flushing the 2D renderer on a SWT graphical\r
+   * context.\r
+   */\r
+  public void render(GC gc) {\r
+    if (awtImage == null) return;\r
+\r
+    org.eclipse.swt.graphics.Rectangle clip = gc.getClipping();\r
+    transferPixels(clip.x, clip.y, clip.width, clip.height);\r
+    gc.drawImage(swtImage, clip.x, clip.y, clip.width, clip.height,\r
+                 clip.x, clip.y, clip.width, clip.height);\r
+  }\r
+\r
+  /**\r
+   * Transfer a rectangular region from the AWT image to the SWT image.\r
+   */\r
+  private void transferPixels(int clipX, int clipY, int clipW, int clipH) {\r
+    int step = swtImageData.depth / 8;\r
+    byte[] data = swtImageData.data;\r
+    awtImage.getRGB(clipX, clipY, clipW, clipH, awtPixels, 0, clipW);\r
+    for (int i = 0; i < clipH; i++) {\r
+      int idx = (clipY + i) * swtImageData.bytesPerLine + clipX * step;\r
+      for (int j = 0; j < clipW; j++) {\r
+        int rgb = awtPixels[j + i * clipW];\r
+        for (int k = swtImageData.depth - 8; k >= 0; k -= 8) {\r
+          data[idx++] = (byte) ((rgb >> k) & 0xFF);\r
+        }\r
+      }\r
+    }\r
+    if (swtImage != null) swtImage.dispose();\r
+    swtImage = new Image(Display.getDefault(), swtImageData);\r
+  }\r
+\r
+  /**\r
+   * Dispose the resources attached to this 2D renderer.\r
+   */\r
+  public void dispose() {\r
+    if (awtImage != null) awtImage.flush();\r
+    if (swtImage != null) swtImage.dispose();\r
+    awtImage = null;\r
+    swtImageData = null;\r
+    awtPixels = null;\r
+  }\r
+\r
+  /**\r
+   * Ensure that the offscreen images are initialized and are at least\r
+   * as large as the size given as parameter.\r
+   */\r
+  private void checkOffScreenImages(int width, int height) {\r
+    int currentImageWidth = 0;\r
+    int currentImageHeight = 0;\r
+    if (swtImage != null) {\r
+      currentImageWidth = swtImage.getImageData().width;\r
+      currentImageHeight = swtImage.getImageData().height;\r
+    }\r
+\r
+    // if the offscreen images are too small, recreate them\r
+    if (width > currentImageWidth || height > currentImageHeight) {\r
+      dispose();\r
+      width = Math.max(width, currentImageWidth);\r
+      height = Math.max(height, currentImageHeight);\r
+      awtImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);\r
+      swtImageData = new ImageData(width, height, 24, PALETTE_DATA);\r
+      swtImageData.transparentPixel = TRANSPARENT_COLOR;\r
+      awtPixels = new int[width * height];\r
+    }\r
+  }\r
+}\r