Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.symbology / org.gvsig.symbology.lib / org.gvsig.symbology.lib.impl / src / main / java / org / gvsig / svgsupport / DefaultSVGRenderer.java @ 43156

History | View | Annotate | Download (5.53 KB)

1
package org.gvsig.svgsupport;
2

    
3
import java.awt.Graphics2D;
4
import java.awt.RenderingHints;
5
import java.awt.geom.AffineTransform;
6
import java.awt.geom.Rectangle2D;
7
import java.io.File;
8
import java.io.IOException;
9
import java.net.URISyntaxException;
10
import java.net.URL;
11
import org.apache.batik.bridge.BridgeContext;
12
import org.apache.batik.bridge.DocumentLoader;
13
import org.apache.batik.bridge.GVTBuilder;
14
import org.apache.batik.bridge.UserAgentAdapter;
15
import org.apache.batik.bridge.ViewBox;
16
import org.apache.batik.dom.svg.SVGOMDocument;
17
import org.apache.batik.gvt.GraphicsNode;
18
import org.apache.batik.gvt.renderer.StaticRenderer;
19
import org.w3c.dom.Document;
20
import org.w3c.dom.Element;
21

    
22
public class DefaultSVGRenderer implements SVGRenderer {
23

    
24
    private final GVTBuilder gvtBuilder = new GVTBuilder();
25
    private final UserAgentAdapter userAgent;
26
    private final DocumentLoader loader;
27
    private final StaticRenderer renderer = new StaticRenderer();
28
    private GraphicsNode gvtRoot;
29
    private final BridgeContext ctx;
30
    private Element elt;
31
    private URL source;
32

    
33
    private static RenderingHints defaultRenderingHints = null;
34

    
35
    public DefaultSVGRenderer() {
36
        userAgent = new UserAgentAdapter();
37
        loader = new DocumentLoader(userAgent);
38
        ctx = new BridgeContext(userAgent, loader);
39
        renderer.setDoubleBuffered(true);
40
    }
41

    
42
    @Override
43
    public Rectangle2D getBounds() {
44
        Rectangle2D bounds = gvtRoot.getBounds();
45
        return bounds;
46
    }
47

    
48
    @Override
49
    public void drawInsideRectangle(Graphics2D g,
50
            Rectangle2D rect,
51
            boolean keepAspectRatio) {
52
        if (keepAspectRatio) {
53
            AffineTransform ataux = null;
54
            if (elt.hasAttribute("viewBox")) {
55

    
56
                try {
57
                    ataux
58
                            = ViewBox.getViewTransform(null,
59
                                    elt,
60
                                    (float) rect.getWidth(),
61
                                    (float) rect.getHeight(),
62
                                    ctx);
63
                } catch (NullPointerException e) {
64
                    
65
                }
66
            }
67
            if( ataux == null ) {
68
                Rectangle2D bounds = gvtRoot.getBounds();
69

    
70
                ataux = getNoRotationTransform(
71
                    bounds,
72
                    new Rectangle2D.Double(
73
                        rect.getX(),
74
                        rect.getY(),
75
                        rect.getWidth(),
76
                        rect.getHeight()),
77
                    true
78
                );
79
            }
80
            RenderingHints renderingHints = new RenderingHints(null);
81
            renderingHints.putAll(getDefaultRenderingHints());
82
            g.setRenderingHints(renderingHints);
83
            gvtRoot.setTransform(ataux);
84
            gvtRoot.paint(g);
85

    
86
        } else {
87

    
88
            Rectangle2D bounds = gvtRoot.getBounds();
89
            AffineTransform ataux = getNoRotationTransform(
90
                bounds,
91
                new Rectangle2D.Double(
92
                    rect.getX(),
93
                    rect.getY(),
94
                    rect.getWidth(),
95
                    rect.getHeight()
96
                ),
97
                false
98
            );
99

    
100
            RenderingHints renderingHints = new RenderingHints(null);
101
            renderingHints.putAll(getDefaultRenderingHints());
102
            g.setRenderingHints(renderingHints);
103
            gvtRoot.setTransform(ataux);
104
            gvtRoot.paint(g);
105
        }
106
    }
107
    
108
    @Override
109
    public void setSource(URL url) throws IOException {
110

    
111
        source = url;
112
        Document svgDoc;
113
        try {
114
            svgDoc = loader.loadDocument(url.toURI().toString());
115
        } catch (URISyntaxException e) {
116
            throw new IOException(e);
117
        }
118
        gvtRoot = gvtBuilder.build(ctx, svgDoc);
119
        renderer.setTree(gvtRoot);
120
        elt = ((SVGOMDocument) svgDoc).getRootElement();
121
    }
122

    
123
    
124
    @Override
125
    public URL getSource() {
126
        return this.source;
127
    }
128

    
129
    private AffineTransform getNoRotationTransform(
130
            Rectangle2D from_rect,
131
            Rectangle2D to_rect,
132
            boolean keep_aspect) {
133

    
134
        double scalex = to_rect.getWidth() / from_rect.getWidth();
135
        double scaley = to_rect.getHeight() / from_rect.getHeight();
136

    
137
        if (keep_aspect) {
138
            // force min value for both
139
            scalex = Math.min(scalex, scaley);
140
            scaley = scalex;
141
        }
142

    
143
        double from_new_center_x = scalex * from_rect.getCenterX();
144
        double from_new_center_y = scaley * from_rect.getCenterY();
145

    
146
        double offx = to_rect.getCenterX() - from_new_center_x;
147
        double offy = to_rect.getCenterY() - from_new_center_y;
148

    
149
        AffineTransform resp
150
                = AffineTransform.getTranslateInstance(offx, offy);
151

    
152
        // this composition is equivalent to:
153
        // first scale, then move
154
        resp.concatenate(
155
                AffineTransform.getScaleInstance(scalex, scaley));
156
        return resp;
157
    }
158

    
159
    private RenderingHints getDefaultRenderingHints() {
160
        if (defaultRenderingHints == null) {
161
            defaultRenderingHints = new RenderingHints(null);
162
            defaultRenderingHints.put(RenderingHints.KEY_ANTIALIASING,
163
                    RenderingHints.VALUE_ANTIALIAS_ON);
164

    
165
            defaultRenderingHints.put(RenderingHints.KEY_INTERPOLATION,
166
                    RenderingHints.VALUE_INTERPOLATION_BILINEAR);
167
        }
168
        return defaultRenderingHints;
169
    }
170

    
171
    @Override
172
    public void setSource(File f) throws IOException {
173
        setSource(f.toURI().toURL());
174
    }
175
}
176