Source Code Cross Referenced for SVGSVGElementBridge.java in  » Graphic-Library » batik » org » apache » batik » bridge » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Graphic Library » batik » org.apache.batik.bridge 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:
003:           Licensed to the Apache Software Foundation (ASF) under one or more
004:           contributor license agreements.  See the NOTICE file distributed with
005:           this work for additional information regarding copyright ownership.
006:           The ASF licenses this file to You under the Apache License, Version 2.0
007:           (the "License"); you may not use this file except in compliance with
008:           the License.  You may obtain a copy of the License at
009:
010:               http://www.apache.org/licenses/LICENSE-2.0
011:
012:           Unless required by applicable law or agreed to in writing, software
013:           distributed under the License is distributed on an "AS IS" BASIS,
014:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015:           See the License for the specific language governing permissions and
016:           limitations under the License.
017:
018:         */
019:        package org.apache.batik.bridge;
020:
021:        import java.awt.Dimension;
022:        import java.awt.RenderingHints;
023:        import java.awt.Shape;
024:        import java.awt.geom.AffineTransform;
025:        import java.awt.geom.NoninvertibleTransformException;
026:        import java.awt.geom.Rectangle2D;
027:        import java.util.ArrayList;
028:        import java.util.HashSet;
029:        import java.util.List;
030:        import java.util.Set;
031:
032:        import org.apache.batik.dom.svg.AnimatedLiveAttributeValue;
033:        import org.apache.batik.dom.svg.LiveAttributeException;
034:        import org.apache.batik.dom.svg.SVGContext;
035:        import org.apache.batik.dom.svg.SVGOMElement;
036:        import org.apache.batik.dom.svg.SVGOMSVGElement;
037:        import org.apache.batik.dom.svg.SVGSVGContext;
038:        import org.apache.batik.ext.awt.image.renderable.ClipRable8Bit;
039:        import org.apache.batik.ext.awt.image.renderable.Filter;
040:        import org.apache.batik.gvt.CanvasGraphicsNode;
041:        import org.apache.batik.gvt.CompositeGraphicsNode;
042:        import org.apache.batik.gvt.GraphicsNode;
043:        import org.apache.batik.gvt.ShapeNode;
044:        import org.apache.batik.gvt.TextNode;
045:
046:        import org.w3c.dom.Element;
047:        import org.w3c.dom.Node;
048:        import org.w3c.dom.events.MutationEvent;
049:        import org.w3c.dom.svg.SVGDocument;
050:        import org.w3c.dom.svg.SVGRect;
051:
052:        /**
053:         * Bridge class for the <svg> element.
054:         *
055:         * @author <a href="mailto:tkormann@apache.org">Thierry Kormann</a>
056:         * @version $Id: SVGSVGElementBridge.java 475477 2006-11-15 22:44:28Z cam $
057:         */
058:        public class SVGSVGElementBridge extends SVGGElementBridge implements 
059:                SVGSVGContext {
060:
061:            /**
062:             * Constructs a new bridge for the &lt;svg> element.
063:             */
064:            public SVGSVGElementBridge() {
065:            }
066:
067:            /**
068:             * Returns 'svg'.
069:             */
070:            public String getLocalName() {
071:                return SVG_SVG_TAG;
072:            }
073:
074:            /**
075:             * Returns a new instance of this bridge.
076:             */
077:            public Bridge getInstance() {
078:                return new SVGSVGElementBridge();
079:            }
080:
081:            /**
082:             * Creates a <tt>CompositeGraphicsNode</tt>.
083:             */
084:            protected GraphicsNode instantiateGraphicsNode() {
085:                return new CanvasGraphicsNode();
086:            }
087:
088:            /**
089:             * Creates a <tt>GraphicsNode</tt> according to the specified parameters.
090:             *
091:             * @param ctx the bridge context to use
092:             * @param e the element that describes the graphics node to build
093:             * @return a graphics node that represents the specified element
094:             */
095:            public GraphicsNode createGraphicsNode(BridgeContext ctx, Element e) {
096:                // 'requiredFeatures', 'requiredExtensions' and 'systemLanguage'
097:                if (!SVGUtilities.matchUserAgent(e, ctx.getUserAgent())) {
098:                    return null;
099:                }
100:
101:                CanvasGraphicsNode cgn;
102:                cgn = (CanvasGraphicsNode) instantiateGraphicsNode();
103:
104:                associateSVGContext(ctx, e, cgn);
105:
106:                try {
107:                    // In some cases we converted document fragments which didn't
108:                    // have a parent SVG element, this check makes sure only the
109:                    // real root of the SVG Document tries to do negotiation with
110:                    // the UA.
111:                    SVGDocument doc = (SVGDocument) e.getOwnerDocument();
112:                    SVGOMSVGElement se = (SVGOMSVGElement) e;
113:                    boolean isOutermost = (doc.getRootElement() == e);
114:                    float x = 0;
115:                    float y = 0;
116:                    // x and y have no meaning on the outermost 'svg' element
117:                    if (!isOutermost) {
118:                        // 'x' attribute - default is 0
119:                        x = se.getX().getAnimVal().getValue();
120:
121:                        // 'y' attribute - default is 0
122:                        y = se.getY().getAnimVal().getValue();
123:                    }
124:
125:                    // 'width' attribute - default is 100%
126:                    float w = se.getWidth().getAnimVal().getValue();
127:
128:                    // 'height' attribute - default is 100%
129:                    float h = se.getHeight().getAnimVal().getValue();
130:
131:                    // 'visibility'
132:                    cgn.setVisible(CSSUtilities.convertVisibility(e));
133:
134:                    // 'viewBox' and "preserveAspectRatio' attributes
135:                    AffineTransform viewingTransform = ViewBox
136:                            .getPreserveAspectRatioTransform(e, w, h, ctx);
137:
138:                    float actualWidth = w;
139:                    float actualHeight = h;
140:                    try {
141:                        AffineTransform vtInv = viewingTransform
142:                                .createInverse();
143:                        actualWidth = (float) (w * vtInv.getScaleX());
144:                        actualHeight = (float) (h * vtInv.getScaleY());
145:                    } catch (NoninvertibleTransformException ex) {
146:                    }
147:
148:                    AffineTransform positionTransform = AffineTransform
149:                            .getTranslateInstance(x, y);
150:                    // The outermost preserveAspectRatio matrix is set by the user
151:                    // agent, so we don't need to set the transform for outermost svg
152:                    if (!isOutermost) {
153:                        // X & Y are ignored on outermost SVG.
154:                        cgn.setPositionTransform(positionTransform);
155:                    } else if (doc == ctx.getDocument()) {
156:                        // <!> FIXME: hack to compute the original document's size
157:                        ctx.setDocumentSize(new Dimension((int) (w + 0.5f),
158:                                (int) (h + 0.5f)));
159:                    }
160:                    // Set the viewing transform, this is often updated when the
161:                    // component prepares for rendering.
162:                    cgn.setViewingTransform(viewingTransform);
163:
164:                    // 'overflow' and 'clip'
165:                    Shape clip = null;
166:                    if (CSSUtilities.convertOverflow(e)) { // overflow:hidden
167:                        float[] offsets = CSSUtilities.convertClip(e);
168:                        if (offsets == null) { // clip:auto
169:                            clip = new Rectangle2D.Float(x, y, w, h);
170:                        } else { // clip:rect(<x> <y> <w> <h>)
171:                            // offsets[0] = top
172:                            // offsets[1] = right
173:                            // offsets[2] = bottom
174:                            // offsets[3] = left
175:                            clip = new Rectangle2D.Float(x + offsets[3], y
176:                                    + offsets[0], w - offsets[1] - offsets[3],
177:                                    h - offsets[2] - offsets[0]);
178:                        }
179:                    }
180:
181:                    if (clip != null) {
182:                        try {
183:                            AffineTransform at = new AffineTransform(
184:                                    positionTransform);
185:                            at.concatenate(viewingTransform);
186:                            at = at.createInverse(); // clip in user space
187:                            clip = at.createTransformedShape(clip);
188:                            Filter filter = cgn.getGraphicsNodeRable(true);
189:                            cgn.setClip(new ClipRable8Bit(filter, clip));
190:                        } catch (NoninvertibleTransformException ex) {
191:                        }
192:                    }
193:                    RenderingHints hints = null;
194:                    hints = CSSUtilities.convertColorRendering(e, hints);
195:                    if (hints != null)
196:                        cgn.setRenderingHints(hints);
197:
198:                    // 'enable-background'
199:                    Rectangle2D r = CSSUtilities.convertEnableBackground(e);
200:                    if (r != null) {
201:                        cgn.setBackgroundEnable(r);
202:                    }
203:
204:                    ctx.openViewport(e, new SVGSVGElementViewport(actualWidth,
205:                            actualHeight));
206:                    return cgn;
207:                } catch (LiveAttributeException ex) {
208:                    throw new BridgeException(ctx, ex);
209:                }
210:            }
211:
212:            /**
213:             * Builds using the specified BridgeContext and element, the
214:             * specified graphics node.
215:             *
216:             * @param ctx the bridge context to use
217:             * @param e the element that describes the graphics node to build
218:             * @param node the graphics node to build
219:             */
220:            public void buildGraphicsNode(BridgeContext ctx, Element e,
221:                    GraphicsNode node) {
222:
223:                // 'opacity'
224:                node.setComposite(CSSUtilities.convertOpacity(e));
225:                // 'filter'
226:                node.setFilter(CSSUtilities.convertFilter(e, node, ctx));
227:                // 'mask'
228:                node.setMask(CSSUtilities.convertMask(e, node, ctx));
229:                // 'pointer-events'
230:                node.setPointerEventType(CSSUtilities.convertPointerEvents(e));
231:
232:                initializeDynamicSupport(ctx, e, node);
233:
234:                ctx.closeViewport(e);
235:            }
236:
237:            // BridgeUpdateHandler implementation //////////////////////////////////
238:
239:            /**
240:             * Disposes this BridgeUpdateHandler and releases all resources.
241:             */
242:            public void dispose() {
243:                ctx.removeViewport(e);
244:                super .dispose();
245:            }
246:
247:            /**
248:             * Invoked when the animated value of an animatable attribute has changed.
249:             */
250:            public void handleAnimatedAttributeChanged(
251:                    AnimatedLiveAttributeValue alav) {
252:                try {
253:                    boolean rebuild = false;
254:                    if (alav.getNamespaceURI() == null) {
255:                        String ln = alav.getLocalName();
256:                        if (ln.equals(SVG_WIDTH_ATTRIBUTE)
257:                                || ln.equals(SVG_HEIGHT_ATTRIBUTE)) {
258:                            rebuild = true;
259:                        } else if (ln.equals(SVG_X_ATTRIBUTE)
260:                                || ln.equals(SVG_Y_ATTRIBUTE)) {
261:                            SVGDocument doc = (SVGDocument) e
262:                                    .getOwnerDocument();
263:                            SVGOMSVGElement se = (SVGOMSVGElement) e;
264:                            // X & Y are ignored on outermost SVG.
265:                            boolean isOutermost = doc.getRootElement() == e;
266:                            if (!isOutermost) {
267:                                // 'x' attribute - default is 0
268:                                float x = se.getX().getAnimVal().getValue();
269:
270:                                // 'y' attribute - default is 0
271:                                float y = se.getY().getAnimVal().getValue();
272:
273:                                AffineTransform positionTransform = AffineTransform
274:                                        .getTranslateInstance(x, y);
275:                                CanvasGraphicsNode cgn;
276:                                cgn = (CanvasGraphicsNode) node;
277:
278:                                cgn.setPositionTransform(positionTransform);
279:                                return;
280:                            }
281:                        }
282:
283:                        if (rebuild) {
284:                            CompositeGraphicsNode gn = node.getParent();
285:                            gn.remove(node);
286:                            disposeTree(e, false);
287:
288:                            handleElementAdded(gn, e.getParentNode(), e);
289:                            return;
290:                        }
291:                    }
292:                } catch (LiveAttributeException ex) {
293:                    throw new BridgeException(ctx, ex);
294:                }
295:                super .handleAnimatedAttributeChanged(alav);
296:            }
297:
298:            /**
299:             * Invoked when an MutationEvent of type 'DOMAttrModified' is fired.
300:             */
301:            public void handleDOMAttrModifiedEvent(MutationEvent evt) {
302:                try {
303:                    // Don't call 'super' because there is no 'transform'
304:                    // attribute on <svg>
305:                    String attrName = evt.getAttrName();
306:                    boolean rebuild = false;
307:                    if (attrName.equals(SVG_VIEW_BOX_ATTRIBUTE)
308:                            || attrName
309:                                    .equals(SVG_PRESERVE_ASPECT_RATIO_ATTRIBUTE)) {
310:                        SVGDocument doc = (SVGDocument) e.getOwnerDocument();
311:                        SVGOMSVGElement se = (SVGOMSVGElement) e;
312:                        boolean isOutermost = doc.getRootElement() == e;
313:
314:                        // X & Y are ignored on outermost SVG.
315:                        float x = 0;
316:                        float y = 0;
317:                        if (!isOutermost) {
318:                            // 'x' attribute - default is 0
319:                            x = se.getX().getAnimVal().getValue();
320:
321:                            // 'y' attribute - default is 0
322:                            y = se.getY().getAnimVal().getValue();
323:                        }
324:
325:                        // 'width' attribute - default is 100%
326:                        float w = se.getWidth().getAnimVal().getValue();
327:
328:                        // 'height' attribute - default is 100%
329:                        float h = se.getHeight().getAnimVal().getValue();
330:
331:                        CanvasGraphicsNode cgn;
332:                        cgn = (CanvasGraphicsNode) node;
333:
334:                        // 'viewBox' and "preserveAspectRatio' attributes
335:                        AffineTransform newVT = ViewBox
336:                                .getPreserveAspectRatioTransform(e, w, h, ctx);
337:                        AffineTransform oldVT = cgn.getViewingTransform();
338:                        if ((newVT.getScaleX() != oldVT.getScaleX())
339:                                || (newVT.getScaleY() != oldVT.getScaleY())
340:                                || (newVT.getShearX() != oldVT.getShearX())
341:                                || (newVT.getShearY() != oldVT.getShearY()))
342:                            rebuild = true;
343:                        else {
344:                            // Only differs in translate.
345:                            cgn.setViewingTransform(newVT);
346:
347:                            // 'overflow' and 'clip'
348:                            Shape clip = null;
349:                            if (CSSUtilities.convertOverflow(e)) { // overflow:hidden
350:                                float[] offsets = CSSUtilities.convertClip(e);
351:                                if (offsets == null) { // clip:auto
352:                                    clip = new Rectangle2D.Float(x, y, w, h);
353:                                } else { // clip:rect(<x> <y> <w> <h>)
354:                                    // offsets[0] = top
355:                                    // offsets[1] = right
356:                                    // offsets[2] = bottom
357:                                    // offsets[3] = left
358:                                    clip = new Rectangle2D.Float(
359:                                            x + offsets[3], y + offsets[0], w
360:                                                    - offsets[1] - offsets[3],
361:                                            h - offsets[2] - offsets[0]);
362:                                }
363:                            }
364:
365:                            if (clip != null) {
366:                                try {
367:                                    AffineTransform at;
368:                                    at = cgn.getPositionTransform();
369:                                    if (at == null)
370:                                        at = new AffineTransform();
371:                                    else
372:                                        at = new AffineTransform(at);
373:                                    at.concatenate(newVT);
374:                                    at = at.createInverse(); // clip in user space
375:                                    clip = at.createTransformedShape(clip);
376:                                    Filter filter = cgn
377:                                            .getGraphicsNodeRable(true);
378:                                    cgn
379:                                            .setClip(new ClipRable8Bit(filter,
380:                                                    clip));
381:                                } catch (NoninvertibleTransformException ex) {
382:                                }
383:                            }
384:                        }
385:                    }
386:
387:                    if (rebuild) {
388:                        CompositeGraphicsNode gn = node.getParent();
389:                        gn.remove(node);
390:                        disposeTree(e, false);
391:
392:                        handleElementAdded(gn, e.getParentNode(), e);
393:                    }
394:                } catch (LiveAttributeException ex) {
395:                    throw new BridgeException(ctx, ex);
396:                }
397:            }
398:
399:            /**
400:             * A viewport defined an &lt;svg> element.
401:             */
402:            public static class SVGSVGElementViewport implements  Viewport {
403:                private float width;
404:                private float height;
405:
406:                /**
407:                 * Constructs a new viewport with the specified <tt>SVGSVGElement</tt>.
408:                 * @param w the width of the viewport
409:                 * @param h the height of the viewport
410:                 */
411:                public SVGSVGElementViewport(float w, float h) {
412:                    this .width = w;
413:                    this .height = h;
414:                }
415:
416:                /**
417:                 * Returns the width of this viewport.
418:                 */
419:                public float getWidth() {
420:                    return width;
421:                }
422:
423:                /**
424:                 * Returns the height of this viewport.
425:                 */
426:                public float getHeight() {
427:                    return height;
428:                }
429:            }
430:
431:            public List getIntersectionList(SVGRect svgRect, Element end) {
432:                List ret = new ArrayList();
433:                Rectangle2D rect = new Rectangle2D.Float(svgRect.getX(),
434:                        svgRect.getY(), svgRect.getWidth(), svgRect.getHeight());
435:
436:                GraphicsNode svgGN = ctx.getGraphicsNode(e);
437:                if (svgGN == null)
438:                    return ret;
439:
440:                Rectangle2D svgBounds = svgGN.getSensitiveBounds();
441:                if (svgBounds == null)
442:                    return ret;
443:
444:                // If the svg elem doesn't intersect none of the children
445:                // will.
446:                if (!rect.intersects(svgBounds))
447:                    return ret;
448:
449:                Element base = e;
450:                AffineTransform ati = svgGN.getGlobalTransform();
451:                try {
452:                    ati = ati.createInverse();
453:                } catch (NoninvertibleTransformException e) {
454:                }
455:
456:                Element curr;
457:                Node next = base.getFirstChild();
458:                while (next != null) {
459:                    if (next instanceof  Element)
460:                        break;
461:                    next = next.getNextSibling();
462:                }
463:                if (next == null)
464:                    return ret;
465:                curr = (Element) next;
466:
467:                Set ancestors = null;
468:                if (end != null) {
469:                    ancestors = getAncestors(end, base);
470:                    if (ancestors == null)
471:                        end = null;
472:                }
473:                while (curr != null) {
474:                    String nsURI = curr.getNamespaceURI();
475:                    String tag = curr.getLocalName();
476:                    boolean isGroup;
477:                    isGroup = SVG_NAMESPACE_URI.equals(nsURI)
478:                            && (SVG_G_TAG.equals(tag)
479:                                    || SVG_SVG_TAG.equals(tag) || SVG_A_TAG
480:                                    .equals(tag));
481:
482:                    GraphicsNode gn = ctx.getGraphicsNode(curr);
483:                    if (gn == null) {
484:                        // No graphics node but check if curr is an
485:                        // ancestor of end.
486:                        if ((ancestors != null) && (ancestors.contains(curr)))
487:                            break;
488:                        curr = getNext(curr, base, end);
489:                        continue;
490:                    }
491:
492:                    AffineTransform at = gn.getGlobalTransform();
493:                    Rectangle2D gnBounds = gn.getSensitiveBounds();
494:                    at.preConcatenate(ati);
495:                    if (gnBounds != null)
496:                        gnBounds = at.createTransformedShape(gnBounds)
497:                                .getBounds2D();
498:
499:                    if ((gnBounds == null) || (!rect.intersects(gnBounds))) {
500:                        // Graphics node does not intersect check if curr is
501:                        // an ancestor of end.
502:                        if ((ancestors != null) && (ancestors.contains(curr)))
503:                            break;
504:                        curr = getNext(curr, base, end);
505:                        continue;
506:                    }
507:
508:                    // Check if it is an SVG 'g', or 'svg' element in
509:                    // which case don't add this node but do check it's
510:                    // children.
511:                    if (isGroup) {
512:                        // Check children.
513:                        next = curr.getFirstChild();
514:                        while (next != null) {
515:                            if (next instanceof  Element)
516:                                break;
517:                            next = next.getNextSibling();
518:                        }
519:                        if (next != null) {
520:                            curr = (Element) next;
521:                            continue;
522:                        }
523:                    } else {
524:                        if (curr == end)
525:                            break;
526:                        // Otherwise check this node for intersection more
527:                        // carefully and if it still intersects add it.
528:                        if (SVG_NAMESPACE_URI.equals(nsURI)
529:                                && SVG_USE_TAG.equals(tag)) {
530:                            // FIXX: This really isn't right we need to 
531:                            // Add the proxy children.
532:                            if (rect.contains(gnBounds))
533:                                ret.add(curr);
534:                        }
535:                        if (gn instanceof  ShapeNode) {
536:                            ShapeNode sn = (ShapeNode) gn;
537:                            Shape sensitive = sn.getSensitiveArea();
538:                            if (sensitive != null) {
539:                                sensitive = at
540:                                        .createTransformedShape(sensitive);
541:                                if (sensitive.intersects(rect))
542:                                    ret.add(curr);
543:                            }
544:                        } else if (gn instanceof  TextNode) {
545:                            SVGOMElement svgElem = (SVGOMElement) curr;
546:                            SVGTextElementBridge txtBridge;
547:                            txtBridge = (SVGTextElementBridge) svgElem
548:                                    .getSVGContext();
549:                            Set elems = txtBridge.getTextIntersectionSet(at,
550:                                    rect);
551:
552:                            // filter elems based on who is before end as
553:                            // children of curr, if needed.
554:                            if ((ancestors != null) && ancestors.contains(curr))
555:                                filterChildren(curr, end, elems, ret);
556:                            else
557:                                ret.addAll(elems);
558:
559:                        } else {
560:                            ret.add(curr);
561:                        }
562:                    }
563:
564:                    curr = getNext(curr, base, end);
565:                }
566:
567:                return ret;
568:            }
569:
570:            public List getEnclosureList(SVGRect svgRect, Element end) {
571:                List ret = new ArrayList();
572:                Rectangle2D rect = new Rectangle2D.Float(svgRect.getX(),
573:                        svgRect.getY(), svgRect.getWidth(), svgRect.getHeight());
574:                GraphicsNode svgGN = ctx.getGraphicsNode(e);
575:                if (svgGN == null)
576:                    return ret;
577:
578:                Rectangle2D svgBounds = svgGN.getSensitiveBounds();
579:                if (svgBounds == null)
580:                    return ret;
581:
582:                // If the svg elem doesn't at least intersect none of the
583:                // children will be enclosed.
584:                if (!rect.intersects(svgBounds))
585:                    return ret;
586:
587:                Element base = e;
588:                AffineTransform ati = svgGN.getGlobalTransform();
589:                try {
590:                    ati = ati.createInverse();
591:                } catch (NoninvertibleTransformException e) {
592:                }
593:
594:                Element curr;
595:                Node next = base.getFirstChild();
596:                while (next != null) {
597:                    if (next instanceof  Element)
598:                        break;
599:                    next = next.getNextSibling();
600:                }
601:
602:                if (next == null)
603:                    return ret;
604:                curr = (Element) next;
605:
606:                Set ancestors = null;
607:                if (end != null) {
608:                    ancestors = getAncestors(end, base);
609:                    if (ancestors == null)
610:                        end = null;
611:                }
612:
613:                while (curr != null) {
614:                    String nsURI = curr.getNamespaceURI();
615:                    String tag = curr.getLocalName();
616:                    boolean isGroup;
617:                    isGroup = SVG_NAMESPACE_URI.equals(nsURI)
618:                            && (SVG_G_TAG.equals(tag)
619:                                    || SVG_SVG_TAG.equals(tag) || SVG_A_TAG
620:                                    .equals(tag));
621:
622:                    GraphicsNode gn = ctx.getGraphicsNode(curr);
623:                    if (gn == null) {
624:                        // No graphics node but check if curr is an
625:                        // ancestor of end.
626:                        if ((ancestors != null) && (ancestors.contains(curr)))
627:                            break;
628:                        curr = getNext(curr, base, end);
629:                        continue;
630:                    }
631:
632:                    AffineTransform at = gn.getGlobalTransform();
633:                    Rectangle2D gnBounds = gn.getSensitiveBounds();
634:                    at.preConcatenate(ati);
635:                    if (gnBounds != null)
636:                        gnBounds = at.createTransformedShape(gnBounds)
637:                                .getBounds2D();
638:
639:                    if ((gnBounds == null) || (!rect.intersects(gnBounds))) {
640:                        // Graphics node does not intersect check if curr is
641:                        // an ancestor of end.
642:                        if ((ancestors != null) && (ancestors.contains(curr)))
643:                            break;
644:                        curr = getNext(curr, base, end);
645:                        continue;
646:                    }
647:
648:                    // If it is a group then don't add this node but do check
649:                    // it's children.
650:                    if (isGroup) {
651:                        // Check children.
652:                        next = curr.getFirstChild();
653:                        while (next != null) {
654:                            if (next instanceof  Element)
655:                                break;
656:                            next = next.getNextSibling();
657:                        }
658:                        if (next != null) {
659:                            curr = (Element) next;
660:                            continue;
661:                        }
662:                    } else {
663:                        if (curr == end)
664:                            break;
665:                        if (SVG_NAMESPACE_URI.equals(nsURI)
666:                                && SVG_USE_TAG.equals(tag)) {
667:                            // FIXX: This really isn't right we need to 
668:                            // Add the proxy children.
669:                            if (rect.contains(gnBounds))
670:                                ret.add(curr);
671:                        } else if (gn instanceof  TextNode) {
672:                            // If gnBounds is contained in rect then just add
673:                            // all the children
674:                            SVGOMElement svgElem = (SVGOMElement) curr;
675:                            SVGTextElementBridge txtBridge;
676:                            txtBridge = (SVGTextElementBridge) svgElem
677:                                    .getSVGContext();
678:                            Set elems = txtBridge.getTextEnclosureSet(at, rect);
679:
680:                            // filter elems based on who is before end as
681:                            // children of curr if needed.
682:                            if ((ancestors != null) && ancestors.contains(curr))
683:                                filterChildren(curr, end, elems, ret);
684:                            else
685:                                ret.addAll(elems);
686:                        } else if (rect.contains(gnBounds)) {
687:                            // shape nodes
688:                            ret.add(curr);
689:                        }
690:                    }
691:
692:                    curr = getNext(curr, base, end);
693:                }
694:                return ret;
695:            }
696:
697:            public boolean checkIntersection(Element element, SVGRect svgRect) {
698:
699:                GraphicsNode svgGN = ctx.getGraphicsNode(e);
700:                if (svgGN == null)
701:                    return false; // not in tree?
702:
703:                Rectangle2D rect = new Rectangle2D.Float(svgRect.getX(),
704:                        svgRect.getY(), svgRect.getWidth(), svgRect.getHeight());
705:                AffineTransform ati = svgGN.getGlobalTransform();
706:
707:                try {
708:                    ati = ati.createInverse();
709:                } catch (NoninvertibleTransformException e) {
710:                }
711:
712:                SVGContext svgctx = null;
713:                if (element instanceof  SVGOMElement) {
714:                    svgctx = ((SVGOMElement) element).getSVGContext();
715:                    if ((svgctx instanceof  SVGTextElementBridge)
716:                            || (svgctx instanceof  SVGTextElementBridge.AbstractTextChildSVGContext)) {
717:                        return SVGTextElementBridge.getTextIntersection(ctx,
718:                                element, ati, rect, true);
719:                    }
720:                }
721:
722:                Rectangle2D gnBounds = null;
723:                GraphicsNode gn = ctx.getGraphicsNode(element);
724:                if (gn != null)
725:                    gnBounds = gn.getSensitiveBounds();
726:
727:                if (gnBounds == null)
728:                    return false;
729:
730:                AffineTransform at = gn.getGlobalTransform();
731:                at.preConcatenate(ati);
732:
733:                gnBounds = at.createTransformedShape(gnBounds).getBounds2D();
734:                if (!rect.intersects(gnBounds))
735:                    return false;
736:
737:                // Check GN more closely
738:                if (!(gn instanceof  ShapeNode))
739:                    return true;
740:
741:                ShapeNode sn = (ShapeNode) gn;
742:                Shape sensitive = sn.getSensitiveArea();
743:                if (sensitive == null)
744:                    return false;
745:
746:                sensitive = at.createTransformedShape(sensitive);
747:                if (sensitive.intersects(rect))
748:                    return true;
749:
750:                return false;
751:            }
752:
753:            public boolean checkEnclosure(Element element, SVGRect svgRect) {
754:                GraphicsNode gn = ctx.getGraphicsNode(element);
755:                Rectangle2D gnBounds = null;
756:                SVGContext svgctx = null;
757:                if (element instanceof  SVGOMElement) {
758:                    svgctx = ((SVGOMElement) element).getSVGContext();
759:                    if ((svgctx instanceof  SVGTextElementBridge)
760:                            || (svgctx instanceof  SVGTextElementBridge.AbstractTextChildSVGContext)) {
761:                        gnBounds = SVGTextElementBridge.getTextBounds(ctx,
762:                                element, true);
763:                        Element p = (Element) element.getParentNode();
764:                        // Get GN for text children so we can get transform.
765:                        while ((p != null) && (gn == null)) {
766:                            gn = ctx.getGraphicsNode(p);
767:                            p = (Element) p.getParentNode();
768:                        }
769:                    } else if (gn != null)
770:                        gnBounds = gn.getSensitiveBounds();
771:                } else if (gn != null)
772:                    gnBounds = gn.getSensitiveBounds();
773:
774:                if (gnBounds == null)
775:                    return false;
776:
777:                GraphicsNode svgGN = ctx.getGraphicsNode(e);
778:                if (svgGN == null)
779:                    return false; // not in tree?
780:
781:                Rectangle2D rect = new Rectangle2D.Float(svgRect.getX(),
782:                        svgRect.getY(), svgRect.getWidth(), svgRect.getHeight());
783:                AffineTransform ati = svgGN.getGlobalTransform();
784:                try {
785:                    ati = ati.createInverse();
786:                } catch (NoninvertibleTransformException e) {
787:                }
788:
789:                AffineTransform at = gn.getGlobalTransform();
790:                at.preConcatenate(ati);
791:
792:                gnBounds = at.createTransformedShape(gnBounds).getBounds2D();
793:
794:                return rect.contains(gnBounds);
795:            }
796:
797:            public boolean filterChildren(Element curr, Element end, Set elems,
798:                    List ret) {
799:                Node child = curr.getFirstChild();
800:                while (child != null) {
801:                    if ((child instanceof  Element)
802:                            && filterChildren((Element) child, end, elems, ret))
803:                        return true;
804:                    child = child.getNextSibling();
805:                }
806:
807:                if (curr == end)
808:                    return true;
809:
810:                if (elems.contains(curr))
811:                    ret.add(curr);
812:
813:                return false;
814:            }
815:
816:            protected Set getAncestors(Element end, Element base) {
817:                Set ret = new HashSet();
818:                Element p = end;
819:                do {
820:                    ret.add(p);
821:                    p = (Element) p.getParentNode();
822:                } while ((p != null) && (p != base));
823:
824:                if (p == null) // 'end' is not a child of 'base'.
825:                    return null;
826:
827:                return ret;
828:            }
829:
830:            protected Element getNext(Element curr, Element base, Element end) {
831:                Node next;
832:                // Check the next element.
833:                next = curr.getNextSibling();
834:                while (next != null) {
835:                    if (next instanceof  Element)
836:                        break;
837:                    next = next.getNextSibling();
838:                }
839:                while (next == null) {
840:                    // No sibling so check parent's siblings...
841:                    curr = (Element) curr.getParentNode();
842:                    if ((curr == end) || (curr == base)) {
843:                        next = null; // signal we are done!
844:                        break;
845:                    }
846:                    next = curr.getNextSibling();
847:                    while (next != null) {
848:                        if (next instanceof  Element)
849:                            break;
850:                        next = next.getNextSibling();
851:                    }
852:                }
853:
854:                return (Element) next;
855:            }
856:
857:            public void deselectAll() {
858:                ctx.getUserAgent().deselectAll();
859:            }
860:
861:            public int suspendRedraw(int max_wait_milliseconds) {
862:                UpdateManager um = ctx.getUpdateManager();
863:                if (um != null)
864:                    return um.addRedrawSuspension(max_wait_milliseconds);
865:                return -1;
866:            }
867:
868:            public boolean unsuspendRedraw(int suspend_handle_id) {
869:                UpdateManager um = ctx.getUpdateManager();
870:                if (um != null)
871:                    return um.releaseRedrawSuspension(suspend_handle_id);
872:                return false; // no UM so couldn't have issued an id...
873:            }
874:
875:            public void unsuspendRedrawAll() {
876:                UpdateManager um = ctx.getUpdateManager();
877:                if (um != null)
878:                    um.releaseAllRedrawSuspension();
879:            }
880:
881:            public void forceRedraw() {
882:                UpdateManager um = ctx.getUpdateManager();
883:                if (um != null)
884:                    um.forceRepaint();
885:            }
886:
887:            /**
888:             * Pauses animations in the document.
889:             */
890:            public void pauseAnimations() {
891:                ctx.getAnimationEngine().pause();
892:            }
893:
894:            /**
895:             * Unpauses animations in the document.
896:             */
897:            public void unpauseAnimations() {
898:                ctx.getAnimationEngine().unpause();
899:            }
900:
901:            /**
902:             * Returns whether animations are currently paused.
903:             */
904:            public boolean animationsPaused() {
905:                return ctx.getAnimationEngine().isPaused();
906:            }
907:
908:            /**
909:             * Returns the current document time.
910:             */
911:            public float getCurrentTime() {
912:                return ctx.getAnimationEngine().getCurrentTime();
913:            }
914:
915:            /**
916:             * Sets the current document time.
917:             */
918:            public void setCurrentTime(float t) {
919:                ctx.getAnimationEngine().setCurrentTime(t);
920:            }
921:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.