summaryrefslogtreecommitdiffstats
path: root/src/main/java/com/kitfox/svg/SVGDiagram.java
blob: c28e6e6d0595cbf1849088bc23056cd7e083cf92 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
/*
 * SVGDiagram.java
 *
 *
 *  The Salamander Project - 2D and 3D graphics libraries in Java
 *  Copyright (C) 2004 Mark McKay
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 *  Mark McKay can be contacted at mark@kitfox.com.  Salamander and other
 *  projects can be found at http://www.kitfox.com
 *
 * Created on February 18, 2004, 5:04 PM
 */

package com.kitfox.svg;

import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.io.Serializable;
import java.net.URI;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


/**
 * Top level structure in an SVG tree.
 *
 * @author Mark McKay
 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a>
 */
public class SVGDiagram implements Serializable
{
    public static final long serialVersionUID = 0;
    
    //Indexes elements within this SVG diagram
    final HashMap idMap = new HashMap();

    SVGRoot root;
    final SVGUniverse universe;

    /**
     * This is used by the SVGRoot to determine the width of the 
     */
    private Rectangle deviceViewport = new Rectangle(100, 100);

    /**
     * If true, no attempt will be made to discard geometry based on it being
     * out of bounds.  This trades potentially drawing many out of bounds
     * shapes with having to recalculate bounding boxes every animation iteration.
     */
    protected boolean ignoreClipHeuristic = false;

    /**
     * URL which uniquely identifies this document
     */
//    final URI docRoot;

    /**
     * URI that uniquely identifies this document.  Also used to resolve
     * relative urls.  Default base for document.
     */
    final URI xmlBase;

    /** Creates a new instance of SVGDiagram */
    public SVGDiagram(URI xmlBase, SVGUniverse universe)
    {
        this.universe = universe;
//        this.docRoot = docRoot;
        this.xmlBase = xmlBase;
    }

    /**
     * Draws this diagram to the passed graphics context
     */
    public void render(Graphics2D g) throws SVGException
    {
        root.render(g);
    }
    
    /**
     * Searches thorough the scene graph for all RenderableElements that have
     * shapes that contain the passed point.
     * 
     * For every shape which contains the pick point, a List containing the
     * path to the node is added to the return list.  That is, the result of
     * SVGElement.getPath() is added for each entry.
     *
     * @return the passed in list
     */
    public List pick(Point2D point, List retVec) throws SVGException
    {
        return pick(point, false, retVec);
    }
    
    public List pick(Point2D point, boolean boundingBox, List retVec) throws SVGException
    {
        if (retVec == null)
        {
            retVec = new ArrayList();
        }
        
        root.pick(point, boundingBox, retVec);
        
        return retVec;
    }

    public List pick(Rectangle2D pickArea, List retVec) throws SVGException
    {
        return pick(pickArea, false, retVec);
    }
    
    public List pick(Rectangle2D pickArea, boolean boundingBox, List retVec) throws SVGException
    {
        if (retVec == null)
        {
            retVec = new ArrayList();
        }
        
        root.pick(pickArea, new AffineTransform(), boundingBox, retVec);
        
        return retVec;
    }

    public SVGUniverse getUniverse()
    {
        return universe;
    }

    public URI getXMLBase()
    {
        return xmlBase;
    }

//    public URL getDocRoot()
//    {
//        return docRoot;
//    }

    public float getWidth()
    {
        if (root == null) return 0;
        return root.getDeviceWidth();
    }
    
    public float getHeight()
    {
        if (root == null) return 0;
        return root.getDeviceHeight();
    }
    
    /**
     * Returns the viewing rectangle of this diagram in device coordinates.
     */
    public Rectangle2D getViewRect(Rectangle2D rect)
    {
        if (root != null) return root.getDeviceRect(rect);
        return rect;
    }

    public Rectangle2D getViewRect()
    {
        return getViewRect(new Rectangle2D.Double());
    }

    public SVGElement getElement(String name)
    {
        return (SVGElement)idMap.get(name);
    }

    public void setElement(String name, SVGElement node)
    {
        idMap.put(name, node);
    }

    public void removeElement(String name)
    {
        idMap.remove(name);
    }

    public SVGRoot getRoot()
    {
        return root;
    }

    public void setRoot(SVGRoot root)
    {
        this.root = root;
    }

    public boolean ignoringClipHeuristic() { return ignoreClipHeuristic; }

    public void setIgnoringClipHeuristic(boolean ignoreClipHeuristic) { this.ignoreClipHeuristic = ignoreClipHeuristic; }

    /**
     * Updates all attributes in this diagram associated with a time event.
     * Ie, all attributes with track information.
     */
    public void updateTime(double curTime) throws SVGException
    {
        if (root == null) return;
        root.updateTime(curTime);
    }

    public Rectangle getDeviceViewport()
    {
        return deviceViewport;
    }

    /**
     * Sets the dimensions of the device being rendered into.  This is used by
     * SVGRoot when its x, y, width or height parameters are specified as
     * percentages.
     */
    public void setDeviceViewport(Rectangle deviceViewport)
    {
        this.deviceViewport.setBounds(deviceViewport);
        if (root != null)
        {
            try
            {
                root.build();
            } catch (SVGException ex)
            {
                ex.printStackTrace();
            }
        }
    }
}