]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/utils/VRamBufferedImage.java
G2DParentNode handles "undefined" child bounds separately
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / utils / VRamBufferedImage.java
1 /*******************************************************************************
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management
3  * in Industry THTH ry.
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
8  *
9  * Contributors:
10  *     VTT Technical Research Centre of Finland - initial API and implementation
11  *******************************************************************************/
12 package org.simantics.scenegraph.utils;
13
14 import java.awt.Color;
15 import java.awt.Graphics2D;
16 import java.awt.Point;
17 import java.awt.RenderingHints;
18 import java.awt.Transparency;
19 import java.awt.geom.AffineTransform;
20 import java.awt.geom.Rectangle2D;
21 import java.awt.image.VolatileImage;
22
23 import com.kitfox.svg.SVGDiagram;
24 import com.kitfox.svg.SVGException;
25
26 /**
27  * @author J-P Laine
28  */
29 public class VRamBufferedImage extends BufferedImage {
30
31     VolatileImage   buffer = null;
32     AffineTransform previousTransform = null;
33
34     /**
35      * @param original
36      * @param imageBounds
37      * @param referenceSize a reference size for the rasterized images or
38      *        <code>null</code> to not specify one in which case a default
39      *        resolution is used
40      */
41     public VRamBufferedImage(SVGDiagram original, Rectangle2D imageBounds, Point referenceSize) {
42         super(original, imageBounds, referenceSize);
43     }
44
45     @Override
46     public synchronized void releaseRaster() {
47         if (buffer != null) {
48             buffer.flush();
49             buffer = null;
50         }
51     }
52
53     @Override
54     public void paint(Graphics2D g) {
55         float margin = 5;
56
57         if(previousTransform == null || previousTransform.getScaleX() != g.getTransform().getScaleX() || previousTransform.getScaleY() != g.getTransform().getScaleY()) {
58             buffer = null;
59             previousTransform = (AffineTransform)g.getTransform().clone();
60             int w = (int)((imageBounds.getWidth()+margin*2) * previousTransform.getScaleX());
61             int h = (int)((imageBounds.getHeight()+margin*2) * previousTransform.getScaleY());
62             if(w < 1) w = 1;
63             if(h < 1) h = 1;
64             buffer = g.getDeviceConfiguration().createCompatibleVolatileImage(w, h, Transparency.TRANSLUCENT);
65
66             // FIXME: render in a "while loop" specified in VolatileImage, this is not guaranteed to work.
67             try {
68                 Graphics2D b2g = (Graphics2D)buffer.getGraphics();
69
70                 b2g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
71                 b2g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
72                 b2g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
73
74                 b2g.setBackground(new Color(255,255,255,0));
75                 b2g.clearRect(0, 0, w, h);
76                 b2g.translate(margin, margin);
77                 b2g.scale(previousTransform.getScaleX(), previousTransform.getScaleY());
78                 b2g.translate(-imageBounds.getMinX(), -imageBounds.getMinY());
79                 source.render(b2g);
80             } catch (SVGException e) {
81                 // TODO Auto-generated catch block
82                 e.printStackTrace();
83             }
84         }
85
86         g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
87         g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
88         g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
89         g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
90
91         AffineTransform at = (AffineTransform)g.getTransform().clone();
92         try {
93             g.translate(imageBounds.getMinX(), imageBounds.getMinY());
94             g.scale(1/previousTransform.getScaleX(), 1/previousTransform.getScaleY());
95             g.translate(-margin, -margin);
96
97             g.drawImage(buffer, 0, 0, null);
98         } finally {
99             g.setTransform(at);
100         }
101     }
102 }