Source Code Cross Referenced for SVGAnimationEngine.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) 


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.bridge;
0020:
0021:        import java.awt.Color;
0022:        import java.awt.Paint;
0023:        import java.lang.ref.WeakReference;
0024:        import java.util.Calendar;
0025:        import java.util.Date;
0026:        import java.util.HashSet;
0027:        import java.util.LinkedList;
0028:        import java.util.Arrays;
0029:        import java.util.Set;
0030:
0031:        import org.apache.batik.anim.AnimationEngine;
0032:        import org.apache.batik.anim.AnimationException;
0033:        import org.apache.batik.dom.anim.AnimationTarget;
0034:        import org.apache.batik.anim.timing.TimedDocumentRoot;
0035:        import org.apache.batik.anim.timing.TimedElement;
0036:        import org.apache.batik.anim.values.AnimatableAngleValue;
0037:        import org.apache.batik.anim.values.AnimatableAngleOrIdentValue;
0038:        import org.apache.batik.anim.values.AnimatableBooleanValue;
0039:        import org.apache.batik.anim.values.AnimatableIntegerValue;
0040:        import org.apache.batik.anim.values.AnimatableLengthValue;
0041:        import org.apache.batik.anim.values.AnimatableLengthListValue;
0042:        import org.apache.batik.anim.values.AnimatableLengthOrIdentValue;
0043:        import org.apache.batik.anim.values.AnimatableNumberValue;
0044:        import org.apache.batik.anim.values.AnimatableNumberListValue;
0045:        import org.apache.batik.anim.values.AnimatableNumberOrPercentageValue;
0046:        import org.apache.batik.anim.values.AnimatablePathDataValue;
0047:        import org.apache.batik.anim.values.AnimatablePointListValue;
0048:        import org.apache.batik.anim.values.AnimatablePreserveAspectRatioValue;
0049:        import org.apache.batik.anim.values.AnimatableNumberOrIdentValue;
0050:        import org.apache.batik.anim.values.AnimatableStringValue;
0051:        import org.apache.batik.anim.values.AnimatableValue;
0052:        import org.apache.batik.anim.values.AnimatableColorValue;
0053:        import org.apache.batik.anim.values.AnimatablePaintValue;
0054:        import org.apache.batik.css.engine.CSSEngine;
0055:        import org.apache.batik.css.engine.CSSStylableElement;
0056:        import org.apache.batik.css.engine.StyleMap;
0057:        import org.apache.batik.css.engine.value.FloatValue;
0058:        import org.apache.batik.css.engine.value.StringValue;
0059:        import org.apache.batik.css.engine.value.Value;
0060:        import org.apache.batik.css.engine.value.ValueManager;
0061:        import org.apache.batik.dom.svg.SVGOMDocument;
0062:        import org.apache.batik.dom.svg.SVGOMElement;
0063:        import org.apache.batik.dom.svg.SVGStylableElement;
0064:        import org.apache.batik.parser.DefaultPreserveAspectRatioHandler;
0065:        import org.apache.batik.parser.FloatArrayProducer;
0066:        import org.apache.batik.parser.DefaultLengthHandler;
0067:        import org.apache.batik.parser.LengthArrayProducer;
0068:        import org.apache.batik.parser.LengthHandler;
0069:        import org.apache.batik.parser.LengthListParser;
0070:        import org.apache.batik.parser.LengthParser;
0071:        import org.apache.batik.parser.NumberListParser;
0072:        import org.apache.batik.parser.PathArrayProducer;
0073:        import org.apache.batik.parser.PathParser;
0074:        import org.apache.batik.parser.PointsParser;
0075:        import org.apache.batik.parser.ParseException;
0076:        import org.apache.batik.parser.PreserveAspectRatioHandler;
0077:        import org.apache.batik.parser.PreserveAspectRatioParser;
0078:        import org.apache.batik.util.RunnableQueue;
0079:        import org.apache.batik.util.SMILConstants;
0080:        import org.apache.batik.util.XMLConstants;
0081:
0082:        import org.w3c.dom.Document;
0083:        import org.w3c.dom.Element;
0084:        import org.w3c.dom.css.CSSPrimitiveValue;
0085:        import org.w3c.dom.css.CSSStyleDeclaration;
0086:        import org.w3c.dom.css.CSSValue;
0087:        import org.w3c.dom.events.EventTarget;
0088:        import org.w3c.dom.svg.SVGAngle;
0089:        import org.w3c.dom.svg.SVGLength;
0090:        import org.w3c.dom.svg.SVGPreserveAspectRatio;
0091:
0092:        /**
0093:         * An AnimationEngine for SVG documents.
0094:         *
0095:         * @author <a href="mailto:cam%40mcc%2eid%2eau">Cameron McCormack</a>
0096:         * @version $Id: SVGAnimationEngine.java 522170 2007-03-25 07:18:46Z cam $
0097:         */
0098:        public class SVGAnimationEngine extends AnimationEngine {
0099:
0100:            /**
0101:             * The BridgeContext to use for value parsing.
0102:             */
0103:            protected BridgeContext ctx;
0104:
0105:            /**
0106:             * The CSSEngine used for CSS value parsing.
0107:             */
0108:            protected CSSEngine cssEngine;
0109:
0110:            /**
0111:             * Whether animation processing has started.  This affects whether
0112:             * animation element bridges add their animation on to the initial
0113:             * bridge list, or process them immediately.
0114:             */
0115:            protected boolean started;
0116:
0117:            /**
0118:             * The Runnable that ticks the document.
0119:             */
0120:            protected AnimationTickRunnable animationTickRunnable;
0121:
0122:            /**
0123:             * The factory for unparsed string values.
0124:             */
0125:            protected UncomputedAnimatableStringValueFactory uncomputedAnimatableStringValueFactory = new UncomputedAnimatableStringValueFactory();
0126:
0127:            /**
0128:             * The factory for length-or-ident values.
0129:             */
0130:            protected AnimatableLengthOrIdentFactory animatableLengthOrIdentFactory = new AnimatableLengthOrIdentFactory();
0131:
0132:            /**
0133:             * The factory for number-or-ident values.
0134:             */
0135:            protected AnimatableNumberOrIdentFactory animatableNumberOrIdentFactory = new AnimatableNumberOrIdentFactory(
0136:                    false);
0137:
0138:            /**
0139:             * Factories for {@link AnimatableValue} parsing.
0140:             */
0141:            protected Factory[] factories = { null, // TYPE_UNKNOWN
0142:                    new AnimatableIntegerValueFactory(), // TYPE_INTEGER
0143:                    new AnimatableNumberValueFactory(), // TYPE_NUMBER
0144:                    new AnimatableLengthValueFactory(), // TYPE_LENGTH
0145:                    null, // TYPE_NUMBER_OPTIONAL_NUMBER
0146:                    new AnimatableAngleValueFactory(), // TYPE_ANGLE
0147:                    new AnimatableColorValueFactory(), // TYPE_COLOR
0148:                    new AnimatablePaintValueFactory(), // TYPE_PAINT
0149:                    null, // TYPE_PERCENTAGE
0150:                    null, // TYPE_TRANSFORM_LIST
0151:                    uncomputedAnimatableStringValueFactory, // TYPE_URI
0152:                    null, // TYPE_FREQUENCY
0153:                    null, // TYPE_TIME
0154:                    new AnimatableNumberListValueFactory(), // TYPE_NUMBER_LIST
0155:                    new AnimatableLengthListValueFactory(), // TYPE_LENGTH_LIST
0156:                    uncomputedAnimatableStringValueFactory, // TYPE_IDENT
0157:                    uncomputedAnimatableStringValueFactory, // TYPE_CDATA
0158:                    animatableLengthOrIdentFactory, // TYPE_LENGTH_OR_INHERIT
0159:                    uncomputedAnimatableStringValueFactory, // TYPE_IDENT_LIST
0160:                    uncomputedAnimatableStringValueFactory, // TYPE_CLIP_VALUE
0161:                    uncomputedAnimatableStringValueFactory, // TYPE_URI_OR_IDENT
0162:                    uncomputedAnimatableStringValueFactory, // TYPE_CURSOR_VALUE
0163:                    new AnimatablePathDataFactory(), // TYPE_PATH_DATA
0164:                    uncomputedAnimatableStringValueFactory, // TYPE_ENABLE_BACKGROUND_VALUE
0165:                    null, // TYPE_TIME_VALUE_LIST
0166:                    animatableNumberOrIdentFactory, // TYPE_NUMBER_OR_INHERIT
0167:                    uncomputedAnimatableStringValueFactory, // TYPE_FONT_FAMILY_VALUE
0168:                    null, // TYPE_FONT_FACE_FONT_SIZE_VALUE
0169:                    new AnimatableNumberOrIdentFactory(true), // TYPE_FONT_WEIGHT_VALUE
0170:                    new AnimatableAngleOrIdentFactory(), // TYPE_ANGLE_OR_IDENT
0171:                    null, // TYPE_KEY_SPLINES_VALUE
0172:                    new AnimatablePointListValueFactory(), // TYPE_POINTS_VALUE
0173:                    new AnimatablePreserveAspectRatioValueFactory(), // TYPE_PRESERVE_ASPECT_RATIO_VALUE
0174:                    null, // TYPE_URI_LIST
0175:                    uncomputedAnimatableStringValueFactory, // TYPE_LENGTH_LIST_OR_IDENT
0176:                    null, // TYPE_CHARACTER_OR_UNICODE_RANGE_LIST
0177:                    null, // TYPE_UNICODE_RANGE_LIST
0178:                    null, // TYPE_FONT_VALUE
0179:                    null, // TYPE_FONT_DECSRIPTOR_SRC_VALUE
0180:                    animatableLengthOrIdentFactory, // TYPE_FONT_SIZE_VALUE
0181:                    animatableLengthOrIdentFactory, // TYPE_BASELINE_SHIFT_VALUE
0182:                    animatableLengthOrIdentFactory, // TYPE_KERNING_VALUE
0183:                    animatableLengthOrIdentFactory, // TYPE_SPACING_VALUE
0184:                    animatableLengthOrIdentFactory, // TYPE_LINE_HEIGHT_VALUE
0185:                    animatableNumberOrIdentFactory, // TYPE_FONT_SIZE_ADJUST_VALUE
0186:                    null, // TYPE_LANG_VALUE
0187:                    null, // TYPE_LANG_LIST_VALUE
0188:                    new AnimatableNumberOrPercentageValueFactory(), // TYPE_NUMBER_OR_PERCENTAGE
0189:                    null, // TYPE_TIMING_SPECIFIER_LIST
0190:                    new AnimatableBooleanValueFactory(), // TYPE_BOOLEAN
0191:            };
0192:
0193:            /**
0194:             * Whether the document is an SVG 1.2 document.
0195:             */
0196:            protected boolean isSVG12;
0197:
0198:            /**
0199:             * List of bridges that will be initialized when the document is started.
0200:             */
0201:            protected LinkedList initialBridges = new LinkedList();
0202:
0203:            /**
0204:             * A StyleMap used by the {@link Factory}s when computing CSS values.
0205:             */
0206:            protected StyleMap dummyStyleMap;
0207:
0208:            /**
0209:             * The thread that ticks the animation engine.
0210:             */
0211:            protected AnimationThread animationThread;
0212:
0213:            /**
0214:             * The animation limiting mode.
0215:             */
0216:            protected int animationLimitingMode;
0217:
0218:            /**
0219:             * The amount of animation limiting.
0220:             */
0221:            protected float animationLimitingAmount;
0222:
0223:            /**
0224:             * Set of SMIL animation event names for SVG 1.1.
0225:             */
0226:            protected static final Set animationEventNames11 = new HashSet();
0227:
0228:            /**
0229:             * Set of SMIL animation event names for SVG 1.2.
0230:             */
0231:            protected static final Set animationEventNames12 = new HashSet();
0232:
0233:            static {
0234:                String[] eventNamesCommon = { "click", "mousedown", "mouseup",
0235:                        "mouseover", "mousemove", "mouseout", "beginEvent",
0236:                        "endEvent" };
0237:                String[] eventNamesSVG11 = { "DOMSubtreeModified",
0238:                        "DOMNodeInserted", "DOMNodeRemoved",
0239:                        "DOMNodeRemovedFromDocument",
0240:                        "DOMNodeInsertedIntoDocument", "DOMAttrModified",
0241:                        "DOMCharacterDataModified", "SVGLoad", "SVGUnload",
0242:                        "SVGAbort", "SVGError", "SVGResize", "SVGScroll",
0243:                        "repeatEvent" };
0244:                String[] eventNamesSVG12 = { "load", "resize", "scroll", "zoom" };
0245:                for (int i = 0; i < eventNamesCommon.length; i++) {
0246:                    animationEventNames11.add(eventNamesCommon[i]);
0247:                    animationEventNames12.add(eventNamesCommon[i]);
0248:                }
0249:                for (int i = 0; i < eventNamesSVG11.length; i++) {
0250:                    animationEventNames11.add(eventNamesSVG11[i]);
0251:                }
0252:                for (int i = 0; i < eventNamesSVG12.length; i++) {
0253:                    animationEventNames12.add(eventNamesSVG12[i]);
0254:                }
0255:            }
0256:
0257:            /**
0258:             * Creates a new SVGAnimationEngine.
0259:             */
0260:            public SVGAnimationEngine(Document doc, BridgeContext ctx) {
0261:                super (doc);
0262:                this .ctx = ctx;
0263:                SVGOMDocument d = (SVGOMDocument) doc;
0264:                cssEngine = d.getCSSEngine();
0265:                dummyStyleMap = new StyleMap(cssEngine.getNumberOfProperties());
0266:                isSVG12 = d.isSVG12();
0267:            }
0268:
0269:            /**
0270:             * Disposes this animation engine.
0271:             */
0272:            public void dispose() {
0273:                synchronized (this ) {
0274:                    pause();
0275:                    super .dispose();
0276:                }
0277:            }
0278:
0279:            /**
0280:             * Adds an animation element bridge to the list of bridges that
0281:             * require initializing when the document is started.
0282:             */
0283:            public void addInitialBridge(SVGAnimationElementBridge b) {
0284:                if (initialBridges != null) {
0285:                    initialBridges.add(b);
0286:                }
0287:            }
0288:
0289:            /**
0290:             * Returns whether animation processing has begun.
0291:             */
0292:            public boolean hasStarted() {
0293:                return started;
0294:            }
0295:
0296:            /**
0297:             * Parses an AnimatableValue.
0298:             */
0299:            public AnimatableValue parseAnimatableValue(Element animElt,
0300:                    AnimationTarget target, String ns, String ln,
0301:                    boolean isCSS, String s) {
0302:                SVGOMElement elt = (SVGOMElement) target.getElement();
0303:                int type;
0304:                if (isCSS) {
0305:                    type = elt.getPropertyType(ln);
0306:                } else {
0307:                    type = elt.getAttributeType(ns, ln);
0308:                }
0309:                Factory factory = factories[type];
0310:                if (factory == null) {
0311:                    String an = ns == null ? ln : '{' + ns + '}' + ln;
0312:                    throw new BridgeException(ctx, animElt,
0313:                            "attribute.not.animatable", new Object[] {
0314:                                    target.getElement().getNodeName(), an });
0315:                }
0316:                return factories[type].createValue(target, ns, ln, isCSS, s);
0317:            }
0318:
0319:            /**
0320:             * Returns an AnimatableValue for the underlying value of a CSS property.
0321:             */
0322:            public AnimatableValue getUnderlyingCSSValue(Element animElt,
0323:                    AnimationTarget target, String pn) {
0324:                ValueManager[] vms = cssEngine.getValueManagers();
0325:                int idx = cssEngine.getPropertyIndex(pn);
0326:                if (idx != -1) {
0327:                    int type = vms[idx].getPropertyType();
0328:                    Factory factory = factories[type];
0329:                    if (factory == null) {
0330:                        throw new BridgeException(ctx, animElt,
0331:                                "attribute.not.animatable", new Object[] {
0332:                                        target.getElement().getNodeName(), pn });
0333:                    }
0334:                    SVGStylableElement e = (SVGStylableElement) target
0335:                            .getElement();
0336:                    CSSStyleDeclaration over = e.getOverrideStyle();
0337:                    String oldValue = over.getPropertyValue(pn);
0338:                    if (oldValue != null) {
0339:                        over.removeProperty(pn);
0340:                    }
0341:                    Value v = cssEngine.getComputedStyle(e, null, idx);
0342:                    if (oldValue != null && !oldValue.equals("")) {
0343:                        over.setProperty(pn, oldValue, null);
0344:                    }
0345:                    return factories[type].createValue(target, pn, v);
0346:                }
0347:                // XXX Doesn't handle shorthands.
0348:                return null;
0349:            }
0350:
0351:            /**
0352:             * Pauses the animations.
0353:             */
0354:            public void pause() {
0355:                super .pause();
0356:                UpdateManager um = ctx.getUpdateManager();
0357:                if (um != null) {
0358:                    um.getUpdateRunnableQueue().setIdleRunnable(null);
0359:                }
0360:            }
0361:
0362:            /**
0363:             * Pauses the animations.
0364:             */
0365:            public void unpause() {
0366:                super .unpause();
0367:                UpdateManager um = ctx.getUpdateManager();
0368:                if (um != null) {
0369:                    um.getUpdateRunnableQueue().setIdleRunnable(
0370:                            animationTickRunnable);
0371:                }
0372:            }
0373:
0374:            /**
0375:             * Returns the current document time.
0376:             */
0377:            public float getCurrentTime() {
0378:                boolean p = pauseTime != 0;
0379:                unpause();
0380:                float t = timedDocumentRoot.getCurrentTime();
0381:                if (p) {
0382:                    pause();
0383:                }
0384:                return t;
0385:            }
0386:
0387:            /**
0388:             * Sets the current document time.
0389:             */
0390:            public float setCurrentTime(float t) {
0391:                float ret = super .setCurrentTime(t);
0392:                if (animationTickRunnable != null) {
0393:                    animationTickRunnable.resume();
0394:                }
0395:                return ret;
0396:            }
0397:
0398:            /**
0399:             * Creates a new returns a new TimedDocumentRoot object for the document.
0400:             */
0401:            protected TimedDocumentRoot createDocumentRoot() {
0402:                return new AnimationRoot();
0403:            }
0404:
0405:            /**
0406:             * Starts the animation engine.
0407:             */
0408:            public void start(long documentStartTime) {
0409:                if (started) {
0410:                    return;
0411:                }
0412:                started = true;
0413:                try {
0414:                    try {
0415:                        Calendar cal = Calendar.getInstance();
0416:                        cal.setTime(new Date(documentStartTime));
0417:                        timedDocumentRoot.resetDocument(cal);
0418:                        Object[] bridges = initialBridges.toArray();
0419:                        initialBridges = null;
0420:                        for (int i = 0; i < bridges.length; i++) {
0421:                            SVGAnimationElementBridge bridge = (SVGAnimationElementBridge) bridges[i];
0422:                            bridge.initializeAnimation();
0423:                        }
0424:                        for (int i = 0; i < bridges.length; i++) {
0425:                            SVGAnimationElementBridge bridge = (SVGAnimationElementBridge) bridges[i];
0426:                            bridge.initializeTimedElement();
0427:                        }
0428:                        // tick(0, false);
0429:                        // animationThread = new AnimationThread();
0430:                        // animationThread.start();
0431:                        UpdateManager um = ctx.getUpdateManager();
0432:                        if (um != null) {
0433:                            RunnableQueue q = um.getUpdateRunnableQueue();
0434:                            animationTickRunnable = new AnimationTickRunnable(
0435:                                    q, this );
0436:                            q.setIdleRunnable(animationTickRunnable);
0437:                        }
0438:                    } catch (AnimationException ex) {
0439:                        throw new BridgeException(ctx, ex.getElement()
0440:                                .getElement(), ex.getMessage());
0441:                    }
0442:                } catch (Exception ex) {
0443:                    if (ctx.getUserAgent() == null) {
0444:                        ex.printStackTrace();
0445:                    } else {
0446:                        ctx.getUserAgent().displayError(ex);
0447:                    }
0448:                }
0449:            }
0450:
0451:            /**
0452:             * Sets the animation limiting mode to "none".
0453:             */
0454:            public void setAnimationLimitingNone() {
0455:                animationLimitingMode = 0;
0456:            }
0457:
0458:            /**
0459:             * Sets the animation limiting mode to a percentage of CPU.
0460:             * @param pc the maximum percentage of CPU to use (0 &lt; pc ≤ 1)
0461:             */
0462:            public void setAnimationLimitingCPU(float pc) {
0463:                animationLimitingMode = 1;
0464:                animationLimitingAmount = pc;
0465:            }
0466:
0467:            /**
0468:             * Sets the animation limiting mode to a number of frames per second.
0469:             * @param fps the maximum number of frames per second (fps &gt; 0)
0470:             */
0471:            public void setAnimationLimitingFPS(float fps) {
0472:                animationLimitingMode = 2;
0473:                animationLimitingAmount = fps;
0474:            }
0475:
0476:            /**
0477:             * A class for the root time container.
0478:             */
0479:            protected class AnimationRoot extends TimedDocumentRoot {
0480:
0481:                /**
0482:                 * Creates a new AnimationRoot object.
0483:                 */
0484:                public AnimationRoot() {
0485:                    super (!isSVG12, isSVG12);
0486:                }
0487:
0488:                /**
0489:                 * Returns the namespace URI of the event that corresponds to the given
0490:                 * animation event name.
0491:                 */
0492:                protected String getEventNamespaceURI(String eventName) {
0493:                    if (!isSVG12) {
0494:                        return null;
0495:                    }
0496:                    if (eventName.equals("focusin")
0497:                            || eventName.equals("focusout")
0498:                            || eventName.equals("activate")
0499:                            || animationEventNames12.contains(eventName)) {
0500:                        return XMLConstants.XML_EVENTS_NAMESPACE_URI;
0501:                    }
0502:                    return null;
0503:                }
0504:
0505:                /**
0506:                 * Returns the type of the event that corresponds to the given
0507:                 * animation event name.
0508:                 */
0509:                protected String getEventType(String eventName) {
0510:                    if (eventName.equals("focusin")) {
0511:                        return "DOMFocusIn";
0512:                    } else if (eventName.equals("focusout")) {
0513:                        return "DOMFocusOut";
0514:                    } else if (eventName.equals("activate")) {
0515:                        return "DOMActivate";
0516:                    }
0517:                    if (isSVG12) {
0518:                        if (animationEventNames12.contains(eventName)) {
0519:                            return eventName;
0520:                        }
0521:                    } else {
0522:                        if (animationEventNames11.contains(eventName)) {
0523:                            return eventName;
0524:                        }
0525:                    }
0526:                    return null;
0527:                }
0528:
0529:                /**
0530:                 * Returns the name of the repeat event.
0531:                 * @return "repeatEvent" for SVG
0532:                 */
0533:                protected String getRepeatEventName() {
0534:                    return SMILConstants.SMIL_REPEAT_EVENT_NAME;
0535:                }
0536:
0537:                /**
0538:                 * Fires a TimeEvent of the given type on this element.
0539:                 * @param eventType the type of TimeEvent ("beginEvent", "endEvent"
0540:                 *                  or "repeatEvent"/"repeat").
0541:                 * @param time the timestamp of the event object
0542:                 */
0543:                protected void fireTimeEvent(String eventType, Calendar time,
0544:                        int detail) {
0545:                    AnimationSupport.fireTimeEvent((EventTarget) document,
0546:                            eventType, time, detail);
0547:                }
0548:
0549:                /**
0550:                 * Invoked to indicate this timed element became active at the
0551:                 * specified time.
0552:                 * @param begin the time the element became active, in document simple time
0553:                 */
0554:                protected void toActive(float begin) {
0555:                }
0556:
0557:                /**
0558:                 * Invoked to indicate that this timed element became inactive.
0559:                 * @param stillActive if true, indicates that the element is still
0560:                 *                    actually active, but between the end of the
0561:                 *                    computed repeat duration and the end of the
0562:                 *                    interval
0563:                 * @param isFrozen whether the element is frozen or not
0564:                 */
0565:                protected void toInactive(boolean stillActive, boolean isFrozen) {
0566:                }
0567:
0568:                /**
0569:                 * Invoked to indicate that this timed element has had its fill removed.
0570:                 */
0571:                protected void removeFill() {
0572:                }
0573:
0574:                /**
0575:                 * Invoked to indicate that this timed element has been sampled at the
0576:                 * given time.
0577:                 * @param simpleTime the sample time in local simple time
0578:                 * @param simpleDur the simple duration of the element
0579:                 * @param repeatIteration the repeat iteration during which the element
0580:                 *                        was sampled
0581:                 */
0582:                protected void sampledAt(float simpleTime, float simpleDur,
0583:                        int repeatIteration) {
0584:                }
0585:
0586:                /**
0587:                 * Invoked to indicate that this timed element has been sampled
0588:                 * at the end of its active time, at an integer multiple of the
0589:                 * simple duration.  This is the "last" value that will be used
0590:                 * for filling, which cannot be sampled normally.
0591:                 */
0592:                protected void sampledLastValue(int repeatIteration) {
0593:                }
0594:
0595:                /**
0596:                 * Returns the timed element with the given ID.
0597:                 */
0598:                protected TimedElement getTimedElementById(String id) {
0599:                    return AnimationSupport.getTimedElementById(id, document);
0600:                }
0601:
0602:                /**
0603:                 * Returns the event target with the given ID.
0604:                 */
0605:                protected EventTarget getEventTargetById(String id) {
0606:                    return AnimationSupport.getEventTargetById(id, document);
0607:                }
0608:
0609:                /**
0610:                 * Returns the target of this animation as an {@link EventTarget}.  Used
0611:                 * for eventbase timing specifiers where the element ID is omitted.
0612:                 */
0613:                protected EventTarget getAnimationEventTarget() {
0614:                    return null;
0615:                }
0616:
0617:                /**
0618:                 * Returns the event target that should be listened to for
0619:                 * access key events.
0620:                 */
0621:                protected EventTarget getRootEventTarget() {
0622:                    return (EventTarget) document;
0623:                }
0624:
0625:                /**
0626:                 * Returns the DOM element that corresponds to this timed element, if
0627:                 * such a DOM element exists.
0628:                 */
0629:                public Element getElement() {
0630:                    return null;
0631:                }
0632:
0633:                /**
0634:                 * Returns whether this timed element comes before the given timed
0635:                 * element in document order.
0636:                 */
0637:                public boolean isBefore(TimedElement other) {
0638:                    return false;
0639:                }
0640:
0641:                /**
0642:                 * Invoked by timed elements in this document to indicate that the
0643:                 * current interval will be re-evaluated at the next sample.
0644:                 */
0645:                protected void currentIntervalWillUpdate() {
0646:                    if (animationTickRunnable != null) {
0647:                        animationTickRunnable.resume();
0648:                    }
0649:                }
0650:            }
0651:
0652:            /**
0653:             * Idle runnable to tick the animation, that reads times from System.in.
0654:             */
0655:            protected static class DebugAnimationTickRunnable extends
0656:                    AnimationTickRunnable {
0657:
0658:                float t = 0f;
0659:
0660:                public DebugAnimationTickRunnable(RunnableQueue q,
0661:                        SVGAnimationEngine eng) {
0662:                    super (q, eng);
0663:                    waitTime = Long.MAX_VALUE;
0664:                    new Thread() {
0665:                        public void run() {
0666:                            java.io.BufferedReader r = new java.io.BufferedReader(
0667:                                    new java.io.InputStreamReader(System.in));
0668:                            System.out.println("Enter times.");
0669:                            for (;;) {
0670:                                String s;
0671:                                try {
0672:                                    s = r.readLine();
0673:                                } catch (java.io.IOException e) {
0674:                                    s = null;
0675:                                }
0676:                                if (s == null) {
0677:                                    System.exit(0);
0678:                                }
0679:                                t = Float.parseFloat(s);
0680:                                DebugAnimationTickRunnable.this .resume();
0681:                            }
0682:                        }
0683:                    }.start();
0684:                }
0685:
0686:                public void resume() {
0687:                    waitTime = 0;
0688:                    Object lock = q.getIteratorLock();
0689:                    synchronized (lock) {
0690:                        lock.notify();
0691:                    }
0692:                }
0693:
0694:                public long getWaitTime() {
0695:                    long wt = waitTime;
0696:                    waitTime = Long.MAX_VALUE;
0697:                    return wt;
0698:                }
0699:
0700:                public void run() {
0701:                    SVGAnimationEngine eng = getAnimationEngine();
0702:                    synchronized (eng) {
0703:                        try {
0704:                            try {
0705:                                eng.tick(t, false);
0706:                            } catch (AnimationException ex) {
0707:                                throw new BridgeException(eng.ctx, ex
0708:                                        .getElement().getElement(), ex
0709:                                        .getMessage());
0710:                            }
0711:                        } catch (Exception ex) {
0712:                            if (eng.ctx.getUserAgent() == null) {
0713:                                ex.printStackTrace();
0714:                            } else {
0715:                                eng.ctx.getUserAgent().displayError(ex);
0716:                            }
0717:                        }
0718:                    }
0719:                }
0720:            }
0721:
0722:            /**
0723:             * Idle runnable to tick the animation.
0724:             */
0725:            protected static class AnimationTickRunnable implements 
0726:                    RunnableQueue.IdleRunnable {
0727:
0728:                /**
0729:                 * Calendar instance used for passing current time values to the
0730:                 * animation timing system.
0731:                 */
0732:                protected Calendar time = Calendar.getInstance();
0733:
0734:                //         /**
0735:                //          * The current document time in seconds, truncated.
0736:                //          */
0737:                //         protected double second = -1.;
0738:
0739:                //         /**
0740:                //          * The number of frames that have been ticked so far this second.
0741:                //          */
0742:                //         protected int frames;
0743:
0744:                /**
0745:                 * The number of milliseconds to wait until the next animation tick.
0746:                 * This is returned by {@link #getWaitTime()}.
0747:                 */
0748:                protected long waitTime;
0749:
0750:                /**
0751:                 * The RunnableQueue in which this is the
0752:                 * {@link RunnableQueue.IdleRunnable}.
0753:                 */
0754:                protected RunnableQueue q;
0755:
0756:                /**
0757:                 * The number of past tick times to keep, for computing the average
0758:                 * time per tick.
0759:                 */
0760:                private static final int NUM_TIMES = 8;
0761:
0762:                /**
0763:                 * The past tick times.
0764:                 */
0765:                protected long[] times = new long[NUM_TIMES];
0766:
0767:                /**
0768:                 * The sum of the times in {@link #times}.
0769:                 */
0770:                protected long sumTime;
0771:
0772:                /**
0773:                 * The current index into {@link #times}.
0774:                 */
0775:                protected int timeIndex;
0776:
0777:                /**
0778:                 * A weak reference to the SVGAnimationEngine this AnimationTickRunnable
0779:                 * is for.  We makes this a WeakReference so that a ticking animation
0780:                 * engine does not prevent from being GCed.
0781:                 */
0782:                protected WeakReference engRef;
0783:
0784:                /**
0785:                 * The maximum number of consecutive exceptions to allow before
0786:                 * stopping the report of them.
0787:                 */
0788:                protected static final int MAX_EXCEPTION_COUNT = 10;
0789:
0790:                /**
0791:                 * The number of consecutive exceptions that have been thrown.  This is
0792:                 * used to detect when exceptions are occurring every tick, and to stop
0793:                 * reporting them when this happens.
0794:                 */
0795:                protected int exceptionCount;
0796:
0797:                /**
0798:                 * Creates a new AnimationTickRunnable.
0799:                 */
0800:                public AnimationTickRunnable(RunnableQueue q,
0801:                        SVGAnimationEngine eng) {
0802:                    this .q = q;
0803:                    this .engRef = new WeakReference(eng);
0804:                    // Initialize the past times to 100ms.
0805:                    Arrays.fill(times, 100);
0806:                    sumTime = 100 * NUM_TIMES;
0807:                }
0808:
0809:                /**
0810:                 * Forces an animation update, if the {@link RunnableQueue} is
0811:                 * currently waiting.
0812:                 */
0813:                public void resume() {
0814:                    waitTime = 0;
0815:                    Object lock = q.getIteratorLock();
0816:                    synchronized (lock) {
0817:                        lock.notify();
0818:                    }
0819:                }
0820:
0821:                /**
0822:                 * Returns the system time that can be safely waited until before this
0823:                 * {@link Runnable} is run again.
0824:                 *
0825:                 * @return time to wait until, <code>0</code> if no waiting can
0826:                 *         be done, or {@link Long#MAX_VALUE} if the {@link Runnable}
0827:                 *         should not be run again at this time
0828:                 */
0829:                public long getWaitTime() {
0830:                    return waitTime;
0831:                }
0832:
0833:                /**
0834:                 * Performs one tick of the animation.
0835:                 */
0836:                public void run() {
0837:                    SVGAnimationEngine eng = getAnimationEngine();
0838:                    synchronized (eng) {
0839:                        int animationLimitingMode = eng.animationLimitingMode;
0840:                        float animationLimitingAmount = eng.animationLimitingAmount;
0841:                        try {
0842:                            try {
0843:                                long before = System.currentTimeMillis();
0844:                                time.setTime(new Date(before));
0845:                                float t = eng.timedDocumentRoot
0846:                                        .convertWallclockTime(time);
0847:                                //                         if (Math.floor(t) > second) {
0848:                                //                             second = Math.floor(t);
0849:                                //                             System.err.println("fps: " + frames);
0850:                                //                             frames = 0;
0851:                                //                         }
0852:                                float t2 = eng.tick(t, false);
0853:                                long after = System.currentTimeMillis();
0854:                                long dur = after - before;
0855:                                if (dur == 0) {
0856:                                    dur = 1;
0857:                                }
0858:                                sumTime -= times[timeIndex];
0859:                                sumTime += dur;
0860:                                times[timeIndex] = dur;
0861:                                timeIndex = (timeIndex + 1) % NUM_TIMES;
0862:
0863:                                if (t2 == Float.POSITIVE_INFINITY) {
0864:                                    waitTime = Long.MAX_VALUE;
0865:                                } else {
0866:                                    waitTime = before + (long) (t2 * 1000)
0867:                                            - 1000;
0868:                                    if (waitTime < after) {
0869:                                        waitTime = after;
0870:                                    }
0871:                                    if (animationLimitingMode != 0) {
0872:                                        float ave = (float) sumTime / NUM_TIMES;
0873:                                        float delay;
0874:                                        if (animationLimitingMode == 1) {
0875:                                            // %cpu
0876:                                            delay = ave
0877:                                                    / animationLimitingAmount
0878:                                                    - ave;
0879:                                        } else {
0880:                                            // fps
0881:                                            delay = 1000f
0882:                                                    / animationLimitingAmount
0883:                                                    - ave;
0884:                                        }
0885:                                        long newWaitTime = after + (long) delay;
0886:                                        if (newWaitTime > waitTime) {
0887:                                            waitTime = newWaitTime;
0888:                                        }
0889:                                    }
0890:                                }
0891:                                //                         frames++;
0892:                            } catch (AnimationException ex) {
0893:                                throw new BridgeException(eng.ctx, ex
0894:                                        .getElement().getElement(), ex
0895:                                        .getMessage());
0896:                            }
0897:                            exceptionCount = 0;
0898:                        } catch (Exception ex) {
0899:                            if (++exceptionCount < MAX_EXCEPTION_COUNT) {
0900:                                if (eng.ctx.getUserAgent() == null) {
0901:                                    ex.printStackTrace();
0902:                                } else {
0903:                                    eng.ctx.getUserAgent().displayError(ex);
0904:                                }
0905:                            }
0906:                        }
0907:
0908:                        if (animationLimitingMode == 0) {
0909:                            // so we don't steal too much time from the Swing thread
0910:                            try {
0911:                                Thread.sleep(1);
0912:                            } catch (InterruptedException ie) {
0913:                            }
0914:                        }
0915:                    }
0916:                }
0917:
0918:                /**
0919:                 * Returns the SVGAnimationEngine this AnimationTickRunnable is for.
0920:                 */
0921:                protected SVGAnimationEngine getAnimationEngine() {
0922:                    return (SVGAnimationEngine) engRef.get();
0923:                }
0924:            }
0925:
0926:            /**
0927:             * The thread that ticks the animation.
0928:             */
0929:            protected class AnimationThread extends Thread {
0930:
0931:                /**
0932:                 * The current time.
0933:                 */
0934:                protected Calendar time = Calendar.getInstance();
0935:
0936:                /**
0937:                 * The RunnableQueue to perform the animation in.
0938:                 */
0939:                protected RunnableQueue runnableQueue = ctx.getUpdateManager()
0940:                        .getUpdateRunnableQueue();
0941:
0942:                /**
0943:                 * The animation ticker Runnable.
0944:                 */
0945:                protected Ticker ticker = new Ticker();
0946:
0947:                /**
0948:                 * Ticks the animation over as fast as possible.
0949:                 */
0950:                public void run() {
0951:                    if (true) {
0952:                        for (;;) {
0953:                            time.setTime(new Date());
0954:                            ticker.t = timedDocumentRoot
0955:                                    .convertWallclockTime(time);
0956:                            try {
0957:                                runnableQueue.invokeAndWait(ticker);
0958:                            } catch (InterruptedException e) {
0959:                                return;
0960:                            }
0961:                        }
0962:                    } else {
0963:                        ticker.t = 1;
0964:                        while (ticker.t < 10) {
0965:                            try {
0966:                                Thread.sleep(1000);
0967:                            } catch (InterruptedException ie) {
0968:                            }
0969:                            try {
0970:                                runnableQueue.invokeAndWait(ticker);
0971:                            } catch (InterruptedException e) {
0972:                                return;
0973:                            }
0974:                            ticker.t++;
0975:                        }
0976:                    }
0977:                }
0978:
0979:                /**
0980:                 * A runnable that ticks the animation engine.
0981:                 */
0982:                protected class Ticker implements  Runnable {
0983:
0984:                    /**
0985:                     * The document time to tick at next.
0986:                     */
0987:                    protected float t;
0988:
0989:                    /**
0990:                     * Ticks the animation over.
0991:                     */
0992:                    public void run() {
0993:                        tick(t, false);
0994:                    }
0995:                }
0996:            }
0997:
0998:            // AnimatableValue factories
0999:
1000:            /**
1001:             * Interface for AnimatableValue factories.
1002:             */
1003:            protected interface Factory {
1004:
1005:                /**
1006:                 * Creates a new AnimatableValue from a string.
1007:                 */
1008:                AnimatableValue createValue(AnimationTarget target, String ns,
1009:                        String ln, boolean isCSS, String s);
1010:
1011:                /**
1012:                 * Creates a new AnimatableValue from a CSS {@link Value}.
1013:                 */
1014:                AnimatableValue createValue(AnimationTarget target, String pn,
1015:                        Value v);
1016:            }
1017:
1018:            /**
1019:             * Factory class for AnimatableValues for CSS properties.
1020:             * XXX Shorthand properties are not supported.
1021:             */
1022:            protected abstract class CSSValueFactory implements  Factory {
1023:
1024:                public AnimatableValue createValue(AnimationTarget target,
1025:                        String ns, String ln, boolean isCSS, String s) {
1026:                    // XXX Always parsing as a CSS value.
1027:                    return createValue(target, ln,
1028:                            createCSSValue(target, ln, s));
1029:                }
1030:
1031:                public AnimatableValue createValue(AnimationTarget target,
1032:                        String pn, Value v) {
1033:                    CSSStylableElement elt = (CSSStylableElement) target
1034:                            .getElement();
1035:                    v = computeValue(elt, pn, v);
1036:                    return createAnimatableValue(target, pn, v);
1037:                }
1038:
1039:                /**
1040:                 * Creates a new AnimatableValue from a CSS {@link Value}, after
1041:                 * computation and inheritance.
1042:                 */
1043:                protected abstract AnimatableValue createAnimatableValue(
1044:                        AnimationTarget target, String pn, Value v);
1045:
1046:                /**
1047:                 * Creates a new CSS {@link Value} from a string.
1048:                 */
1049:                protected Value createCSSValue(AnimationTarget t, String pn,
1050:                        String s) {
1051:                    CSSStylableElement elt = (CSSStylableElement) t
1052:                            .getElement();
1053:                    Value v = cssEngine.parsePropertyValue(elt, pn, s);
1054:                    return computeValue(elt, pn, v);
1055:                }
1056:
1057:                /**
1058:                 * Computes a CSS {@link Value} and performance inheritance if the
1059:                 * specified value is 'inherit'.
1060:                 */
1061:                protected Value computeValue(CSSStylableElement elt, String pn,
1062:                        Value v) {
1063:                    ValueManager[] vms = cssEngine.getValueManagers();
1064:                    int idx = cssEngine.getPropertyIndex(pn);
1065:                    if (idx != -1) {
1066:                        if (v.getCssValueType() == CSSValue.CSS_INHERIT) {
1067:                            elt = CSSEngine.getParentCSSStylableElement(elt);
1068:                            if (elt != null) {
1069:                                return cssEngine.getComputedStyle(elt, null,
1070:                                        idx);
1071:                            }
1072:                            return vms[idx].getDefaultValue();
1073:                        }
1074:                        v = vms[idx].computeValue(elt, null, cssEngine, idx,
1075:                                dummyStyleMap, v);
1076:                    }
1077:                    return v;
1078:                }
1079:            }
1080:
1081:            /**
1082:             * Factory class for {@link AnimatableBooleanValue}s.
1083:             */
1084:            protected class AnimatableBooleanValueFactory implements  Factory {
1085:
1086:                /**
1087:                 * Creates a new AnimatableValue from a string.
1088:                 */
1089:                public AnimatableValue createValue(AnimationTarget target,
1090:                        String ns, String ln, boolean isCSS, String s) {
1091:                    return new AnimatableBooleanValue(target, "true".equals(s));
1092:                }
1093:
1094:                /**
1095:                 * Creates a new AnimatableValue from a CSS {@link Value}.
1096:                 */
1097:                public AnimatableValue createValue(AnimationTarget target,
1098:                        String pn, Value v) {
1099:                    return new AnimatableBooleanValue(target, "true".equals(v
1100:                            .getCssText()));
1101:                }
1102:            }
1103:
1104:            /**
1105:             * Factory class for {@link AnimatableIntegerValue}s.
1106:             */
1107:            protected class AnimatableIntegerValueFactory implements  Factory {
1108:
1109:                /**
1110:                 * Creates a new AnimatableValue from a string.
1111:                 */
1112:                public AnimatableValue createValue(AnimationTarget target,
1113:                        String ns, String ln, boolean isCSS, String s) {
1114:                    return new AnimatableIntegerValue(target, Integer
1115:                            .parseInt(s));
1116:                }
1117:
1118:                /**
1119:                 * Creates a new AnimatableValue from a CSS {@link Value}.
1120:                 */
1121:                public AnimatableValue createValue(AnimationTarget target,
1122:                        String pn, Value v) {
1123:                    return new AnimatableIntegerValue(target, Math.round(v
1124:                            .getFloatValue()));
1125:                }
1126:            }
1127:
1128:            /**
1129:             * Factory class for {@link AnimatableNumberValue}s.
1130:             */
1131:            protected class AnimatableNumberValueFactory implements  Factory {
1132:
1133:                /**
1134:                 * Creates a new AnimatableValue from a string.
1135:                 */
1136:                public AnimatableValue createValue(AnimationTarget target,
1137:                        String ns, String ln, boolean isCSS, String s) {
1138:                    return new AnimatableNumberValue(target, Float
1139:                            .parseFloat(s));
1140:                }
1141:
1142:                /**
1143:                 * Creates a new AnimatableValue from a CSS {@link Value}.
1144:                 */
1145:                public AnimatableValue createValue(AnimationTarget target,
1146:                        String pn, Value v) {
1147:                    return new AnimatableNumberValue(target, v.getFloatValue());
1148:                }
1149:            }
1150:
1151:            /**
1152:             * Factory class for {@link AnimatableNumberOrPercentageValue}s.
1153:             */
1154:            protected class AnimatableNumberOrPercentageValueFactory implements 
1155:                    Factory {
1156:
1157:                /**
1158:                 * Creates a new AnimatableValue from a string.
1159:                 */
1160:                public AnimatableValue createValue(AnimationTarget target,
1161:                        String ns, String ln, boolean isCSS, String s) {
1162:                    float v;
1163:                    boolean pc;
1164:                    if (s.charAt(s.length() - 1) == '%') {
1165:                        v = Float.parseFloat(s.substring(0, s.length() - 1));
1166:                        pc = true;
1167:                    } else {
1168:                        v = Float.parseFloat(s);
1169:                        pc = false;
1170:                    }
1171:                    return new AnimatableNumberOrPercentageValue(target, v, pc);
1172:                }
1173:
1174:                /**
1175:                 * Creates a new AnimatableValue from a CSS {@link Value}.
1176:                 */
1177:                public AnimatableValue createValue(AnimationTarget target,
1178:                        String pn, Value v) {
1179:                    switch (v.getPrimitiveType()) {
1180:                    case CSSPrimitiveValue.CSS_PERCENTAGE:
1181:                        return new AnimatableNumberOrPercentageValue(target, v
1182:                                .getFloatValue(), true);
1183:                    case CSSPrimitiveValue.CSS_NUMBER:
1184:                        return new AnimatableNumberOrPercentageValue(target, v
1185:                                .getFloatValue());
1186:                    }
1187:                    // XXX Do something better than returning null.
1188:                    return null;
1189:                }
1190:            }
1191:
1192:            /**
1193:             * Factory class for {@link AnimatablePreserveAspectRatioValue}s.
1194:             */
1195:            protected class AnimatablePreserveAspectRatioValueFactory implements 
1196:                    Factory {
1197:
1198:                /**
1199:                 * The parsed 'align' value.
1200:                 */
1201:                protected short align;
1202:
1203:                /**
1204:                 * The parsed 'meetOrSlice' value.
1205:                 */
1206:                protected short meetOrSlice;
1207:
1208:                /**
1209:                 * Parser for preserveAspectRatio values.
1210:                 */
1211:                protected PreserveAspectRatioParser parser = new PreserveAspectRatioParser();
1212:
1213:                /**
1214:                 * Handler for the preserveAspectRatio parser.
1215:                 */
1216:                protected DefaultPreserveAspectRatioHandler handler = new DefaultPreserveAspectRatioHandler() {
1217:
1218:                    /**
1219:                     * Implements {@link
1220:                     * PreserveAspectRatioHandler#startPreserveAspectRatio()}.
1221:                     */
1222:                    public void startPreserveAspectRatio()
1223:                            throws ParseException {
1224:                        align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_UNKNOWN;
1225:                        meetOrSlice = SVGPreserveAspectRatio.SVG_MEETORSLICE_UNKNOWN;
1226:                    }
1227:
1228:                    /**
1229:                     * Implements {@link PreserveAspectRatioHandler#none()}.
1230:                     */
1231:                    public void none() throws ParseException {
1232:                        align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_NONE;
1233:                    }
1234:
1235:                    /**
1236:                     * Implements {@link PreserveAspectRatioHandler#xMaxYMax()}.
1237:                     */
1238:                    public void xMaxYMax() throws ParseException {
1239:                        align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMAX;
1240:                    }
1241:
1242:                    /**
1243:                     * Implements {@link PreserveAspectRatioHandler#xMaxYMid()}.
1244:                     */
1245:                    public void xMaxYMid() throws ParseException {
1246:                        align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMID;
1247:                    }
1248:
1249:                    /**
1250:                     * Implements {@link PreserveAspectRatioHandler#xMaxYMin()}.
1251:                     */
1252:                    public void xMaxYMin() throws ParseException {
1253:                        align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMAXYMIN;
1254:                    }
1255:
1256:                    /**
1257:                     * Implements {@link PreserveAspectRatioHandler#xMidYMax()}.
1258:                     */
1259:                    public void xMidYMax() throws ParseException {
1260:                        align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMAX;
1261:                    }
1262:
1263:                    /**
1264:                     * Implements {@link PreserveAspectRatioHandler#xMidYMid()}.
1265:                     */
1266:                    public void xMidYMid() throws ParseException {
1267:                        align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMID;
1268:                    }
1269:
1270:                    /**
1271:                     * Implements {@link PreserveAspectRatioHandler#xMidYMin()}.
1272:                     */
1273:                    public void xMidYMin() throws ParseException {
1274:                        align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMIN;
1275:                    }
1276:
1277:                    /**
1278:                     * Implements {@link PreserveAspectRatioHandler#xMinYMax()}.
1279:                     */
1280:                    public void xMinYMax() throws ParseException {
1281:                        align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMAX;
1282:                    }
1283:
1284:                    /**
1285:                     * Implements {@link PreserveAspectRatioHandler#xMinYMid()}.
1286:                     */
1287:                    public void xMinYMid() throws ParseException {
1288:                        align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMID;
1289:                    }
1290:
1291:                    /**
1292:                     * Implements {@link PreserveAspectRatioHandler#xMinYMin()}.
1293:                     */
1294:                    public void xMinYMin() throws ParseException {
1295:                        align = SVGPreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMINYMIN;
1296:                    }
1297:
1298:                    /**
1299:                     * Implements {@link PreserveAspectRatioHandler#meet()}.
1300:                     */
1301:                    public void meet() throws ParseException {
1302:                        meetOrSlice = SVGPreserveAspectRatio.SVG_MEETORSLICE_MEET;
1303:                    }
1304:
1305:                    /**
1306:                     * Implements {@link PreserveAspectRatioHandler#slice()}.
1307:                     */
1308:                    public void slice() throws ParseException {
1309:                        meetOrSlice = SVGPreserveAspectRatio.SVG_MEETORSLICE_SLICE;
1310:                    }
1311:                };
1312:
1313:                /**
1314:                 * Creates a new AnimatablePreserveAspectRatioValueFactory.
1315:                 */
1316:                public AnimatablePreserveAspectRatioValueFactory() {
1317:                    parser.setPreserveAspectRatioHandler(handler);
1318:                }
1319:
1320:                /**
1321:                 * Creates a new AnimatableValue from a string.
1322:                 */
1323:                public AnimatableValue createValue(AnimationTarget target,
1324:                        String ns, String ln, boolean isCSS, String s) {
1325:                    try {
1326:                        parser.parse(s);
1327:                        return new AnimatablePreserveAspectRatioValue(target,
1328:                                align, meetOrSlice);
1329:                    } catch (ParseException e) {
1330:                        // XXX Do something better than returning null.
1331:                        return null;
1332:                    }
1333:                }
1334:
1335:                /**
1336:                 * Creates a new AnimatableValue from a CSS {@link Value}.  Returns null
1337:                 * since preserveAspectRatio values aren't used in CSS values.
1338:                 */
1339:                public AnimatableValue createValue(AnimationTarget target,
1340:                        String pn, Value v) {
1341:                    return null;
1342:                }
1343:            }
1344:
1345:            /**
1346:             * Factory class for {@link AnimatableLengthValue}s.
1347:             */
1348:            protected class AnimatableLengthValueFactory implements  Factory {
1349:
1350:                /**
1351:                 * The parsed length unit type.
1352:                 */
1353:                protected short type;
1354:
1355:                /**
1356:                 * The parsed length value.
1357:                 */
1358:                protected float value;
1359:
1360:                /**
1361:                 * Parser for lengths.
1362:                 */
1363:                protected LengthParser parser = new LengthParser();
1364:
1365:                /**
1366:                 * Handler for the length parser.
1367:                 */
1368:                protected LengthHandler handler = new DefaultLengthHandler() {
1369:                    public void startLength() throws ParseException {
1370:                        type = SVGLength.SVG_LENGTHTYPE_NUMBER;
1371:                    }
1372:
1373:                    public void lengthValue(float v) throws ParseException {
1374:                        value = v;
1375:                    }
1376:
1377:                    public void em() throws ParseException {
1378:                        type = SVGLength.SVG_LENGTHTYPE_EMS;
1379:                    }
1380:
1381:                    public void ex() throws ParseException {
1382:                        type = SVGLength.SVG_LENGTHTYPE_EXS;
1383:                    }
1384:
1385:                    public void in() throws ParseException {
1386:                        type = SVGLength.SVG_LENGTHTYPE_IN;
1387:                    }
1388:
1389:                    public void cm() throws ParseException {
1390:                        type = SVGLength.SVG_LENGTHTYPE_CM;
1391:                    }
1392:
1393:                    public void mm() throws ParseException {
1394:                        type = SVGLength.SVG_LENGTHTYPE_MM;
1395:                    }
1396:
1397:                    public void pc() throws ParseException {
1398:                        type = SVGLength.SVG_LENGTHTYPE_PC;
1399:                    }
1400:
1401:                    public void pt() throws ParseException {
1402:                        type = SVGLength.SVG_LENGTHTYPE_PT;
1403:                    }
1404:
1405:                    public void px() throws ParseException {
1406:                        type = SVGLength.SVG_LENGTHTYPE_PX;
1407:                    }
1408:
1409:                    public void percentage() throws ParseException {
1410:                        type = SVGLength.SVG_LENGTHTYPE_PERCENTAGE;
1411:                    }
1412:
1413:                    public void endLength() throws ParseException {
1414:                    }
1415:                };
1416:
1417:                /**
1418:                 * Creates a new AnimatableLengthValueFactory.
1419:                 */
1420:                public AnimatableLengthValueFactory() {
1421:                    parser.setLengthHandler(handler);
1422:                }
1423:
1424:                /**
1425:                 * Creates a new AnimatableValue from a string.
1426:                 */
1427:                public AnimatableValue createValue(AnimationTarget target,
1428:                        String ns, String ln, boolean isCSS, String s) {
1429:                    short pcInterp = target.getPercentageInterpretation(ns, ln,
1430:                            isCSS);
1431:                    try {
1432:                        parser.parse(s);
1433:                        return new AnimatableLengthValue(target, type, value,
1434:                                pcInterp);
1435:                    } catch (ParseException e) {
1436:                        // XXX Do something better than returning null.
1437:                        return null;
1438:                    }
1439:                }
1440:
1441:                /**
1442:                 * Creates a new AnimatableValue from a CSS {@link Value}.
1443:                 */
1444:                public AnimatableValue createValue(AnimationTarget target,
1445:                        String pn, Value v) {
1446:                    return new AnimatableIntegerValue(target, Math.round(v
1447:                            .getFloatValue()));
1448:                }
1449:            }
1450:
1451:            /**
1452:             * Factory class for {@link AnimatableLengthListValue}s.
1453:             */
1454:            protected class AnimatableLengthListValueFactory implements  Factory {
1455:
1456:                /**
1457:                 * Parser for length lists.
1458:                 */
1459:                protected LengthListParser parser = new LengthListParser();
1460:
1461:                /**
1462:                 * The producer class that accumulates the lengths.
1463:                 */
1464:                protected LengthArrayProducer producer = new LengthArrayProducer();
1465:
1466:                /**
1467:                 * Creates a new AnimatableLengthListValueFactory.
1468:                 */
1469:                public AnimatableLengthListValueFactory() {
1470:                    parser.setLengthListHandler(producer);
1471:                }
1472:
1473:                /**
1474:                 * Creates a new AnimatableValue from a string.
1475:                 */
1476:                public AnimatableValue createValue(AnimationTarget target,
1477:                        String ns, String ln, boolean isCSS, String s) {
1478:                    try {
1479:                        short pcInterp = target.getPercentageInterpretation(ns,
1480:                                ln, isCSS);
1481:                        parser.parse(s);
1482:                        return new AnimatableLengthListValue(target, producer
1483:                                .getLengthTypeArray(), producer
1484:                                .getLengthValueArray(), pcInterp);
1485:                    } catch (ParseException e) {
1486:                        // XXX Do something better than returning null.
1487:                        return null;
1488:                    }
1489:                }
1490:
1491:                /**
1492:                 * Creates a new AnimatableValue from a CSS {@link Value}.  Returns null
1493:                 * since point lists aren't used in CSS values.
1494:                 */
1495:                public AnimatableValue createValue(AnimationTarget target,
1496:                        String pn, Value v) {
1497:                    return null;
1498:                }
1499:            }
1500:
1501:            /**
1502:             * Factory class for {@link AnimatableNumberListValue}s.
1503:             */
1504:            protected class AnimatableNumberListValueFactory implements  Factory {
1505:
1506:                /**
1507:                 * Parser for number lists.
1508:                 */
1509:                protected NumberListParser parser = new NumberListParser();
1510:
1511:                /**
1512:                 * The producer class that accumulates the numbers.
1513:                 */
1514:                protected FloatArrayProducer producer = new FloatArrayProducer();
1515:
1516:                /**
1517:                 * Creates a new AnimatableNumberListValueFactory.
1518:                 */
1519:                public AnimatableNumberListValueFactory() {
1520:                    parser.setNumberListHandler(producer);
1521:                }
1522:
1523:                /**
1524:                 * Creates a new AnimatableValue from a string.
1525:                 */
1526:                public AnimatableValue createValue(AnimationTarget target,
1527:                        String ns, String ln, boolean isCSS, String s) {
1528:                    try {
1529:                        parser.parse(s);
1530:                        return new AnimatableNumberListValue(target, producer
1531:                                .getFloatArray());
1532:                    } catch (ParseException e) {
1533:                        // XXX Do something better than returning null.
1534:                        return null;
1535:                    }
1536:                }
1537:
1538:                /**
1539:                 * Creates a new AnimatableValue from a CSS {@link Value}.  Returns null
1540:                 * since number lists aren't used in CSS values.
1541:                 */
1542:                public AnimatableValue createValue(AnimationTarget target,
1543:                        String pn, Value v) {
1544:                    return null;
1545:                }
1546:            }
1547:
1548:            /**
1549:             * Factory class for {@link AnimatablePointListValue}s.
1550:             */
1551:            protected class AnimatablePointListValueFactory implements  Factory {
1552:
1553:                /**
1554:                 * Parser for point lists.
1555:                 */
1556:                protected PointsParser parser = new PointsParser();
1557:
1558:                /**
1559:                 * The producer class that accumulates the points.
1560:                 */
1561:                protected FloatArrayProducer producer = new FloatArrayProducer();
1562:
1563:                /**
1564:                 * Creates a new AnimatablePointListValueFactory.
1565:                 */
1566:                public AnimatablePointListValueFactory() {
1567:                    parser.setPointsHandler(producer);
1568:                }
1569:
1570:                /**
1571:                 * Creates a new AnimatableValue from a string.
1572:                 */
1573:                public AnimatableValue createValue(AnimationTarget target,
1574:                        String ns, String ln, boolean isCSS, String s) {
1575:                    try {
1576:                        parser.parse(s);
1577:                        return new AnimatablePointListValue(target, producer
1578:                                .getFloatArray());
1579:                    } catch (ParseException e) {
1580:                        // XXX Do something better than returning null.
1581:                        return null;
1582:                    }
1583:                }
1584:
1585:                /**
1586:                 * Creates a new AnimatableValue from a CSS {@link Value}.  Returns null
1587:                 * since point lists aren't used in CSS values.
1588:                 */
1589:                public AnimatableValue createValue(AnimationTarget target,
1590:                        String pn, Value v) {
1591:                    return null;
1592:                }
1593:            }
1594:
1595:            /**
1596:             * Factory class for {@link AnimatablePathDataValue}s.
1597:             */
1598:            protected class AnimatablePathDataFactory implements  Factory {
1599:
1600:                /**
1601:                 * Parser for path data.
1602:                 */
1603:                protected PathParser parser = new PathParser();
1604:
1605:                /**
1606:                 * The producer class that accumulates the path segments.
1607:                 */
1608:                protected PathArrayProducer producer = new PathArrayProducer();
1609:
1610:                /**
1611:                 * Creates a new AnimatablePathDataFactory.
1612:                 */
1613:                public AnimatablePathDataFactory() {
1614:                    parser.setPathHandler(producer);
1615:                }
1616:
1617:                /**
1618:                 * Creates a new AnimatableValue from a string.
1619:                 */
1620:                public AnimatableValue createValue(AnimationTarget target,
1621:                        String ns, String ln, boolean isCSS, String s) {
1622:                    try {
1623:                        parser.parse(s);
1624:                        return new AnimatablePathDataValue(target, producer
1625:                                .getPathCommands(), producer
1626:                                .getPathParameters());
1627:                    } catch (ParseException e) {
1628:                        // XXX Do something better than returning null.
1629:                        return null;
1630:                    }
1631:                }
1632:
1633:                /**
1634:                 * Creates a new AnimatableValue from a CSS {@link Value}.  Returns null
1635:                 * since point lists aren't used in CSS values.
1636:                 */
1637:                public AnimatableValue createValue(AnimationTarget target,
1638:                        String pn, Value v) {
1639:                    return null;
1640:                }
1641:            }
1642:
1643:            /**
1644:             * Factory class for {@link AnimatableStringValue}s.
1645:             */
1646:            protected class UncomputedAnimatableStringValueFactory implements 
1647:                    Factory {
1648:
1649:                public AnimatableValue createValue(AnimationTarget target,
1650:                        String ns, String ln, boolean isCSS, String s) {
1651:                    return new AnimatableStringValue(target, s);
1652:                }
1653:
1654:                public AnimatableValue createValue(AnimationTarget target,
1655:                        String pn, Value v) {
1656:                    return new AnimatableStringValue(target, v.getCssText());
1657:                }
1658:            }
1659:
1660:            /**
1661:             * Factory class for {@link AnimatableLengthOrIdentValue}s.
1662:             */
1663:            protected class AnimatableLengthOrIdentFactory extends
1664:                    CSSValueFactory {
1665:
1666:                protected AnimatableValue createAnimatableValue(
1667:                        AnimationTarget target, String pn, Value v) {
1668:                    if (v instanceof  StringValue) {
1669:                        return new AnimatableLengthOrIdentValue(target, v
1670:                                .getStringValue());
1671:                    }
1672:                    short pcInterp = target.getPercentageInterpretation(null,
1673:                            pn, true);
1674:                    FloatValue fv = (FloatValue) v;
1675:                    return new AnimatableLengthOrIdentValue(target, fv
1676:                            .getPrimitiveType(), fv.getFloatValue(), pcInterp);
1677:                }
1678:            }
1679:
1680:            /**
1681:             * Factory class for {@link AnimatableNumberOrIdentValue}s.
1682:             */
1683:            protected class AnimatableNumberOrIdentFactory extends
1684:                    CSSValueFactory {
1685:
1686:                /**
1687:                 * Whether numbers are actually numeric keywords, as with the
1688:                 * font-weight property.
1689:                 */
1690:                protected boolean numericIdents;
1691:
1692:                public AnimatableNumberOrIdentFactory(boolean numericIdents) {
1693:                    this .numericIdents = numericIdents;
1694:                }
1695:
1696:                protected AnimatableValue createAnimatableValue(
1697:                        AnimationTarget target, String pn, Value v) {
1698:                    if (v instanceof  StringValue) {
1699:                        return new AnimatableNumberOrIdentValue(target, v
1700:                                .getStringValue());
1701:                    }
1702:                    FloatValue fv = (FloatValue) v;
1703:                    return new AnimatableNumberOrIdentValue(target, fv
1704:                            .getFloatValue(), numericIdents);
1705:                }
1706:            }
1707:
1708:            /**
1709:             * Factory class for {@link AnimatableAngleValue}s.
1710:             */
1711:            protected class AnimatableAngleValueFactory extends CSSValueFactory {
1712:
1713:                protected AnimatableValue createAnimatableValue(
1714:                        AnimationTarget target, String pn, Value v) {
1715:                    FloatValue fv = (FloatValue) v;
1716:                    short unit;
1717:                    switch (fv.getPrimitiveType()) {
1718:                    case CSSPrimitiveValue.CSS_NUMBER:
1719:                    case CSSPrimitiveValue.CSS_DEG:
1720:                        unit = SVGAngle.SVG_ANGLETYPE_DEG;
1721:                        break;
1722:                    case CSSPrimitiveValue.CSS_RAD:
1723:                        unit = SVGAngle.SVG_ANGLETYPE_RAD;
1724:                        break;
1725:                    case CSSPrimitiveValue.CSS_GRAD:
1726:                        unit = SVGAngle.SVG_ANGLETYPE_GRAD;
1727:                        break;
1728:                    default:
1729:                        // XXX Do something better than returning null.
1730:                        return null;
1731:                    }
1732:                    return new AnimatableAngleValue(target, fv.getFloatValue(),
1733:                            unit);
1734:                }
1735:            }
1736:
1737:            /**
1738:             * Factory class for {@link AnimatableAngleOrIdentValue}s.
1739:             */
1740:            protected class AnimatableAngleOrIdentFactory extends
1741:                    CSSValueFactory {
1742:
1743:                protected AnimatableValue createAnimatableValue(
1744:                        AnimationTarget target, String pn, Value v) {
1745:                    if (v instanceof  StringValue) {
1746:                        return new AnimatableAngleOrIdentValue(target, v
1747:                                .getStringValue());
1748:                    }
1749:                    FloatValue fv = (FloatValue) v;
1750:                    short unit;
1751:                    switch (fv.getPrimitiveType()) {
1752:                    case CSSPrimitiveValue.CSS_NUMBER:
1753:                    case CSSPrimitiveValue.CSS_DEG:
1754:                        unit = SVGAngle.SVG_ANGLETYPE_DEG;
1755:                        break;
1756:                    case CSSPrimitiveValue.CSS_RAD:
1757:                        unit = SVGAngle.SVG_ANGLETYPE_RAD;
1758:                        break;
1759:                    case CSSPrimitiveValue.CSS_GRAD:
1760:                        unit = SVGAngle.SVG_ANGLETYPE_GRAD;
1761:                        break;
1762:                    default:
1763:                        // XXX Do something better than returning null.
1764:                        return null;
1765:                    }
1766:                    return new AnimatableAngleOrIdentValue(target, fv
1767:                            .getFloatValue(), unit);
1768:                }
1769:            }
1770:
1771:            /**
1772:             * Factory class for {@link AnimatableColorValue}s.
1773:             */
1774:            protected class AnimatableColorValueFactory extends CSSValueFactory {
1775:
1776:                protected AnimatableValue createAnimatableValue(
1777:                        AnimationTarget target, String pn, Value v) {
1778:                    Paint p = PaintServer.convertPaint(target.getElement(),
1779:                            null, v, 1.0f, ctx);
1780:                    if (p instanceof  Color) {
1781:                        Color c = (Color) p;
1782:                        return new AnimatableColorValue(target,
1783:                                c.getRed() / 255f, c.getGreen() / 255f, c
1784:                                        .getBlue() / 255f);
1785:                    }
1786:                    // XXX Indicate that the parsed value wasn't a Color?
1787:                    return null;
1788:                }
1789:            }
1790:
1791:            /**
1792:             * Factory class for {@link AnimatablePaintValue}s.
1793:             */
1794:            protected class AnimatablePaintValueFactory extends CSSValueFactory {
1795:
1796:                /**
1797:                 * Creates a new {@link AnimatablePaintValue} from a {@link Color}
1798:                 * object.
1799:                 */
1800:                protected AnimatablePaintValue createColorPaintValue(
1801:                        AnimationTarget t, Color c) {
1802:                    return AnimatablePaintValue.createColorPaintValue(t, c
1803:                            .getRed() / 255f, c.getGreen() / 255f,
1804:                            c.getBlue() / 255f);
1805:
1806:                }
1807:
1808:                protected AnimatableValue createAnimatableValue(
1809:                        AnimationTarget target, String pn, Value v) {
1810:                    if (v.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) {
1811:                        switch (v.getPrimitiveType()) {
1812:                        case CSSPrimitiveValue.CSS_IDENT:
1813:                            return AnimatablePaintValue
1814:                                    .createNonePaintValue(target);
1815:                        case CSSPrimitiveValue.CSS_RGBCOLOR: {
1816:                            Paint p = PaintServer.convertPaint(target
1817:                                    .getElement(), null, v, 1.0f, ctx);
1818:                            return createColorPaintValue(target, (Color) p);
1819:                        }
1820:                        case CSSPrimitiveValue.CSS_URI:
1821:                            return AnimatablePaintValue.createURIPaintValue(
1822:                                    target, v.getStringValue());
1823:                        }
1824:                    } else {
1825:                        Value v1 = v.item(0);
1826:                        switch (v1.getPrimitiveType()) {
1827:                        case CSSPrimitiveValue.CSS_RGBCOLOR: {
1828:                            Paint p = PaintServer.convertPaint(target
1829:                                    .getElement(), null, v, 1.0f, ctx);
1830:                            return createColorPaintValue(target, (Color) p);
1831:                        }
1832:                        case CSSPrimitiveValue.CSS_URI: {
1833:                            Value v2 = v.item(1);
1834:                            switch (v2.getPrimitiveType()) {
1835:                            case CSSPrimitiveValue.CSS_IDENT:
1836:                                return AnimatablePaintValue
1837:                                        .createURINonePaintValue(target, v1
1838:                                                .getStringValue());
1839:                            case CSSPrimitiveValue.CSS_RGBCOLOR: {
1840:                                Paint p = PaintServer.convertPaint(target
1841:                                        .getElement(), null, v.item(1), 1.0f,
1842:                                        ctx);
1843:                                return createColorPaintValue(target, (Color) p);
1844:                            }
1845:                            }
1846:                        }
1847:                        }
1848:                    }
1849:                    // XXX Indicate that the specified Value wasn't a Color?
1850:                    return null;
1851:                }
1852:            }
1853:
1854:            /**
1855:             * Factory class for computed CSS {@link AnimatableStringValue}s.
1856:             */
1857:            protected class AnimatableStringValueFactory extends
1858:                    CSSValueFactory {
1859:
1860:                protected AnimatableValue createAnimatableValue(
1861:                        AnimationTarget target, String pn, Value v) {
1862:                    return new AnimatableStringValue(target, v.getCssText());
1863:                }
1864:            }
1865:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.