001/* 002 * SVG Salamander 003 * Copyright (c) 2004, Mark McKay 004 * All rights reserved. 005 * 006 * Redistribution and use in source and binary forms, with or 007 * without modification, are permitted provided that the following 008 * conditions are met: 009 * 010 * - Redistributions of source code must retain the above 011 * copyright notice, this list of conditions and the following 012 * disclaimer. 013 * - Redistributions in binary form must reproduce the above 014 * copyright notice, this list of conditions and the following 015 * disclaimer in the documentation and/or other materials 016 * provided with the distribution. 017 * 018 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 019 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 020 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 021 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 022 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 023 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 025 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 026 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 027 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 028 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 029 * OF THE POSSIBILITY OF SUCH DAMAGE. 030 * 031 * Mark McKay can be contacted at mark@kitfox.com. Salamander and other 032 * projects can be found at http://www.kitfox.com 033 * 034 * Created on February 18, 2004, 5:04 PM 035 */ 036 037package com.kitfox.svg; 038 039import java.awt.Graphics2D; 040import java.awt.Rectangle; 041import java.awt.geom.AffineTransform; 042import java.awt.geom.Point2D; 043import java.awt.geom.Rectangle2D; 044import java.io.Serializable; 045import java.net.URI; 046import java.util.ArrayList; 047import java.util.HashMap; 048import java.util.List; 049import java.util.logging.Level; 050import java.util.logging.Logger; 051 052 053/** 054 * Top level structure in an SVG tree. 055 * 056 * @author Mark McKay 057 * @author <a href="mailto:mark@kitfox.com">Mark McKay</a> 058 */ 059public class SVGDiagram implements Serializable 060{ 061 public static final long serialVersionUID = 0; 062 063 //Indexes elements within this SVG diagram 064 final HashMap<String, SVGElement> idMap = new HashMap<String, SVGElement>(); 065 066 SVGRoot root; 067 final SVGUniverse universe; 068 069 /** 070 * This is used by the SVGRoot to determine the width of the 071 */ 072 private Rectangle deviceViewport = new Rectangle(100, 100); 073 074 /** 075 * If true, no attempt will be made to discard geometry based on it being 076 * out of bounds. This trades potentially drawing many out of bounds 077 * shapes with having to recalculate bounding boxes every animation iteration. 078 */ 079 protected boolean ignoreClipHeuristic = false; 080 081 /** 082 * URL which uniquely identifies this document 083 */ 084// final URI docRoot; 085 086 /** 087 * URI that uniquely identifies this document. Also used to resolve 088 * relative urls. Default base for document. 089 */ 090 final URI xmlBase; 091 092 /** 093 * Creates a new instance of SVGDiagram 094 * @param xmlBase 095 * @param universe 096 */ 097 public SVGDiagram(URI xmlBase, SVGUniverse universe) 098 { 099 this.universe = universe; 100// this.docRoot = docRoot; 101 this.xmlBase = xmlBase; 102 } 103 104 /** 105 * Draws this diagram to the passed graphics context 106 * @param g 107 * @throws com.kitfox.svg.SVGException 108 */ 109 public void render(Graphics2D g) throws SVGException 110 { 111 root.renderToViewport(g); 112 } 113 114 /** 115 * Searches thorough the scene graph for all RenderableElements that have 116 * shapes that contain the passed point. 117 * 118 * For every shape which contains the pick point, a List containing the 119 * path to the node is added to the return list. That is, the result of 120 * SVGElement.getPath() is added for each entry. 121 * 122 * @param point 123 * @param retVec 124 * @return the passed in list 125 * @throws com.kitfox.svg.SVGException 126 */ 127 public List<List<SVGElement>> pick(Point2D point, List<List<SVGElement>> retVec) throws SVGException 128 { 129 return pick(point, false, retVec); 130 } 131 132 public List<List<SVGElement>> pick(Point2D point, boolean boundingBox, List<List<SVGElement>> retVec) throws SVGException 133 { 134 if (retVec == null) 135 { 136 retVec = new ArrayList<List<SVGElement>>(); 137 } 138 139 root.pick(point, boundingBox, retVec); 140 141 return retVec; 142 } 143 144 public List<List<SVGElement>> pick(Rectangle2D pickArea, List<List<SVGElement>> retVec) throws SVGException 145 { 146 return pick(pickArea, false, retVec); 147 } 148 149 public List<List<SVGElement>> pick(Rectangle2D pickArea, boolean boundingBox, List<List<SVGElement>> retVec) throws SVGException 150 { 151 if (retVec == null) 152 { 153 retVec = new ArrayList<List<SVGElement>>(); 154 } 155 156 root.pick(pickArea, new AffineTransform(), boundingBox, retVec); 157 158 return retVec; 159 } 160 161 public SVGUniverse getUniverse() 162 { 163 return universe; 164 } 165 166 public URI getXMLBase() 167 { 168 return xmlBase; 169 } 170 171// public URL getDocRoot() 172// { 173// return docRoot; 174// } 175 176 public float getWidth() 177 { 178 if (root == null) return 0; 179 return root.getDeviceWidth(); 180 } 181 182 public float getHeight() 183 { 184 if (root == null) return 0; 185 return root.getDeviceHeight(); 186 } 187 188 /** 189 * Returns the viewing rectangle of this diagram in device coordinates. 190 * @param rect 191 * @return 192 */ 193 public Rectangle2D getViewRect(Rectangle2D rect) 194 { 195 if (root != null) return root.getDeviceRect(rect); 196 return rect; 197 } 198 199 public Rectangle2D getViewRect() 200 { 201 return getViewRect(new Rectangle2D.Double()); 202 } 203 204 public SVGElement getElement(String name) 205 { 206 return (SVGElement)idMap.get(name); 207 } 208 209 public void setElement(String name, SVGElement node) 210 { 211 idMap.put(name, node); 212 } 213 214 public void removeElement(String name) 215 { 216 idMap.remove(name); 217 } 218 219 public SVGRoot getRoot() 220 { 221 return root; 222 } 223 224 public void setRoot(SVGRoot root) 225 { 226 this.root = root; 227 root.setDiagram(this); 228 } 229 230 public boolean ignoringClipHeuristic() { return ignoreClipHeuristic; } 231 232 public void setIgnoringClipHeuristic(boolean ignoreClipHeuristic) { this.ignoreClipHeuristic = ignoreClipHeuristic; } 233 234 /** 235 * Updates all attributes in this diagram associated with a time event. 236 * Ie, all attributes with track information. 237 * @param curTime 238 * @throws com.kitfox.svg.SVGException 239 */ 240 public void updateTime(double curTime) throws SVGException 241 { 242 if (root == null) return; 243 root.updateTime(curTime); 244 } 245 246 public Rectangle getDeviceViewport() 247 { 248 return deviceViewport; 249 } 250 251 /** 252 * Sets the dimensions of the device being rendered into. This is used by 253 * SVGRoot when its x, y, width or height parameters are specified as 254 * percentages. 255 * @param deviceViewport 256 */ 257 public void setDeviceViewport(Rectangle deviceViewport) 258 { 259 this.deviceViewport.setBounds(deviceViewport); 260 if (root != null) 261 { 262 try 263 { 264 root.build(); 265 } catch (SVGException ex) 266 { 267 Logger.getLogger(SVGConst.SVG_LOGGER).log(Level.WARNING, 268 "Could not build document", ex); 269 } 270 } 271 } 272}