-/*******************************************************************************\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
-package org.simantics.g2d.image.impl;\r
-\r
-import java.awt.AlphaComposite;\r
-import java.awt.Color;\r
-import java.awt.Graphics2D;\r
-import java.awt.geom.Point2D;\r
-import java.awt.geom.Rectangle2D;\r
-import java.awt.image.BufferedImage;\r
-import java.awt.image.ConvolveOp;\r
-import java.awt.image.Kernel;\r
-import java.util.Arrays;\r
-import java.util.EnumSet;\r
-\r
-import org.simantics.g2d.image.Image;\r
-import org.simantics.scenegraph.Node;\r
-import org.simantics.scenegraph.g2d.G2DParentNode;\r
-\r
-/**\r
- * Reflects to a shadow of a symbol.\r
- * \r
- * @author Toni Kalajainen\r
- */\r
-public class Shadow extends ImageProxy implements Image {\r
-\r
- public static final ShadowParameters SHADOW = new ShadowParameters(0.5, Color.BLACK, 2);\r
- public static final class ShadowParameters {\r
- public final double alpha;\r
- public final Color color;\r
- public final int size;\r
- public ShadowParameters(double alpha, Color color, int size) {\r
- this.alpha = alpha;\r
- this.color = color;\r
- this.size = size;\r
- }\r
- }\r
-\r
- public final ShadowParameters shadow;\r
- Point2D size;\r
- ConvolveOp horiz, vert;\r
- int shadowSizeX, shadowSizeY;\r
- EnumSet<Feature> feats;\r
- public ImageListener origListener;\r
-\r
- /**\r
- * \r
- * @param source\r
- * @param shadow\r
- * @param shadowOnly\r
- */\r
- public Shadow(Image source, ShadowParameters shadow)\r
- {\r
- super(source);\r
- this.shadow = shadow;\r
- shadowSizeX = shadow.size;\r
- shadowSizeY = shadow.size;\r
- horiz = createBlurOp(shadow.size, 1);\r
- vert = createBlurOp(1, shadow.size);\r
- if (source.getFeatures().contains(Feature.Volatile)) {\r
- feats = EnumSet.of(Feature.Volatile);\r
- } else\r
- feats = EnumSet.noneOf(Feature.class);\r
- }\r
-\r
- public Shadow(Image source, ShadowParameters shadow, double width, double height)\r
- {\r
- this(source, shadow);\r
- this.size = new Point2D.Double(width, height);\r
- shadowSizeX = (int) Math.round( shadow.size * width / source.getBounds().getWidth() );\r
- shadowSizeY = (int) Math.round( shadow.size * height / source.getBounds().getHeight() );\r
- if (shadowSizeX<1) shadowSizeX = 1;\r
- if (shadowSizeY<1) shadowSizeY = 1;\r
- horiz = createBlurOp(shadowSizeX, 1);\r
- vert = createBlurOp(1, shadowSizeY);\r
- }\r
-\r
- @Override\r
- public Rectangle2D getBounds() {\r
- Rectangle2D rect = source.getBounds();\r
- return new Rectangle2D.Double(rect.getX() - shadowSizeX, rect.getY() - shadowSizeY, rect.getWidth() + shadowSizeX*2, rect.getHeight() + shadowSizeY*2);\r
- }\r
-\r
- private BufferedImage createImage() {\r
- Rectangle2D origBounds = source.getBounds();\r
- double width = size==null?origBounds.getWidth() :size.getX();\r
- double height = size==null?origBounds.getHeight():size.getY();\r
- BufferedImage subject = new BufferedImage(\r
- (int)Math.ceil( width + shadowSizeX * 2 ),\r
- (int)Math.ceil( height + shadowSizeY * 2 ),\r
- BufferedImage.TYPE_INT_ARGB);\r
-\r
- Graphics2D g = subject.createGraphics();\r
- g.translate(shadowSizeX, shadowSizeY);\r
- if (size!=null)\r
- g.scale(size.getX()/origBounds.getWidth(), size.getY()/origBounds.getHeight());\r
- g.translate(-origBounds.getMinX(), -origBounds.getMinY());\r
-\r
- Rectangle2D bounds = new Rectangle2D.Double(0, 0, subject.getWidth(), subject.getHeight());\r
-// GraphicsContextImpl gc = new GraphicsContextImpl(bounds, null);\r
-// try {\r
-// source.paint(gc);\r
-// } finally {\r
-// gc.dispose();\r
-// }\r
-\r
- g.dispose();\r
- return subject;\r
- }\r
-\r
- private BufferedImage createShadowMask(BufferedImage image) {\r
- BufferedImage mask = new BufferedImage(image.getWidth(),\r
- image.getHeight(),\r
- BufferedImage.TYPE_INT_ARGB);\r
-\r
- Graphics2D g2d = mask.createGraphics();\r
- g2d.drawImage(image, 0, 0, null);\r
- g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN,\r
- (float)shadow.alpha));\r
- g2d.setColor(shadow.color);\r
- g2d.fillRect(0, 0, image.getWidth(), image.getHeight());\r
- g2d.dispose();\r
-\r
- return mask;\r
- }\r
-\r
- public BufferedImage createShadow() {\r
- BufferedImage i1 = createImage();\r
- BufferedImage i2 = new BufferedImage(i1.getWidth(), i1.getHeight(), BufferedImage.TYPE_INT_ARGB);\r
- BufferedImage shadowMask = createShadowMask(i1);\r
- horiz.filter(shadowMask, i2);\r
- vert.filter(i2, shadowMask);\r
- return shadowMask;\r
- }\r
-\r
- private ConvolveOp createBlurOp(int width, int height) {\r
- float[] data = new float[width * height];\r
- float value = 1.0f / (width * height);\r
- Arrays.fill(data, value);\r
- return new ConvolveOp(new Kernel(width, height, data));\r
- }\r
-\r
-\r
- @Override\r
- public Node init(G2DParentNode parent) {\r
- return null;\r
-// Graphics2D g = gc.getGraphics2D();\r
-// BufferedImage bi = createShadow();\r
-//\r
-// Rectangle2D origBounds = source.getBounds();\r
-// if (size!=null) {\r
-// g.translate(origBounds.getMinX(), origBounds.getMinY());\r
-// g.scale(origBounds.getWidth()/size.getX(), origBounds.getHeight()/size.getY());\r
-// g.translate(-shadowSizeX, -shadowSizeY);\r
-// g.drawImage(bi, 0, 0, null);\r
-// g.translate(shadowSizeX, shadowSizeY);\r
-// g.scale(size.getX()/origBounds.getWidth(), size.getY()/origBounds.getHeight());\r
-// g.translate(-origBounds.getMinX(), -origBounds.getMinY());\r
-// } else {\r
-// g.translate(-shadowSizeX, -shadowSizeY);\r
-// g.translate(origBounds.getMinX(), origBounds.getMinY());\r
-// g.drawImage(bi, 0, 0, null);\r
-// g.translate(shadowSizeX, shadowSizeY);\r
-// g.translate(-origBounds.getMinX(), -origBounds.getMinY());\r
-// }\r
- }\r
-\r
- @Override\r
- public EnumSet<Feature> getFeatures() {\r
- return feats;\r
- }\r
-\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.g2d.image.impl;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+import java.awt.image.BufferedImage;
+import java.awt.image.ConvolveOp;
+import java.awt.image.Kernel;
+import java.util.Arrays;
+import java.util.EnumSet;
+
+import org.simantics.g2d.image.Image;
+import org.simantics.scenegraph.Node;
+import org.simantics.scenegraph.g2d.G2DParentNode;
+
+/**
+ * Reflects to a shadow of a symbol.
+ *
+ * @author Toni Kalajainen
+ */
+public class Shadow extends ImageProxy implements Image {
+
+ public static final ShadowParameters SHADOW = new ShadowParameters(0.5, Color.BLACK, 2);
+ public static final class ShadowParameters {
+ public final double alpha;
+ public final Color color;
+ public final int size;
+ public ShadowParameters(double alpha, Color color, int size) {
+ this.alpha = alpha;
+ this.color = color;
+ this.size = size;
+ }
+ }
+
+ public final ShadowParameters shadow;
+ Point2D size;
+ ConvolveOp horiz, vert;
+ int shadowSizeX, shadowSizeY;
+ EnumSet<Feature> feats;
+ public ImageListener origListener;
+
+ /**
+ *
+ * @param source
+ * @param shadow
+ * @param shadowOnly
+ */
+ public Shadow(Image source, ShadowParameters shadow)
+ {
+ super(source);
+ this.shadow = shadow;
+ shadowSizeX = shadow.size;
+ shadowSizeY = shadow.size;
+ horiz = createBlurOp(shadow.size, 1);
+ vert = createBlurOp(1, shadow.size);
+ if (source.getFeatures().contains(Feature.Volatile)) {
+ feats = EnumSet.of(Feature.Volatile);
+ } else
+ feats = EnumSet.noneOf(Feature.class);
+ }
+
+ public Shadow(Image source, ShadowParameters shadow, double width, double height)
+ {
+ this(source, shadow);
+ this.size = new Point2D.Double(width, height);
+ shadowSizeX = (int) Math.round( shadow.size * width / source.getBounds().getWidth() );
+ shadowSizeY = (int) Math.round( shadow.size * height / source.getBounds().getHeight() );
+ if (shadowSizeX<1) shadowSizeX = 1;
+ if (shadowSizeY<1) shadowSizeY = 1;
+ horiz = createBlurOp(shadowSizeX, 1);
+ vert = createBlurOp(1, shadowSizeY);
+ }
+
+ @Override
+ public Rectangle2D getBounds() {
+ Rectangle2D rect = source.getBounds();
+ return new Rectangle2D.Double(rect.getX() - shadowSizeX, rect.getY() - shadowSizeY, rect.getWidth() + shadowSizeX*2, rect.getHeight() + shadowSizeY*2);
+ }
+
+ private BufferedImage createImage() {
+ Rectangle2D origBounds = source.getBounds();
+ double width = size==null?origBounds.getWidth() :size.getX();
+ double height = size==null?origBounds.getHeight():size.getY();
+ BufferedImage subject = new BufferedImage(
+ (int)Math.ceil( width + shadowSizeX * 2 ),
+ (int)Math.ceil( height + shadowSizeY * 2 ),
+ BufferedImage.TYPE_INT_ARGB);
+
+ Graphics2D g = subject.createGraphics();
+ g.translate(shadowSizeX, shadowSizeY);
+ if (size!=null)
+ g.scale(size.getX()/origBounds.getWidth(), size.getY()/origBounds.getHeight());
+ g.translate(-origBounds.getMinX(), -origBounds.getMinY());
+
+ Rectangle2D bounds = new Rectangle2D.Double(0, 0, subject.getWidth(), subject.getHeight());
+// GraphicsContextImpl gc = new GraphicsContextImpl(bounds, null);
+// try {
+// source.paint(gc);
+// } finally {
+// gc.dispose();
+// }
+
+ g.dispose();
+ return subject;
+ }
+
+ private BufferedImage createShadowMask(BufferedImage image) {
+ BufferedImage mask = new BufferedImage(image.getWidth(),
+ image.getHeight(),
+ BufferedImage.TYPE_INT_ARGB);
+
+ Graphics2D g2d = mask.createGraphics();
+ g2d.drawImage(image, 0, 0, null);
+ g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN,
+ (float)shadow.alpha));
+ g2d.setColor(shadow.color);
+ g2d.fillRect(0, 0, image.getWidth(), image.getHeight());
+ g2d.dispose();
+
+ return mask;
+ }
+
+ public BufferedImage createShadow() {
+ BufferedImage i1 = createImage();
+ BufferedImage i2 = new BufferedImage(i1.getWidth(), i1.getHeight(), BufferedImage.TYPE_INT_ARGB);
+ BufferedImage shadowMask = createShadowMask(i1);
+ horiz.filter(shadowMask, i2);
+ vert.filter(i2, shadowMask);
+ return shadowMask;
+ }
+
+ private ConvolveOp createBlurOp(int width, int height) {
+ float[] data = new float[width * height];
+ float value = 1.0f / (width * height);
+ Arrays.fill(data, value);
+ return new ConvolveOp(new Kernel(width, height, data));
+ }
+
+
+ @Override
+ public Node init(G2DParentNode parent) {
+ return null;
+// Graphics2D g = gc.getGraphics2D();
+// BufferedImage bi = createShadow();
+//
+// Rectangle2D origBounds = source.getBounds();
+// if (size!=null) {
+// g.translate(origBounds.getMinX(), origBounds.getMinY());
+// g.scale(origBounds.getWidth()/size.getX(), origBounds.getHeight()/size.getY());
+// g.translate(-shadowSizeX, -shadowSizeY);
+// g.drawImage(bi, 0, 0, null);
+// g.translate(shadowSizeX, shadowSizeY);
+// g.scale(size.getX()/origBounds.getWidth(), size.getY()/origBounds.getHeight());
+// g.translate(-origBounds.getMinX(), -origBounds.getMinY());
+// } else {
+// g.translate(-shadowSizeX, -shadowSizeY);
+// g.translate(origBounds.getMinX(), origBounds.getMinY());
+// g.drawImage(bi, 0, 0, null);
+// g.translate(shadowSizeX, shadowSizeY);
+// g.translate(-origBounds.getMinX(), -origBounds.getMinY());
+// }
+ }
+
+ @Override
+ public EnumSet<Feature> getFeatures() {
+ return feats;
+ }
+
+
+}