1 18 package org.apache.batik.bridge.svg12; 19 20 import java.awt.Dimension ; 21 import java.awt.geom.AffineTransform ; 22 import java.awt.geom.Rectangle2D ; 23 import java.util.Collection ; 24 import java.util.Iterator ; 25 import java.util.LinkedList ; 26 import java.util.List ; 27 28 import org.apache.batik.ext.awt.image.renderable.ClipRable8Bit; 29 import org.apache.batik.ext.awt.image.renderable.Filter; 30 31 import org.apache.batik.bridge.Bridge; 32 import org.apache.batik.bridge.BridgeContext; 33 import org.apache.batik.bridge.BridgeException; 34 import org.apache.batik.bridge.CSSUtilities; 35 import org.apache.batik.bridge.SVGImageElementBridge; 36 import org.apache.batik.bridge.SVGUtilities; 37 import org.apache.batik.bridge.Viewport; 38 import org.apache.batik.dom.svg.SVGOMElement; 39 import org.apache.batik.dom.svg.XMLBaseSupport; 40 import org.apache.batik.dom.util.XLinkSupport; 41 import org.apache.batik.gvt.GraphicsNode; 42 import org.apache.batik.gvt.ImageNode; 43 import org.apache.batik.gvt.svg12.MultiResGraphicsNode; 44 45 import org.apache.batik.util.ParsedURL; 46 import org.apache.batik.util.SVG12Constants; 47 import org.w3c.dom.Attr ; 48 import org.w3c.dom.Document ; 49 import org.w3c.dom.Element ; 50 import org.w3c.dom.NamedNodeMap ; 51 import org.w3c.dom.Node ; 52 53 75 public class SVGMultiImageElementBridge extends SVGImageElementBridge { 76 77 public SVGMultiImageElementBridge() { } 78 79 82 public String getNamespaceURI() { 83 return SVG12Constants.SVG_NAMESPACE_URI; 84 } 85 86 89 public String getLocalName() { 90 return SVG12Constants.SVG_MULTI_IMAGE_TAG; 91 } 92 93 96 public Bridge getInstance() { 97 return new SVGImageElementBridge(); 98 } 99 100 108 public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) { 109 if (!SVGUtilities.matchUserAgent(e, ctx.getUserAgent())) { 111 return null; 112 } 113 114 ImageNode imgNode = (ImageNode)instantiateGraphicsNode(); 115 if (imgNode == null) { 116 return null; 117 } 118 119 Rectangle2D b = getImageBounds(ctx, e); 120 121 AffineTransform at = null; 123 String s = e.getAttribute(SVG_TRANSFORM_ATTRIBUTE); 124 if (s.length() != 0) 125 at = SVGUtilities.convertTransform(e, SVG_TRANSFORM_ATTRIBUTE, s); 126 else 127 at = new AffineTransform (); 128 129 at.translate(b.getX(), b.getY()); 130 imgNode.setTransform(at); 131 132 imgNode.setVisible(CSSUtilities.convertVisibility(e)); 134 135 Rectangle2D clip; 136 clip = new Rectangle2D.Double (0,0,b.getWidth(), b.getHeight()); 137 Filter filter = imgNode.getGraphicsNodeRable(true); 138 imgNode.setClip(new ClipRable8Bit(filter, clip)); 139 140 Rectangle2D r = CSSUtilities.convertEnableBackground(e); 142 if (r != null) { 143 imgNode.setBackgroundEnable(r); 144 } 145 ctx.openViewport(e, new MultiImageElementViewport 146 ((float)b.getWidth(), (float)b.getHeight())); 147 148 149 List elems = new LinkedList (); 150 List minDim = new LinkedList (); 151 List maxDim = new LinkedList (); 152 153 for (Node n = e.getFirstChild(); n != null; n = n.getNextSibling()) { 154 if (n.getNodeType() != Node.ELEMENT_NODE) 155 continue; 156 157 Element se = (Element)n; 158 if (!getNamespaceURI().equals(se.getNamespaceURI())) 159 continue; 160 if (se.getLocalName().equals(SVG12Constants.SVG_SUB_IMAGE_TAG)) { 161 addInfo(se, elems, minDim, maxDim, b); 162 } 163 if (se.getLocalName().equals(SVG12Constants.SVG_SUB_IMAGE_REF_TAG)) { 164 addRefInfo(se, elems, minDim, maxDim, b); 165 } 166 } 167 168 Dimension [] mindary = new Dimension [elems.size()]; 169 Dimension [] maxdary = new Dimension [elems.size()]; 170 Element [] elemary = new Element [elems.size()]; 171 Iterator mindi = minDim.iterator(); 172 Iterator maxdi = maxDim.iterator(); 173 Iterator ei = elems.iterator(); 174 int n=0; 175 while (mindi.hasNext()) { 176 Dimension minD = (Dimension )mindi.next(); 177 Dimension maxD = (Dimension )maxdi.next(); 178 int i =0; 179 if (minD != null) { 180 for (; i<n; i++) { 181 if ((mindary[i] != null) && 182 (minD.width < mindary[i].width)) { 183 break; 184 } 185 } 186 } 187 for (int j=n; j>i; j--) { 188 elemary[j] = elemary[j-1]; 189 mindary[j] = mindary[j-1]; 190 maxdary[j] = maxdary[j-1]; 191 } 192 193 elemary[i] = (Element)ei.next(); 194 mindary[i] = minD; 195 maxdary[i] = maxD; 196 n++; 197 } 198 199 GraphicsNode node = new MultiResGraphicsNode(e, clip, elemary, 200 mindary, maxdary, 201 ctx); 202 imgNode.setImage(node); 203 204 return imgNode; 205 } 206 207 210 public boolean isComposite() { 211 return false; 212 } 213 214 public void buildGraphicsNode(BridgeContext ctx, 215 Element e, 216 GraphicsNode node) { 217 initializeDynamicSupport(ctx, e, node); 218 219 ctx.closeViewport(e); 223 } 224 225 231 protected void initializeDynamicSupport(BridgeContext ctx, 232 Element e, 233 GraphicsNode node) { 234 if (!ctx.isInteractive()) 235 return; 236 237 ImageNode imgNode = (ImageNode)node; 239 ctx.bind(e, imgNode.getImage()); 240 241 if (ctx.isDynamic()) { 242 this.e = e; 243 this.node = node; 244 this.ctx = ctx; 245 ((SVGOMElement)e).setSVGContext(this); 246 } 247 } 248 249 252 public void dispose() { 253 ctx.removeViewport(e); 254 super.dispose(); 255 } 256 257 protected void addInfo(Element e, Collection elems, 258 Collection minDim, Collection maxDim, 259 Rectangle2D bounds) { 260 Document doc = e.getOwnerDocument(); 261 Element gElem = doc.createElementNS(SVG_NAMESPACE_URI, 262 SVG_G_TAG); 263 NamedNodeMap attrs = e.getAttributes(); 264 int len = attrs.getLength(); 265 for (int i = 0; i < len; i++) { 266 Attr attr = (Attr )attrs.item(i); 267 gElem.setAttributeNS(attr.getNamespaceURI(), 268 attr.getName(), 269 attr.getValue()); 270 } 271 for (Node n = e.getFirstChild(); 273 n != null; 274 n = e.getFirstChild()) { 275 gElem.appendChild(n); 276 } 277 e.appendChild(gElem); 278 elems.add(gElem); 279 minDim.add(getElementMinPixel(e, bounds)); 280 maxDim.add(getElementMaxPixel(e, bounds)); 281 } 282 283 protected void addRefInfo(Element e, Collection elems, 284 Collection minDim, Collection maxDim, 285 Rectangle2D bounds) { 286 String uriStr = XLinkSupport.getXLinkHref(e); 287 if (uriStr.length() == 0) { 288 throw new BridgeException(e, ERR_ATTRIBUTE_MISSING, 289 new Object [] {"xlink:href"}); 290 } 291 String baseURI = XMLBaseSupport.getCascadedXMLBase(e); 292 ParsedURL purl; 293 if (baseURI == null) purl = new ParsedURL(uriStr); 294 else purl = new ParsedURL(baseURI, uriStr); 295 Document doc = e.getOwnerDocument(); 296 Element imgElem = doc.createElementNS(SVG_NAMESPACE_URI, 297 SVG_IMAGE_TAG); 298 imgElem.setAttributeNS(XLinkSupport.XLINK_NAMESPACE_URI, 299 "href", purl.toString()); 300 NamedNodeMap attrs = e.getAttributes(); 302 int len = attrs.getLength(); 303 for (int i = 0; i < len; i++) { 304 Attr attr = (Attr )attrs.item(i); 305 imgElem.setAttributeNS(attr.getNamespaceURI(), 306 attr.getName(), 307 attr.getValue()); 308 } 309 String s; 310 s = e.getAttribute("x"); 311 if (s.length() == 0) imgElem.setAttribute("x", "0"); 312 s = e.getAttribute("y"); 313 if (s.length() == 0) imgElem.setAttribute("y", "0"); 314 s = e.getAttribute("width"); 315 if (s.length() == 0) imgElem.setAttribute("width", "100%"); 316 s = e.getAttribute("height"); 317 if (s.length() == 0) imgElem.setAttribute("height", "100%"); 318 e.appendChild(imgElem); 319 elems.add(imgElem); 320 321 minDim.add(getElementMinPixel(e, bounds)); 322 maxDim.add(getElementMaxPixel(e, bounds)); 323 } 324 325 protected Dimension getElementMinPixel(Element e, Rectangle2D bounds) { 326 return getElementPixelSize 327 (e, SVG12Constants.SVG_MAX_PIXEL_SIZE_ATTRIBUTE, bounds); 328 } 329 protected Dimension getElementMaxPixel(Element e, Rectangle2D bounds) { 330 return getElementPixelSize 331 (e, SVG12Constants.SVG_MIN_PIXEL_SIZE_ATTRIBUTE, bounds); 332 } 333 334 protected Dimension getElementPixelSize(Element e, 335 String attr, 336 Rectangle2D bounds) { 337 String s; 338 s = e.getAttribute(attr); 339 if (s.length() == 0) return null; 340 341 Float [] vals = SVGUtilities.convertSVGNumberOptionalNumber 342 (e, attr, s); 343 344 if (vals[0] == null) return null; 345 346 float xPixSz = vals[0].floatValue(); 347 float yPixSz = xPixSz; 348 if (vals[1] != null) 349 yPixSz = vals[1].floatValue(); 350 351 return new Dimension ((int)(bounds.getWidth()/xPixSz+0.5), 352 (int)(bounds.getHeight()/yPixSz+0.5)); 353 } 354 355 358 public static class MultiImageElementViewport implements Viewport { 359 private float width; 360 private float height; 361 362 367 public MultiImageElementViewport(float w, float h) { 368 this.width = w; 369 this.height = h; 370 } 371 372 375 public float getWidth(){ 376 return width; 377 } 378 379 382 public float getHeight(){ 383 return height; 384 } 385 } 386 } 387 | Popular Tags |