Source Code Cross Referenced for AbstractGraphicsNode.java in  » Graphic-Library » batik » org » apache » batik » gvt » 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.gvt 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:
0003:           Licensed to the Apache Software Foundation (ASF) under one or more
0004:           contributor license agreements.  See the NOTICE file distributed with
0005:           this work for additional information regarding copyright ownership.
0006:           The ASF licenses this file to You under the Apache License, Version 2.0
0007:           (the "License"); you may not use this file except in compliance with
0008:           the License.  You may obtain a copy of the License at
0009:
0010:               http://www.apache.org/licenses/LICENSE-2.0
0011:
0012:           Unless required by applicable law or agreed to in writing, software
0013:           distributed under the License is distributed on an "AS IS" BASIS,
0014:           WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0015:           See the License for the specific language governing permissions and
0016:           limitations under the License.
0017:
0018:         */
0019:        package org.apache.batik.gvt;
0020:
0021:        import java.awt.AlphaComposite;
0022:        import java.awt.Composite;
0023:        import java.awt.Graphics2D;
0024:        import java.awt.RenderingHints;
0025:        import java.awt.Shape;
0026:        import java.awt.geom.AffineTransform;
0027:        import java.awt.geom.NoninvertibleTransformException;
0028:        import java.awt.geom.Point2D;
0029:        import java.awt.geom.Rectangle2D;
0030:        import java.lang.ref.WeakReference;
0031:        import java.util.Iterator;
0032:        import java.util.List;
0033:        import java.util.Map;
0034:
0035:        import javax.swing.event.EventListenerList;
0036:
0037:        import org.apache.batik.ext.awt.RenderingHintsKeyExt;
0038:        import org.apache.batik.ext.awt.image.renderable.ClipRable;
0039:        import org.apache.batik.ext.awt.image.renderable.Filter;
0040:        import org.apache.batik.gvt.event.GraphicsNodeChangeEvent;
0041:        import org.apache.batik.gvt.event.GraphicsNodeChangeListener;
0042:        import org.apache.batik.gvt.filter.GraphicsNodeRable;
0043:        import org.apache.batik.gvt.filter.GraphicsNodeRable8Bit;
0044:        import org.apache.batik.gvt.filter.Mask;
0045:        import org.apache.batik.util.HaltingThread;
0046:
0047:        /**
0048:         * A partial implementation of the <tt>GraphicsNode</tt> interface.
0049:         *
0050:         * @author <a href="mailto:Thierry.Kormann@sophia.inria.fr">Thierry Kormann</a>
0051:         * @author <a href="mailto:etissandier@ilog.fr">Emmanuel Tissandier</a>
0052:         * @author <a href="mailto:Thomas.DeWeeese@Kodak.com">Thomas DeWeese</a>
0053:         * @version $Id: AbstractGraphicsNode.java 504084 2007-02-06 11:24:46Z dvholten $
0054:         */
0055:        public abstract class AbstractGraphicsNode implements  GraphicsNode {
0056:
0057:            /**
0058:             * The listeners list.
0059:             */
0060:            protected EventListenerList listeners;
0061:
0062:            /**
0063:             * The transform of this graphics node.
0064:             */
0065:            protected AffineTransform transform;
0066:
0067:            /**
0068:             * The inverse transform for this node, i.e., from parent node
0069:             * to this node.
0070:             */
0071:            protected AffineTransform inverseTransform;
0072:
0073:            /**
0074:             * The compositing operation to be used when a graphics node is
0075:             * painted on top of another one.
0076:             */
0077:            protected Composite composite;
0078:
0079:            /**
0080:             * This flag bit indicates whether or not this graphics node is visible.
0081:             */
0082:            protected boolean isVisible = true;
0083:
0084:            /**
0085:             * The clipping filter for this graphics node.
0086:             */
0087:            protected ClipRable clip;
0088:
0089:            /**
0090:             * The rendering hints that control the quality to use when rendering
0091:             * this graphics node.
0092:             */
0093:            protected RenderingHints hints;
0094:
0095:            /**
0096:             * The parent of this graphics node.
0097:             */
0098:            protected CompositeGraphicsNode parent;
0099:
0100:            /**
0101:             * The root of the GVT tree.
0102:             */
0103:            protected RootGraphicsNode root;
0104:
0105:            /**
0106:             * The mask of this graphics node.
0107:             */
0108:            protected Mask mask;
0109:
0110:            /**
0111:             * The filter of this graphics node.
0112:             */
0113:            protected Filter filter;
0114:
0115:            /**
0116:             * Indicates how this graphics node reacts to events.
0117:             */
0118:            protected int pointerEventType = VISIBLE_PAINTED;
0119:
0120:            /**
0121:             * The GraphicsNodeRable for this node.
0122:             */
0123:            protected WeakReference graphicsNodeRable;
0124:
0125:            /**
0126:             * The GraphicsNodeRable for this node with all filtering applied
0127:             */
0128:            protected WeakReference enableBackgroundGraphicsNodeRable;
0129:
0130:            /**
0131:             * A Weak Reference to this.
0132:             */
0133:            protected WeakReference weakRef;
0134:
0135:            /**
0136:             * Internal Cache: node bounds
0137:             */
0138:            private Rectangle2D bounds;
0139:
0140:            protected GraphicsNodeChangeEvent changeStartedEvent = null;
0141:            protected GraphicsNodeChangeEvent changeCompletedEvent = null;
0142:
0143:            /**
0144:             * Constructs a new graphics node.
0145:             */
0146:            protected AbstractGraphicsNode() {
0147:            }
0148:
0149:            /**
0150:             * Returns a canonical WeakReference to this GraphicsNode.
0151:             * This is suitable for use as a key value in a hash map
0152:             */
0153:            public WeakReference getWeakReference() {
0154:                if (weakRef == null)
0155:                    weakRef = new WeakReference(this );
0156:                return weakRef;
0157:            }
0158:
0159:            //
0160:            // Properties methods
0161:            //
0162:
0163:            /**
0164:             * Returns the type that describes how this graphics node reacts to events.
0165:             *
0166:             * @return VISIBLE_PAINTED | VISIBLE_FILL | VISIBLE_STROKE | VISIBLE |
0167:             * PAINTED | FILL | STROKE | ALL | NONE
0168:             */
0169:            public int getPointerEventType() {
0170:                return pointerEventType;
0171:            }
0172:
0173:            /**
0174:             * Sets the type that describes how this graphics node reacts to events.
0175:             *
0176:             * @param pointerEventType VISIBLE_PAINTED | VISIBLE_FILL | VISIBLE_STROKE |
0177:             * VISIBLE | PAINTED | FILL | STROKE | ALL | NONE
0178:             */
0179:            public void setPointerEventType(int pointerEventType) {
0180:                this .pointerEventType = pointerEventType;
0181:            }
0182:
0183:            /**
0184:             * Sets the transform of this node.
0185:             *
0186:             * @param newTransform the new transform of this node
0187:             */
0188:            public void setTransform(AffineTransform newTransform) {
0189:                fireGraphicsNodeChangeStarted();
0190:                this .transform = newTransform;
0191:                if (transform.getDeterminant() != 0) {
0192:                    try {
0193:                        inverseTransform = transform.createInverse();
0194:                    } catch (NoninvertibleTransformException e) {
0195:                        // Should never happen.
0196:                        throw new Error(e.getMessage());
0197:                    }
0198:                } else {
0199:                    // The transform is not invertible. Use the same
0200:                    // transform.
0201:                    inverseTransform = transform;
0202:                }
0203:                if (parent != null)
0204:                    parent.invalidateGeometryCache();
0205:                fireGraphicsNodeChangeCompleted();
0206:            }
0207:
0208:            /**
0209:             * Returns the transform of this node or null if any.
0210:             */
0211:            public AffineTransform getTransform() {
0212:                return transform;
0213:            }
0214:
0215:            /**
0216:             * Returns the inverse transform for this node.
0217:             */
0218:            public AffineTransform getInverseTransform() {
0219:                return inverseTransform;
0220:            }
0221:
0222:            /**
0223:             * Returns the concatenated transform of this node. That is, this
0224:             * node's transform preconcatenated with it's parent's transforms.
0225:             */
0226:            public AffineTransform getGlobalTransform() {
0227:                AffineTransform ctm = new AffineTransform();
0228:                GraphicsNode node = this ;
0229:                while (node != null) {
0230:                    if (node.getTransform() != null) {
0231:                        ctm.preConcatenate(node.getTransform());
0232:                    }
0233:                    node = node.getParent();
0234:                }
0235:                return ctm;
0236:            }
0237:
0238:            /**
0239:             * Sets the composite of this node.
0240:             *
0241:             * @param newComposite the composite of this node
0242:             */
0243:            public void setComposite(Composite newComposite) {
0244:                fireGraphicsNodeChangeStarted();
0245:                invalidateGeometryCache();
0246:                this .composite = newComposite;
0247:                fireGraphicsNodeChangeCompleted();
0248:            }
0249:
0250:            /**
0251:             * Returns the composite of this node or null if any.
0252:             */
0253:            public Composite getComposite() {
0254:                return composite;
0255:            }
0256:
0257:            /**
0258:             * Sets if this node is visible or not depending on the specified value.
0259:             *
0260:             * @param isVisible If true this node is visible
0261:             */
0262:            public void setVisible(boolean isVisible) {
0263:                fireGraphicsNodeChangeStarted();
0264:                this .isVisible = isVisible;
0265:                invalidateGeometryCache();
0266:                fireGraphicsNodeChangeCompleted();
0267:            }
0268:
0269:            /**
0270:             * Returns true if this node is visible, false otherwise.
0271:             */
0272:            public boolean isVisible() {
0273:                return isVisible;
0274:            }
0275:
0276:            public void setClip(ClipRable newClipper) {
0277:                if ((newClipper == null) && (this .clip == null))
0278:                    return; // No change still no clip.
0279:
0280:                fireGraphicsNodeChangeStarted();
0281:                invalidateGeometryCache();
0282:                this .clip = newClipper;
0283:                fireGraphicsNodeChangeCompleted();
0284:            }
0285:
0286:            /**
0287:             * Returns the clipping filter of this node or null if any.
0288:             */
0289:            public ClipRable getClip() {
0290:                return clip;
0291:            }
0292:
0293:            /**
0294:             * Maps the specified key to the specified value in the rendering hints of
0295:             * this node.
0296:             *
0297:             * @param key the key of the hint to be set
0298:             * @param value the value indicating preferences for the specified
0299:             * hint category.
0300:             */
0301:            public void setRenderingHint(RenderingHints.Key key, Object value) {
0302:                fireGraphicsNodeChangeStarted();
0303:                if (this .hints == null) {
0304:                    this .hints = new RenderingHints(key, value);
0305:                } else {
0306:                    hints.put(key, value);
0307:                }
0308:                fireGraphicsNodeChangeCompleted();
0309:            }
0310:
0311:            /**
0312:             * Copies all of the mappings from the specified Map to the
0313:             * rendering hints of this node.
0314:             *
0315:             * @param hints the rendering hints to be set
0316:             */
0317:            public void setRenderingHints(Map hints) {
0318:                fireGraphicsNodeChangeStarted();
0319:                if (this .hints == null) {
0320:                    this .hints = new RenderingHints(hints);
0321:                } else {
0322:                    this .hints.putAll(hints);
0323:                }
0324:                fireGraphicsNodeChangeCompleted();
0325:            }
0326:
0327:            /**
0328:             * Sets the rendering hints of this node.
0329:             *
0330:             * @param newHints the new rendering hints of this node
0331:             */
0332:            public void setRenderingHints(RenderingHints newHints) {
0333:                fireGraphicsNodeChangeStarted();
0334:                hints = newHints;
0335:                fireGraphicsNodeChangeCompleted();
0336:            }
0337:
0338:            /**
0339:             * Returns the rendering hints of this node or null if any.
0340:             */
0341:            public RenderingHints getRenderingHints() {
0342:                return hints;
0343:            }
0344:
0345:            /**
0346:             * Sets the mask of this node.
0347:             *
0348:             * @param newMask the new mask of this node
0349:             */
0350:            public void setMask(Mask newMask) {
0351:                if ((newMask == null) && (mask == null))
0352:                    return; // No change still no mask.
0353:
0354:                fireGraphicsNodeChangeStarted();
0355:                invalidateGeometryCache();
0356:                mask = newMask;
0357:                fireGraphicsNodeChangeCompleted();
0358:            }
0359:
0360:            /**
0361:             * Returns the mask of this node or null if any.
0362:             */
0363:            public Mask getMask() {
0364:                return mask;
0365:            }
0366:
0367:            /**
0368:             * Sets the filter of this node.
0369:             *
0370:             * @param newFilter the new filter of this node
0371:             */
0372:            public void setFilter(Filter newFilter) {
0373:                if ((newFilter == null) && (filter == null))
0374:                    return; // No change still no filter.
0375:
0376:                fireGraphicsNodeChangeStarted();
0377:                invalidateGeometryCache();
0378:                filter = newFilter;
0379:                fireGraphicsNodeChangeCompleted();
0380:            }
0381:
0382:            /**
0383:             * Returns the filter of this node or null if any.
0384:             */
0385:            public Filter getFilter() {
0386:                return filter;
0387:            }
0388:
0389:            /**
0390:             * Returns the GraphicsNodeRable for this node.  This
0391:             * GraphicsNodeRable is the Renderable (Filter) before any of the
0392:             * filter operations have been applied.
0393:             */
0394:            public Filter getGraphicsNodeRable(boolean createIfNeeded) {
0395:                GraphicsNodeRable ret = null;
0396:                if (graphicsNodeRable != null) {
0397:                    ret = (GraphicsNodeRable) graphicsNodeRable.get();
0398:                    if (ret != null)
0399:                        return ret;
0400:                }
0401:                if (createIfNeeded) {
0402:                    ret = new GraphicsNodeRable8Bit(this );
0403:                    graphicsNodeRable = new WeakReference(ret);
0404:                }
0405:                return ret;
0406:            }
0407:
0408:            /**
0409:             * Returns the GraphicsNodeRable for this node.  This
0410:             * GraphicsNodeRable is the Renderable (Filter) after all of the
0411:             * filter operations have been applied.
0412:             */
0413:            public Filter getEnableBackgroundGraphicsNodeRable(
0414:                    boolean createIfNeeded) {
0415:                GraphicsNodeRable ret = null;
0416:                if (enableBackgroundGraphicsNodeRable != null) {
0417:                    ret = (GraphicsNodeRable) enableBackgroundGraphicsNodeRable
0418:                            .get();
0419:                    if (ret != null)
0420:                        return ret;
0421:                }
0422:                if (createIfNeeded) {
0423:                    ret = new GraphicsNodeRable8Bit(this );
0424:                    ret.setUsePrimitivePaint(false);
0425:                    enableBackgroundGraphicsNodeRable = new WeakReference(ret);
0426:                }
0427:                return ret;
0428:            }
0429:
0430:            //
0431:            // Drawing methods
0432:            //
0433:
0434:            /**
0435:             * Paints this node.
0436:             *
0437:             * @param g2d the Graphics2D to use
0438:             */
0439:            public void paint(Graphics2D g2d) {
0440:                if ((composite != null)
0441:                        && (composite instanceof  AlphaComposite)) {
0442:                    AlphaComposite ac = (AlphaComposite) composite;
0443:                    if (ac.getAlpha() < 0.001)
0444:                        return; // No point in drawing
0445:                }
0446:                Rectangle2D bounds = getBounds();
0447:                if (bounds == null)
0448:                    return;
0449:
0450:                // Set up graphic context. It is important to setup the
0451:                // transform first, because the clip is defined in this node's
0452:                // user space.
0453:                Composite defaultComposite = null;
0454:                AffineTransform defaultTransform = null;
0455:                RenderingHints defaultHints = null;
0456:                Graphics2D baseG2d = null;
0457:
0458:                if (clip != null) {
0459:                    baseG2d = g2d;
0460:                    g2d = (Graphics2D) g2d.create();
0461:                    if (hints != null)
0462:                        g2d.addRenderingHints(hints);
0463:                    if (transform != null)
0464:                        g2d.transform(transform);
0465:                    if (composite != null)
0466:                        g2d.setComposite(composite);
0467:                    g2d.clip(clip.getClipPath());
0468:                } else {
0469:                    if (hints != null) {
0470:                        defaultHints = g2d.getRenderingHints();
0471:                        g2d.addRenderingHints(hints);
0472:                    }
0473:                    if (transform != null) {
0474:                        defaultTransform = g2d.getTransform();
0475:                        g2d.transform(transform);
0476:                    }
0477:                    if (composite != null) {
0478:                        defaultComposite = g2d.getComposite();
0479:                        g2d.setComposite(composite);
0480:                    }
0481:                }
0482:
0483:                Shape curClip = g2d.getClip();
0484:                g2d.setRenderingHint(RenderingHintsKeyExt.KEY_AREA_OF_INTEREST,
0485:                        curClip);
0486:
0487:                // Check if any painting is needed at all. Get the clip (in user space)
0488:                // and see if it intersects with this node's bounds (in user space).
0489:                boolean paintNeeded = true;
0490:                Shape g2dClip = curClip; //g2d.getClip();
0491:                if (g2dClip != null) {
0492:                    Rectangle2D cb = g2dClip.getBounds2D();
0493:                    if (!bounds.intersects(cb.getX(), cb.getY(), cb.getWidth(),
0494:                            cb.getHeight()))
0495:                        paintNeeded = false;
0496:                }
0497:
0498:                // Only paint if needed.
0499:                if (paintNeeded) {
0500:                    boolean antialiasedClip = false;
0501:                    if ((clip != null) && clip.getUseAntialiasedClip()) {
0502:                        antialiasedClip = isAntialiasedClip(g2d.getTransform(),
0503:                                g2d.getRenderingHints(), clip.getClipPath());
0504:                    }
0505:
0506:                    boolean useOffscreen = isOffscreenBufferNeeded();
0507:
0508:                    useOffscreen |= antialiasedClip;
0509:
0510:                    if (!useOffscreen) {
0511:                        // Render on this canvas.
0512:                        primitivePaint(g2d);
0513:                    } else {
0514:                        Filter filteredImage = null;
0515:
0516:                        if (filter == null) {
0517:                            filteredImage = getGraphicsNodeRable(true);
0518:                        } else {
0519:                            // traceFilter(filter, "=====>> ");
0520:                            filteredImage = filter;
0521:                        }
0522:
0523:                        if (mask != null) {
0524:                            if (mask.getSource() != filteredImage) {
0525:                                mask.setSource(filteredImage);
0526:                            }
0527:                            filteredImage = mask;
0528:                        }
0529:
0530:                        if (clip != null && antialiasedClip) {
0531:                            if (clip.getSource() != filteredImage) {
0532:                                clip.setSource(filteredImage);
0533:                            }
0534:                            filteredImage = clip;
0535:                        }
0536:
0537:                        baseG2d = g2d;
0538:                        // Only muck with the clip on a 'child'
0539:                        // graphics 2D otherwise when we restore the
0540:                        // clip it might 'wander' by a pixel.
0541:                        g2d = (Graphics2D) g2d.create();
0542:
0543:                        if (antialiasedClip) {
0544:                            // Remove hard edged clip
0545:                            g2d.setClip(null);
0546:                        }
0547:
0548:                        Rectangle2D filterBounds = filteredImage.getBounds2D();
0549:                        g2d.clip(filterBounds);
0550:
0551:                        org.apache.batik.ext.awt.image.GraphicsUtil.drawImage(
0552:                                g2d, filteredImage);
0553:
0554:                        g2d.dispose();
0555:                        g2d = baseG2d;
0556:                        baseG2d = null;// Don't leave null we need g2d restored...
0557:                    }
0558:                }
0559:
0560:                // Restore default rendering attributes
0561:                if (baseG2d != null) {
0562:                    g2d.dispose();
0563:                } else {
0564:                    if (defaultHints != null)
0565:                        g2d.setRenderingHints(defaultHints);
0566:                    if (defaultTransform != null)
0567:                        g2d.setTransform(defaultTransform);
0568:                    if (defaultComposite != null) {
0569:                        g2d.setComposite(defaultComposite);
0570:                    }
0571:                }
0572:            }
0573:
0574:            /**
0575:             * DEBUG: Trace filter chain
0576:             */
0577:            private void traceFilter(Filter filter, String prefix) {
0578:                System.out.println(prefix + filter.getClass().getName());
0579:                System.out.println(prefix + filter.getBounds2D());
0580:                List sources = filter.getSources();
0581:                int nSources = sources != null ? sources.size() : 0;
0582:                prefix += "\t";
0583:                for (int i = 0; i < nSources; i++) {
0584:                    Filter source = (Filter) sources.get(i);
0585:                    traceFilter(source, prefix);
0586:                }
0587:
0588:                System.out.flush();
0589:            }
0590:
0591:            /**
0592:             * Returns true of an offscreen buffer is needed to render this node, false
0593:             * otherwise.
0594:             */
0595:            protected boolean isOffscreenBufferNeeded() {
0596:                return ((filter != null) || (mask != null) || (composite != null && !AlphaComposite.SrcOver
0597:                        .equals(composite)));
0598:            }
0599:
0600:            /**
0601:             * Returns true if there is a clip and it should be antialiased
0602:             */
0603:            protected boolean isAntialiasedClip(AffineTransform usr2dev,
0604:                    RenderingHints hints, Shape clip) {
0605:                // Antialias clip if:
0606:                // + The KEY_CLIP_ANTIALIASING is true.
0607:                // *and*
0608:                // + clip is not null
0609:                // *and*
0610:                // + clip is not a rectangle in device space.
0611:                //
0612:                // This leaves out the case where the node clip is a
0613:                // rectangle and the current clip (i.e., the intersection
0614:                // of the current Graphics2D's clip and this node's clip)
0615:                // is not a rectangle.
0616:                //
0617:                if (clip == null)
0618:                    return false;
0619:
0620:                Object val = hints.get(RenderingHintsKeyExt.KEY_TRANSCODING);
0621:                if ((val == RenderingHintsKeyExt.VALUE_TRANSCODING_PRINTING)
0622:                        || (val == RenderingHintsKeyExt.VALUE_TRANSCODING_VECTOR))
0623:                    return false;
0624:
0625:                if (!(clip instanceof  Rectangle2D && usr2dev.getShearX() == 0 && usr2dev
0626:                        .getShearY() == 0))
0627:                    return true;
0628:
0629:                return false;
0630:            }
0631:
0632:            //
0633:            // Event support methods
0634:            //
0635:            public void fireGraphicsNodeChangeStarted(GraphicsNode changeSrc) {
0636:                if (changeStartedEvent == null)
0637:                    changeStartedEvent = new GraphicsNodeChangeEvent(this ,
0638:                            GraphicsNodeChangeEvent.CHANGE_STARTED);
0639:                changeStartedEvent.setChangeSrc(changeSrc);
0640:                fireGraphicsNodeChangeStarted(changeStartedEvent);
0641:                changeStartedEvent.setChangeSrc(null);
0642:            }
0643:
0644:            //
0645:            // Event support methods
0646:            //
0647:            public void fireGraphicsNodeChangeStarted() {
0648:                if (changeStartedEvent == null)
0649:                    changeStartedEvent = new GraphicsNodeChangeEvent(this ,
0650:                            GraphicsNodeChangeEvent.CHANGE_STARTED);
0651:                else {
0652:                    changeStartedEvent.setChangeSrc(null);
0653:                }
0654:                fireGraphicsNodeChangeStarted(changeStartedEvent);
0655:            }
0656:
0657:            public void fireGraphicsNodeChangeStarted(
0658:                    GraphicsNodeChangeEvent changeStartedEvent) {
0659:                // If we had per node listeners we would fire them here...
0660:
0661:                RootGraphicsNode rootGN = getRoot();
0662:                if (rootGN == null)
0663:                    return;
0664:
0665:                List l = rootGN.getTreeGraphicsNodeChangeListeners();
0666:                if (l == null)
0667:                    return;
0668:
0669:                Iterator i = l.iterator();
0670:                GraphicsNodeChangeListener gncl;
0671:                while (i.hasNext()) {
0672:                    gncl = (GraphicsNodeChangeListener) i.next();
0673:                    gncl.changeStarted(changeStartedEvent);
0674:                }
0675:            }
0676:
0677:            public void fireGraphicsNodeChangeCompleted() {
0678:                if (changeCompletedEvent == null) {
0679:                    changeCompletedEvent = new GraphicsNodeChangeEvent(this ,
0680:                            GraphicsNodeChangeEvent.CHANGE_COMPLETED);
0681:                }
0682:
0683:                // If we had per node listeners we would fire them here...
0684:
0685:                RootGraphicsNode rootGN = getRoot();
0686:                if (rootGN == null)
0687:                    return;
0688:
0689:                List l = rootGN.getTreeGraphicsNodeChangeListeners();
0690:                if (l == null)
0691:                    return;
0692:
0693:                Iterator i = l.iterator();
0694:                GraphicsNodeChangeListener gncl;
0695:                while (i.hasNext()) {
0696:                    gncl = (GraphicsNodeChangeListener) i.next();
0697:                    gncl.changeCompleted(changeCompletedEvent);
0698:                }
0699:            }
0700:
0701:            //
0702:            // Structural methods
0703:            //
0704:
0705:            /**
0706:             * Returns the parent of this node or null if any.
0707:             */
0708:            public CompositeGraphicsNode getParent() {
0709:                return parent;
0710:            }
0711:
0712:            /**
0713:             * Returns the root of the GVT tree or null if the node is not part of a GVT
0714:             * tree.
0715:             */
0716:            public RootGraphicsNode getRoot() {
0717:                return root;
0718:            }
0719:
0720:            /**
0721:             * Sets the root node of this graphics node.
0722:             *
0723:             * @param newRoot the new root node of this node
0724:             */
0725:            protected void setRoot(RootGraphicsNode newRoot) {
0726:                this .root = newRoot;
0727:            }
0728:
0729:            /**
0730:             * Sets the parent node of this graphics node.
0731:             *
0732:             * @param newParent the new parent node of this node
0733:             */
0734:            protected void setParent(CompositeGraphicsNode newParent) {
0735:                this .parent = newParent;
0736:            }
0737:
0738:            //
0739:            // Geometric methods
0740:            //
0741:
0742:            /**
0743:             * Invalidates the cached geometric bounds. This method is called
0744:             * each time an attribute that affects the bounds of this node
0745:             * changed.
0746:             */
0747:            protected void invalidateGeometryCache() {
0748:                // If our bounds are invalid then our parents bounds
0749:                // must be invalid also. So just return.
0750:                //if (bounds == null) return;
0751:
0752:                if (parent != null) {
0753:                    parent.invalidateGeometryCache();
0754:                }
0755:                bounds = null;
0756:            }
0757:
0758:            /**
0759:             * Returns the bounds of this node in user space. This includes primitive
0760:             * paint, filtering, clipping and masking.
0761:             */
0762:            public Rectangle2D getBounds() {
0763:                // Get the primitive bounds
0764:                // Rectangle2D bounds = null;
0765:                if (bounds == null) {
0766:                    // The painted region, before cliping, masking and compositing is
0767:                    // either the area painted by the primitive paint or the area
0768:                    // painted by the filter.
0769:                    if (filter == null) {
0770:                        bounds = getPrimitiveBounds();
0771:                    } else {
0772:                        bounds = filter.getBounds2D();
0773:                    }
0774:                    // Factor in the clipping area, if any
0775:                    if (bounds != null) {
0776:                        if (clip != null) {
0777:                            Rectangle2D clipR = clip.getClipPath()
0778:                                    .getBounds2D();
0779:                            if (clipR.intersects(bounds))
0780:                                Rectangle2D.intersect(bounds, clipR, bounds);
0781:                        }
0782:                        // Factor in the mask, if any
0783:                        if (mask != null) {
0784:                            Rectangle2D maskR = mask.getBounds2D();
0785:                            if (maskR.intersects(bounds))
0786:                                Rectangle2D.intersect(bounds, maskR, bounds);
0787:                        }
0788:                    }
0789:
0790:                    bounds = normalizeRectangle(bounds);
0791:
0792:                    // Check If we should halt early.
0793:                    if (HaltingThread.hasBeenHalted()) {
0794:                        // The Thread has been 'halted'.
0795:                        // Invalidate any cached values and proceed.
0796:                        invalidateGeometryCache();
0797:                    }
0798:                }
0799:
0800:                return bounds;
0801:            }
0802:
0803:            /**
0804:             * Returns the bounds of this node after applying the input transform
0805:             * (if any), concatenated with this node's transform (if any).
0806:             *
0807:             * @param txf the affine transform with which this node's transform should
0808:             *        be concatenated. Should not be null.
0809:             */
0810:            public Rectangle2D getTransformedBounds(AffineTransform txf) {
0811:                AffineTransform t = txf;
0812:                if (transform != null) {
0813:                    t = new AffineTransform(txf);
0814:                    t.concatenate(transform);
0815:                }
0816:
0817:                // The painted region, before cliping, masking and compositing
0818:                // is either the area painted by the primitive paint or the
0819:                // area painted by the filter.
0820:                Rectangle2D tBounds = null;
0821:                if (filter == null) {
0822:                    // Use txf, not t
0823:                    tBounds = getTransformedPrimitiveBounds(txf);
0824:                } else {
0825:                    tBounds = t.createTransformedShape(filter.getBounds2D())
0826:                            .getBounds2D();
0827:                }
0828:                // Factor in the clipping area, if any
0829:                if (tBounds != null) {
0830:                    if (clip != null) {
0831:                        Rectangle2D.intersect(tBounds, t
0832:                                .createTransformedShape(clip.getClipPath())
0833:                                .getBounds2D(), tBounds);
0834:                    }
0835:
0836:                    // Factor in the mask, if any
0837:                    if (mask != null) {
0838:                        Rectangle2D.intersect(tBounds, t
0839:                                .createTransformedShape(mask.getBounds2D())
0840:                                .getBounds2D(), tBounds);
0841:                    }
0842:                }
0843:
0844:                return tBounds;
0845:            }
0846:
0847:            /**
0848:             * Returns the bounds of this node's primitivePaint after applying
0849:             * the input transform (if any), concatenated with this node's
0850:             * transform (if any).
0851:             *
0852:             * @param txf the affine transform with which this node's transform should
0853:             *        be concatenated. Should not be null.  */
0854:            public Rectangle2D getTransformedPrimitiveBounds(AffineTransform txf) {
0855:                Rectangle2D tpBounds = getPrimitiveBounds();
0856:                if (tpBounds == null) {
0857:                    return null;
0858:                }
0859:                AffineTransform t = txf;
0860:                if (transform != null) {
0861:                    t = new AffineTransform(txf);
0862:                    t.concatenate(transform);
0863:                }
0864:
0865:                return t.createTransformedShape(tpBounds).getBounds2D();
0866:            }
0867:
0868:            /**
0869:             * Returns the bounds of the area covered by this node, without
0870:             * taking any of its rendering attribute into accoun. That is,
0871:             * exclusive of any clipping, masking, filtering or stroking, for
0872:             * example. The returned value is transformed by the concatenation
0873:             * of the input transform and this node's transform.
0874:             *
0875:             * @param txf the affine transform with which this node's transform should
0876:             *        be concatenated. Should not be null.
0877:             */
0878:            public Rectangle2D getTransformedGeometryBounds(AffineTransform txf) {
0879:                Rectangle2D tpBounds = getGeometryBounds();
0880:                if (tpBounds == null) {
0881:                    return null;
0882:                }
0883:                AffineTransform t = txf;
0884:                if (transform != null) {
0885:                    t = new AffineTransform(txf);
0886:                    t.concatenate(transform);
0887:                }
0888:
0889:                return t.createTransformedShape(tpBounds).getBounds2D();
0890:            }
0891:
0892:            /**
0893:             * Returns the bounds of the sensitive area covered by this node,
0894:             * This includes the stroked area but does not include the effects
0895:             * of clipping, masking or filtering. The returned value is
0896:             * transformed by the concatenation of the input transform and
0897:             * this node's transform.
0898:             *
0899:             * @param txf the affine transform with which this node's
0900:             * transform should be concatenated. Should not be null.
0901:             */
0902:            public Rectangle2D getTransformedSensitiveBounds(AffineTransform txf) {
0903:                Rectangle2D sBounds = getSensitiveBounds();
0904:                if (sBounds == null) {
0905:                    return null;
0906:                }
0907:                AffineTransform t = txf;
0908:                if (transform != null) {
0909:                    t = new AffineTransform(txf);
0910:                    t.concatenate(transform);
0911:                }
0912:
0913:                return t.createTransformedShape(sBounds).getBounds2D();
0914:            }
0915:
0916:            /**
0917:             * Returns true if the specified Point2D is inside the boundary of this
0918:             * node, false otherwise.
0919:             *
0920:             * @param p the specified Point2D in the user space
0921:             */
0922:            public boolean contains(Point2D p) {
0923:                Rectangle2D b = getSensitiveBounds();
0924:                if (b == null || !b.contains(p)) {
0925:                    return false;
0926:                }
0927:                switch (pointerEventType) {
0928:                case VISIBLE_PAINTED:
0929:                case VISIBLE_FILL:
0930:                case VISIBLE_STROKE:
0931:                case VISIBLE:
0932:                    return isVisible;
0933:                case PAINTED:
0934:                case FILL:
0935:                case STROKE:
0936:                case ALL:
0937:                    return true;
0938:                case NONE:
0939:                default:
0940:                    return false;
0941:                }
0942:            }
0943:
0944:            /**
0945:             * Returns true if the interior of this node intersects the interior of a
0946:             * specified Rectangle2D, false otherwise.
0947:             *
0948:             * @param r the specified Rectangle2D in the user node space
0949:             */
0950:            public boolean intersects(Rectangle2D r) {
0951:                Rectangle2D b = getBounds();
0952:                if (b == null)
0953:                    return false;
0954:
0955:                return b.intersects(r);
0956:            }
0957:
0958:            /**
0959:             * Returns the GraphicsNode containing point p if this node or one of its
0960:             * children is sensitive to mouse events at p.
0961:             *
0962:             * @param p the specified Point2D in the user space
0963:             */
0964:            public GraphicsNode nodeHitAt(Point2D p) {
0965:                return (contains(p) ? this  : null);
0966:            }
0967:
0968:            static double EPSILON = 1e-6;
0969:
0970:            /**
0971:             * This method makes sure that neither the width nor height of the
0972:             * rectangle is zero.  But it tries to make them very small
0973:             * relatively speaking.
0974:             */
0975:            protected Rectangle2D normalizeRectangle(Rectangle2D bounds) {
0976:                if (bounds == null)
0977:                    return null;
0978:
0979:                if ((bounds.getWidth() < EPSILON)) {
0980:                    if (bounds.getHeight() < EPSILON) {
0981:                        AffineTransform gt = getGlobalTransform();
0982:                        double det = Math.sqrt(gt.getDeterminant());
0983:                        return new Rectangle2D.Double(bounds.getX(), bounds
0984:                                .getY(), EPSILON / det, EPSILON / det);
0985:                    } else {
0986:                        double tmpW = bounds.getHeight() * EPSILON;
0987:                        if (tmpW < bounds.getWidth())
0988:                            tmpW = bounds.getWidth();
0989:                        return new Rectangle2D.Double(bounds.getX(), bounds
0990:                                .getY(), tmpW, bounds.getHeight());
0991:                    }
0992:                } else if (bounds.getHeight() < EPSILON) {
0993:                    double tmpH = bounds.getWidth() * EPSILON;
0994:                    if (tmpH < bounds.getHeight())
0995:                        tmpH = bounds.getHeight();
0996:                    return new Rectangle2D.Double(bounds.getX(), bounds.getY(),
0997:                            bounds.getWidth(), tmpH);
0998:                }
0999:                return bounds;
1000:            }
1001:
1002:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.