KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > batik > bridge > svg12 > SVGMultiImageElementBridge


1 /*
2
3    Copyright 2002-2003 The Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16
17  */

18 package org.apache.batik.bridge.svg12;
19
20 import java.awt.Dimension JavaDoc;
21 import java.awt.geom.AffineTransform JavaDoc;
22 import java.awt.geom.Rectangle2D JavaDoc;
23 import java.util.Collection JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.LinkedList JavaDoc;
26 import java.util.List JavaDoc;
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 JavaDoc;
48 import org.w3c.dom.Document JavaDoc;
49 import org.w3c.dom.Element JavaDoc;
50 import org.w3c.dom.NamedNodeMap JavaDoc;
51 import org.w3c.dom.Node JavaDoc;
52
53 /**
54  * Bridge class for the <multiImage> element.
55  *
56  * The 'multiImage' element is similar to the 'image' element (supports
57  * all the same attributes and properties) except.
58  * <ol>
59  * <li>It can only be used to reference raster content (this is an
60  * implementation thing really)</li>
61  * <li>It has two addtional attributes: 'pixel-width' and
62  * 'pixel-height' which are the maximum width and height of the
63  * image referenced by the xlink:href attribute.</li>
64  * <li>It can contain a child element 'subImage' which has only
65  * three attributes, pixel-width, pixel-height and xlink:href.
66  * The image displayed is the smallest image such that
67  * pixel-width and pixel-height are greater than or equal to the
68  * required image size for display.</li>
69  * </ol>
70  *
71  *
72  * @author <a HREF="mailto:deweese@apache.org">Thomas DeWeese</a>
73  * @version $Id: SVGMultiImageElementBridge.java,v 1.4 2005/03/27 08:58:30 cam Exp $
74  */

75 public class SVGMultiImageElementBridge extends SVGImageElementBridge {
76
77     public SVGMultiImageElementBridge() { }
78
79     /**
80      * Returns the Batik Extension namespace URI.
81      */

82     public String JavaDoc getNamespaceURI() {
83         return SVG12Constants.SVG_NAMESPACE_URI;
84     }
85
86     /**
87      * Returns 'multiImage'.
88      */

89     public String JavaDoc getLocalName() {
90         return SVG12Constants.SVG_MULTI_IMAGE_TAG;
91     }
92
93     /**
94      * Returns a new instance of this bridge.
95      */

96     public Bridge getInstance() {
97         return new SVGImageElementBridge();
98     }
99
100      /**
101       * Creates a graphics node using the specified BridgeContext and for the
102       * specified element.
103       *
104       * @param ctx the bridge context to use
105       * @param e the element that describes the graphics node to build
106       * @return a graphics node that represents the specified element
107       */

108     public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) {
109         // 'requiredFeatures', 'requiredExtensions' and 'systemLanguage'
110
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 JavaDoc b = getImageBounds(ctx, e);
120
121         // 'transform'
122
AffineTransform JavaDoc at = null;
123         String JavaDoc 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 JavaDoc();
128
129         at.translate(b.getX(), b.getY());
130         imgNode.setTransform(at);
131         
132         // 'visibility'
133
imgNode.setVisible(CSSUtilities.convertVisibility(e));
134
135         Rectangle2D JavaDoc clip;
136         clip = new Rectangle2D.Double JavaDoc(0,0,b.getWidth(), b.getHeight());
137         Filter filter = imgNode.getGraphicsNodeRable(true);
138         imgNode.setClip(new ClipRable8Bit(filter, clip));
139
140         // 'enable-background'
141
Rectangle2D JavaDoc 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 JavaDoc elems = new LinkedList JavaDoc();
150         List JavaDoc minDim = new LinkedList JavaDoc();
151         List JavaDoc maxDim = new LinkedList JavaDoc();
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 JavaDoc [] mindary = new Dimension JavaDoc[elems.size()];
169         Dimension JavaDoc [] maxdary = new Dimension JavaDoc[elems.size()];
170         Element [] elemary = new Element [elems.size()];
171         Iterator JavaDoc mindi = minDim.iterator();
172         Iterator JavaDoc maxdi = maxDim.iterator();
173         Iterator JavaDoc ei = elems.iterator();
174         int n=0;
175         while (mindi.hasNext()) {
176             Dimension JavaDoc minD = (Dimension JavaDoc)mindi.next();
177             Dimension JavaDoc maxD = (Dimension JavaDoc)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     /**
208      * Returns false as shapes are not a container.
209      */

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         // Handle children elements such as <title>
220
//SVGUtilities.bridgeChildren(ctx, e);
221
//super.buildGraphicsNode(ctx, e, node);
222
ctx.closeViewport(e);
223     }
224
225     /**
226      * This method is invoked during the build phase if the document
227      * is dynamic. The responsability of this method is to ensure that
228      * any dynamic modifications of the element this bridge is
229      * dedicated to, happen on its associated GVT product.
230      */

231     protected void initializeDynamicSupport(BridgeContext ctx,
232                                             Element e,
233                                             GraphicsNode node) {
234         if (!ctx.isInteractive())
235             return;
236
237         // HACK due to the way images are represented in GVT
238
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     /**
250      * Disposes this BridgeUpdateHandler and releases all resources.
251      */

252     public void dispose() {
253         ctx.removeViewport(e);
254         super.dispose();
255     }
256
257     protected void addInfo(Element e, Collection JavaDoc elems,
258                            Collection JavaDoc minDim, Collection JavaDoc maxDim,
259                            Rectangle2D JavaDoc bounds) {
260         Document JavaDoc doc = e.getOwnerDocument();
261         Element gElem = doc.createElementNS(SVG_NAMESPACE_URI,
262                                               SVG_G_TAG);
263         NamedNodeMap JavaDoc attrs = e.getAttributes();
264         int len = attrs.getLength();
265         for (int i = 0; i < len; i++) {
266             Attr JavaDoc attr = (Attr JavaDoc)attrs.item(i);
267             gElem.setAttributeNS(attr.getNamespaceURI(),
268                                  attr.getName(),
269                                  attr.getValue());
270         }
271         // move the children from <subImage> to the <g> element
272
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 JavaDoc elems,
284                               Collection JavaDoc minDim, Collection JavaDoc maxDim,
285                               Rectangle2D JavaDoc bounds) {
286         String JavaDoc uriStr = XLinkSupport.getXLinkHref(e);
287         if (uriStr.length() == 0) {
288             throw new BridgeException(e, ERR_ATTRIBUTE_MISSING,
289                                       new Object JavaDoc[] {"xlink:href"});
290         }
291         String JavaDoc baseURI = XMLBaseSupport.getCascadedXMLBase(e);
292         ParsedURL purl;
293         if (baseURI == null) purl = new ParsedURL(uriStr);
294         else purl = new ParsedURL(baseURI, uriStr);
295         Document JavaDoc 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         // move the attributes from <subImageRef> to the <image> element
301
NamedNodeMap JavaDoc attrs = e.getAttributes();
302         int len = attrs.getLength();
303         for (int i = 0; i < len; i++) {
304             Attr JavaDoc attr = (Attr JavaDoc)attrs.item(i);
305             imgElem.setAttributeNS(attr.getNamespaceURI(),
306                                    attr.getName(),
307                                    attr.getValue());
308         }
309         String JavaDoc 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 JavaDoc getElementMinPixel(Element e, Rectangle2D JavaDoc bounds) {
326         return getElementPixelSize
327             (e, SVG12Constants.SVG_MAX_PIXEL_SIZE_ATTRIBUTE, bounds);
328     }
329     protected Dimension JavaDoc getElementMaxPixel(Element e, Rectangle2D JavaDoc bounds) {
330         return getElementPixelSize
331             (e, SVG12Constants.SVG_MIN_PIXEL_SIZE_ATTRIBUTE, bounds);
332     }
333
334     protected Dimension JavaDoc getElementPixelSize(Element e,
335                                             String JavaDoc attr,
336                                             Rectangle2D JavaDoc bounds) {
337         String JavaDoc s;
338         s = e.getAttribute(attr);
339         if (s.length() == 0) return null;
340
341         Float JavaDoc [] 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 JavaDoc((int)(bounds.getWidth()/xPixSz+0.5),
352                              (int)(bounds.getHeight()/yPixSz+0.5));
353     }
354
355     /**
356      * A viewport defined an &lt;svg> element.
357      */

358     public static class MultiImageElementViewport implements Viewport {
359         private float width;
360         private float height;
361
362         /**
363          * Constructs a new viewport with the specified <tt>SVGSVGElement</tt>.
364          * @param w the width of the viewport
365          * @param h the height of the viewport
366          */

367         public MultiImageElementViewport(float w, float h) {
368             this.width = w;
369             this.height = h;
370         }
371
372         /**
373          * Returns the width of this viewport.
374          */

375         public float getWidth(){
376             return width;
377         }
378
379         /**
380          * Returns the height of this viewport.
381          */

382         public float getHeight(){
383             return height;
384         }
385     }
386 }
387
Popular Tags