]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.scenegraph/src/org/simantics/scenegraph/utils/BufferedImage.java
More robustness fixes for editing of texts inside SVG elements.
[simantics/platform.git] / bundles / org.simantics.scenegraph / src / org / simantics / scenegraph / utils / BufferedImage.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.geom.AffineTransform;
19 import java.awt.geom.Rectangle2D;
20
21 import com.kitfox.svg.SVGDiagram;
22 import com.kitfox.svg.SVGException;
23
24 /**
25  * @author J-P Laine
26  */
27 public class BufferedImage  {
28     SVGDiagram                 source;
29     Rectangle2D                imageBounds;
30     Point                      referenceSize;
31
32     java.awt.image.BufferedImage   buffer = null;
33     AffineTransform previousTransform = null;
34
35     /**
36      * @param original
37      * @param imageBounds
38      * @param referenceSize a reference size for the rasterized images or
39      *        <code>null</code> to not specify one in which case a default
40      *        resolution is used
41      */
42     public BufferedImage(SVGDiagram original, Rectangle2D imageBounds, Point referenceSize) {
43         this.source = original;
44         this.imageBounds = imageBounds;
45         this.referenceSize = referenceSize;
46     }
47
48     public BufferedImage(SVGDiagram original) {
49         this.source = original;
50         this.imageBounds = original.getViewRect();
51         this.referenceSize = null;
52     }
53
54     public java.awt.image.BufferedImage getBuffer() {
55         return buffer;
56     }
57     
58     @Override
59     public void finalize() throws Throwable {
60         //System.out.println("BufferedImage.finalize()");
61         releaseRaster();
62         super.finalize();
63     }
64
65     public synchronized void releaseRaster() {
66         source = null;
67         if (buffer != null) {
68             buffer.flush();
69             buffer = null;
70         }
71     }
72
73     public void paintToBuffer(AffineTransform transform, float margin) throws SVGException {
74
75         int w = (int)((imageBounds.getWidth()+margin*2) * transform.getScaleX());
76         int h = (int)((imageBounds.getHeight()+margin*2) * transform.getScaleY());
77         if(w < 1) w = 1;
78         if(h < 1) h = 1; // FIXME
79         
80         buffer = new java.awt.image.BufferedImage(w, h, java.awt.image.BufferedImage.TYPE_INT_ARGB);
81         
82         Graphics2D b2g = (Graphics2D)buffer.getGraphics();
83
84         b2g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
85         b2g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
86         b2g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
87
88         b2g.setBackground(Color.WHITE);
89         b2g.clearRect(0, 0, w, h);
90         b2g.translate(margin, margin);
91         b2g.scale(transform.getScaleX(), transform.getScaleY());
92         b2g.translate(-imageBounds.getMinX(), -imageBounds.getMinY());
93         source.render(b2g);
94
95     }
96     
97     public void paint(Graphics2D g) {
98         float margin = 5;
99
100         if(previousTransform == null || previousTransform.getScaleX() != g.getTransform().getScaleX() || previousTransform.getScaleY() != g.getTransform().getScaleY()) {
101 //              setupSourceRender(g);
102             try {
103                 previousTransform = (AffineTransform)g.getTransform().clone();
104                 paintToBuffer(previousTransform, margin);
105             } catch (SVGException e) {
106                 // TODO Auto-generated catch block
107                 e.printStackTrace();
108             }
109         }
110
111         g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
112         g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
113         g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
114         g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
115
116         AffineTransform at = (AffineTransform)g.getTransform().clone();
117         try {
118             g.translate(imageBounds.getMinX(), imageBounds.getMinY());
119             g.scale(1/previousTransform.getScaleX(), 1/previousTransform.getScaleY());
120             g.translate(-margin, -margin);
121
122             g.drawImage(buffer, 0, 0, null);
123         } finally {
124             g.setTransform(at);
125         }
126     }
127 }