Source Code Cross Referenced for StructureNode.java in  » 6.0-JDK-Modules » j2me » com » sun » perseus » model » 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 » 6.0 JDK Modules » j2me » com.sun.perseus.model 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *
0003:         *
0004:         * Copyright  1990-2007 Sun Microsystems, Inc. All Rights Reserved.
0005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
0006:         * 
0007:         * This program is free software; you can redistribute it and/or
0008:         * modify it under the terms of the GNU General Public License version
0009:         * 2 only, as published by the Free Software Foundation.
0010:         * 
0011:         * This program is distributed in the hope that it will be useful, but
0012:         * WITHOUT ANY WARRANTY; without even the implied warranty of
0013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0014:         * General Public License version 2 for more details (a copy is
0015:         * included at /legal/license.txt).
0016:         * 
0017:         * You should have received a copy of the GNU General Public License
0018:         * version 2 along with this work; if not, write to the Free Software
0019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0020:         * 02110-1301 USA
0021:         * 
0022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
0023:         * Clara, CA 95054 or visit www.sun.com if you need additional
0024:         * information or have any questions.
0025:         */
0026:        package com.sun.perseus.model;
0027:
0028:        import com.sun.perseus.j2d.Box;
0029:        import com.sun.perseus.j2d.RenderGraphics;
0030:        import com.sun.perseus.j2d.TextProperties;
0031:        import com.sun.perseus.j2d.TextRenderingProperties;
0032:        import com.sun.perseus.util.SVGConstants;
0033:
0034:        import org.w3c.dom.DOMException;
0035:        import org.w3c.dom.svg.SVGRect;
0036:
0037:        import com.sun.perseus.j2d.Transform;
0038:
0039:        /**
0040:         * <code>StructureNode</code> is the base class for all nodes that
0041:         * represent structure content, such as images, defs or svg elements.
0042:         *
0043:         * @version $Id: StructureNode.java,v 1.8 2006/06/29 10:47:35 ln156897 Exp $
0044:         */
0045:        public abstract class StructureNode extends CompositeGraphicsNode
0046:                implements  TextNode, TextRenderingProperties {
0047:            /**
0048:             * Marker used to mark that the fontWeight property was set to bolder.
0049:             */
0050:            public static final int FONT_WEIGHT_BOLDER_MARKER = 1 << 23;
0051:
0052:            /**
0053:             * Marker used to mark that the fontWeight property was set to lighter.
0054:             */
0055:            public static final int FONT_WEIGHT_LIGHTER_MARKER = 1 << 24;
0056:
0057:            /**
0058:             * When align is set to ALIGN_NONE, the SVG content
0059:             * is rescaled so that the widht and height of the 
0060:             * viewBox map to the viewport width and height and 
0061:             * the origin of the viewBox maps to the viewport 
0062:             * origin.
0063:             */
0064:            public static final int ALIGN_NONE = 0;
0065:
0066:            /**
0067:             * When align is set to ALIGN_XMIDYMID, the SVG 
0068:             * content is rescaled so that the aspect ratio
0069:             * of the viewBox is preserved. With that constraint,
0070:             * either the width or height of the viewBox is
0071:             * mapped to the width or height of the viewPort.
0072:             * The rescaled content is centered into the viewport.
0073:             */
0074:            public static final int ALIGN_XMIDYMID = 1;
0075:
0076:            // ====================================================================
0077:            // Properties
0078:            // ====================================================================
0079:            /**
0080:             * Controls this node's fontFamily
0081:             */
0082:            protected String[] fontFamily = INITIAL_FONT_FAMILY;
0083:
0084:            /**
0085:             * Controls this node's fontSize
0086:             */
0087:            protected float fontSize = INITIAL_FONT_SIZE;
0088:
0089:            /**
0090:             * Constructor.
0091:             *
0092:             * @param ownerDocument this element's owner <code>DocumentNode</code>
0093:             */
0094:            public StructureNode(final DocumentNode ownerDocument) {
0095:                super (ownerDocument);
0096:            }
0097:
0098:            /**
0099:             * @param bbox the bounding box to which this node's bounding box should be
0100:             *        appended. That bounding box is in the target coordinate space. It 
0101:             *        may be null, in which case this node should create a new one.
0102:             * @param t the transform to apply from the node's coordinate space to the
0103:             *        target coordinate space. May be null for the identity 
0104:             *        transform.
0105:             * @return the node's bounding box in the target coordinate space.
0106:             */
0107:            Box addBBox(Box bbox, final Transform t) {
0108:                ModelNode c = getFirstChildNode();
0109:                while (c != null) {
0110:                    if (c.contributeBBox()) {
0111:                        bbox = c.addBBox(bbox, c.appendTransform(t, null));
0112:                    }
0113:                    c = c.nextSibling;
0114:                }
0115:
0116:                return bbox;
0117:            }
0118:
0119:            /**
0120:             * @return the tight bounding box in current user coordinate
0121:             * space. 
0122:             */
0123:            public SVGRect getBBox() {
0124:                return addBBox(null, null);
0125:            }
0126:
0127:            /**
0128:             * @return the tight bounding box in screen coordinate space.
0129:             */
0130:            public SVGRect getScreenBBox() {
0131:                // There is no screen bounding box if the element is not hooked
0132:                // into the main tree.
0133:                if (!inDocumentTree()) {
0134:                    return null;
0135:                }
0136:
0137:                return addBBox(null, txf);
0138:            }
0139:
0140:            /**
0141:             * Returns the <code>ModelNode</code>, if any, hit by the
0142:             * point at coordinate x/y. 
0143:             * 
0144:             * @param pt the x/y coordinate. Should never be null and be
0145:             *        of size two. If not, the behavior is unspecified.
0146:             *        The coordinates are in viewport space.
0147:             * @return the <tt>ModelNode</tt> hit at the given point or null
0148:             *         if none was hit.
0149:             */
0150:            public ModelNode nodeHitAt(final float[] pt) {
0151:                // If a node does not render, it is never hit
0152:                if (canRenderState != 0) {
0153:                    return null;
0154:                }
0155:
0156:                // Check for a hit on children
0157:                return nodeHitAt(getLastChildNode(), pt);
0158:            }
0159:
0160:            /**
0161:             * Returns the <code>ModelNode</code>, if any, hit by the
0162:             * point at coordinate x/y in the proxy tree starting at 
0163:             * proxy.
0164:             * 
0165:             * @param pt the x/y coordinate. Should never be null and be
0166:             *        of size two. If not, the behavior is unspecified.
0167:             *        The coordinates are in viewport space.
0168:             * @param proxy the root of the proxy tree to test.
0169:             * @return the <tt>ModelNode</tt> hit at the given point or null
0170:             *         if none was hit.
0171:             */
0172:            ModelNode proxyNodeHitAt(final float[] pt,
0173:                    final ElementNodeProxy proxy) {
0174:                // If a node does not render, it is never hit
0175:                if (canRenderState != 0) {
0176:                    return null;
0177:                }
0178:
0179:                // Check for a hit on expanded children
0180:                return nodeHitAt(proxy.getLastExpandedChild(), pt);
0181:            }
0182:
0183:            /**
0184:             * @return the number of properties supported by this node
0185:             */
0186:            public int getNumberOfProperties() {
0187:                return GraphicsNode.NUMBER_OF_PROPERTIES
0188:                        + TextNode.NUMBER_OF_PROPERTIES;
0189:            }
0190:
0191:            /**
0192:             * Recomputes all inherited properties.
0193:             */
0194:            void recomputeInheritedProperties() {
0195:                super .recomputeInheritedProperties();
0196:                ModelNode p = ownerDocument;
0197:                if (parent != null) {
0198:                    p = parent;
0199:                }
0200:                recomputePropertyState(PROPERTY_FONT_FAMILY, p
0201:                        .getPropertyState(PROPERTY_FONT_FAMILY));
0202:                recomputeFloatPropertyState(PROPERTY_FONT_SIZE, p
0203:                        .getFloatPropertyState(PROPERTY_FONT_SIZE));
0204:                recomputePackedPropertyState(PROPERTY_FONT_STYLE, p
0205:                        .getPackedPropertyState(PROPERTY_FONT_STYLE));
0206:                recomputePackedPropertyState(PROPERTY_FONT_WEIGHT, p
0207:                        .getPackedPropertyState(PROPERTY_FONT_WEIGHT));
0208:                recomputePackedPropertyState(PROPERTY_TEXT_ANCHOR, p
0209:                        .getPackedPropertyState(PROPERTY_TEXT_ANCHOR));
0210:            }
0211:
0212:            /**
0213:             * Recomputes the given packed property's state given the new parent 
0214:             * property.
0215:             *
0216:             * @param propertyIndex index for the property whose value is changing.
0217:             * @param parentPropertyValue the value that children of this node should 
0218:             *        now inherit.
0219:             * 
0220:             */
0221:            protected void recomputePackedPropertyState(
0222:                    final int propertyIndex, final int parentPropertyValue) {
0223:                if (propertyIndex != PROPERTY_FONT_WEIGHT) {
0224:                    super .recomputePackedPropertyState(propertyIndex,
0225:                            parentPropertyValue);
0226:                } else {
0227:                    // We do not need to recompute the fontWeight value if:
0228:                    // - the fontWeight is _not_ inherited & not relative (i.e. lighter
0229:                    //   or bolder)
0230:                    // or
0231:                    // - the property is inherited but the new parent property computed
0232:                    //   value is the same as the current value & the bolder and lighter
0233:                    //   markes are in the same state
0234:                    boolean isBolder = isMarkerSet(FONT_WEIGHT_BOLDER_MARKER);
0235:                    boolean isLighter = isMarkerSet(FONT_WEIGHT_LIGHTER_MARKER);
0236:                    if ((!isInherited(propertyIndex) && !isBolder && !isLighter)
0237:                            || isPackedPropertyState(propertyIndex,
0238:                                    parentPropertyValue)) {
0239:                        return;
0240:                    }
0241:
0242:                    int packedFontWeight = parentPropertyValue;
0243:                    if (isBolder) {
0244:                        packedFontWeight = computeFontWeight(
0245:                                parentPropertyValue, FONT_WEIGHT_BOLDER);
0246:                    } else if (isLighter) {
0247:                        packedFontWeight = computeFontWeight(
0248:                                parentPropertyValue, FONT_WEIGHT_LIGHTER);
0249:                    }
0250:
0251:                    setPackedPropertyState(propertyIndex, packedFontWeight);
0252:
0253:                    propagatePackedPropertyState(propertyIndex,
0254:                            parentPropertyValue);
0255:                }
0256:            }
0257:
0258:            /**
0259:             * Returns the value for the given property.
0260:             *
0261:             * @return the value for the given property.
0262:             */
0263:            protected Object getPropertyState(final int propertyIndex) {
0264:                switch (propertyIndex) {
0265:                case PROPERTY_FONT_FAMILY:
0266:                    return fontFamily;
0267:                default:
0268:                    return super .getPropertyState(propertyIndex);
0269:                }
0270:            }
0271:
0272:            /**
0273:             * Returns the value for the given float property.
0274:             *
0275:             * @return the value for the given property.
0276:             */
0277:            protected float getFloatPropertyState(final int propertyIndex) {
0278:                switch (propertyIndex) {
0279:                case PROPERTY_FONT_SIZE:
0280:                    return fontSize;
0281:                default:
0282:                    return super .getFloatPropertyState(propertyIndex);
0283:                }
0284:            }
0285:
0286:            /**
0287:             * Returns the value for the given packed property.
0288:             *
0289:             * @return the value for the given packed property.
0290:             */
0291:            protected int getPackedPropertyState(final int propertyIndex) {
0292:                switch (propertyIndex) {
0293:                case TextNode.PROPERTY_FONT_STYLE:
0294:                    return pack & StructureNode.FONT_STYLE_MASK;
0295:                case TextNode.PROPERTY_FONT_WEIGHT:
0296:                    return pack & StructureNode.FONT_WEIGHT_MASK;
0297:                case TextNode.PROPERTY_TEXT_ANCHOR:
0298:                    return pack & StructureNode.TEXT_ANCHOR_MASK;
0299:                default:
0300:                    return super .getPackedPropertyState(propertyIndex);
0301:                }
0302:            }
0303:
0304:            /**
0305:             * Sets the computed value for the given property.
0306:             *
0307:             * @param propertyIndex the property index
0308:             * @param propertyValue the computed value for the property.
0309:             */
0310:            protected void setPropertyState(final int propertyIndex,
0311:                    final Object propertyValue) {
0312:                switch (propertyIndex) {
0313:                case PROPERTY_FONT_FAMILY:
0314:                    setComputedFontFamily((String[]) propertyValue);
0315:                    break;
0316:                default:
0317:                    super .setPropertyState(propertyIndex, propertyValue);
0318:                }
0319:            }
0320:
0321:            /**
0322:             * Sets the computed value for the given float property.
0323:             *
0324:             * @param propertyIndex the property index
0325:             * @param propertyValue the computed value for the property.
0326:             */
0327:            protected void setFloatPropertyState(final int propertyIndex,
0328:                    final float propertyValue) {
0329:                switch (propertyIndex) {
0330:                case PROPERTY_FONT_SIZE:
0331:                    setComputedFontSize(propertyValue);
0332:                    break;
0333:                default:
0334:                    super .setFloatPropertyState(propertyIndex, propertyValue);
0335:                }
0336:            }
0337:
0338:            /**
0339:             * Sets the computed value for the given packed property.
0340:             *
0341:             * @param propertyIndex the property index
0342:             * @param propertyValue the computed value for the property.
0343:             */
0344:            protected void setPackedPropertyState(final int propertyIndex,
0345:                    final int propertyValue) {
0346:                switch (propertyIndex) {
0347:                case PROPERTY_FONT_STYLE:
0348:                    switch (propertyValue) {
0349:                    case FONT_STYLE_NORMAL_IMPL:
0350:                        setComputedFontStyle(FONT_STYLE_NORMAL);
0351:                        break;
0352:                    case FONT_STYLE_ITALIC_IMPL:
0353:                        setComputedFontStyle(FONT_STYLE_ITALIC);
0354:                        break;
0355:                    case FONT_STYLE_OBLIQUE_IMPL:
0356:                    default:
0357:                        setComputedFontStyle(FONT_STYLE_OBLIQUE);
0358:                        break;
0359:                    }
0360:                    break;
0361:                case PROPERTY_FONT_WEIGHT:
0362:                    setComputedFontWeight(propertyValue);
0363:                    break;
0364:                case PROPERTY_TEXT_ANCHOR:
0365:                    switch (propertyValue) {
0366:                    case TEXT_ANCHOR_START_IMPL:
0367:                        setComputedTextAnchor(TEXT_ANCHOR_START);
0368:                        break;
0369:                    case TEXT_ANCHOR_MIDDLE_IMPL:
0370:                        setComputedTextAnchor(TEXT_ANCHOR_MIDDLE);
0371:                        break;
0372:                    case TEXT_ANCHOR_END_IMPL:
0373:                    default:
0374:                        setComputedTextAnchor(TEXT_ANCHOR_END);
0375:                        break;
0376:                    }
0377:                    break;
0378:                default:
0379:                    super .setPackedPropertyState(propertyIndex, propertyValue);
0380:                }
0381:            }
0382:
0383:            /**
0384:             * Checks the state of the property value.
0385:             *
0386:             * @param propertyIndex the property index
0387:             * @param propertyValue the computed value for the property.
0388:             */
0389:            protected boolean isPropertyState(final int propertyIndex,
0390:                    final Object propertyValue) {
0391:                switch (propertyIndex) {
0392:                case TextNode.PROPERTY_FONT_FAMILY:
0393:                    return fontFamily == propertyValue;
0394:                default:
0395:                    return super .isPropertyState(propertyIndex, propertyValue);
0396:                }
0397:            }
0398:
0399:            /**
0400:             * Checks the state of the float property value.
0401:             *
0402:             * @param propertyIndex the property index
0403:             * @param propertyValue the computed value for the property.
0404:             */
0405:            protected boolean isFloatPropertyState(final int propertyIndex,
0406:                    final float propertyValue) {
0407:                switch (propertyIndex) {
0408:                case TextNode.PROPERTY_FONT_SIZE:
0409:                    return fontSize == propertyValue;
0410:                default:
0411:                    return super .isFloatPropertyState(propertyIndex,
0412:                            propertyValue);
0413:                }
0414:            }
0415:
0416:            /**
0417:             * Checks the state of the property value.
0418:             *
0419:             * @param propertyIndex the property index
0420:             * @param propertyValue the computed value for the property.
0421:             */
0422:            protected boolean isPackedPropertyState(final int propertyIndex,
0423:                    final int propertyValue) {
0424:                switch (propertyIndex) {
0425:                case TextNode.PROPERTY_FONT_STYLE:
0426:                    return (propertyValue == (pack & StructureNode.FONT_STYLE_MASK));
0427:                case TextNode.PROPERTY_FONT_WEIGHT:
0428:                    return (propertyValue == (pack & StructureNode.FONT_WEIGHT_MASK));
0429:                case TextNode.PROPERTY_TEXT_ANCHOR:
0430:                    return (propertyValue == (pack & StructureNode.TEXT_ANCHOR_MASK));
0431:                default:
0432:                    return super .isPackedPropertyState(propertyIndex,
0433:                            propertyValue);
0434:                }
0435:            }
0436:
0437:            // ====================================================================
0438:            // TextNodeProperties implementation
0439:            // ====================================================================
0440:
0441:            /**
0442:             * @return this node's computed font-family
0443:             */
0444:            public String[] getFontFamily() {
0445:                return fontFamily;
0446:            }
0447:
0448:            /**
0449:             * @param newFontFamily The fontFamily is used when the property is 
0450:             *        not inherited
0451:             */
0452:            public void setFontFamily(final String[] newFontFamily) {
0453:                if (!isInherited(PROPERTY_FONT_FAMILY)
0454:                        && equal(newFontFamily, fontFamily)) {
0455:                    return;
0456:                }
0457:                modifyingNode();
0458:                setInheritedQuiet(PROPERTY_FONT_FAMILY, false);
0459:                setComputedFontFamily(newFontFamily);
0460:                propagatePropertyState(PROPERTY_FONT_FAMILY, newFontFamily);
0461:                modifiedNode();
0462:            }
0463:
0464:            /**
0465:             * @param newFontFamily the new computed font-family property value.
0466:             */
0467:            void setComputedFontFamily(final String[] newFontFamily) {
0468:                this .fontFamily = newFontFamily;
0469:            }
0470:
0471:            /**
0472:             * @return this node's computed fontSize
0473:             */
0474:            public float getFontSize() {
0475:                return fontSize;
0476:            }
0477:
0478:            /**
0479:             * @param newFontSize the fontSize is used when the property is 
0480:             *        not inherited. This should not be less than zero.
0481:             */
0482:            public void setFontSize(final float newFontSize) {
0483:                if (newFontSize < 0) {
0484:                    throw new IllegalArgumentException();
0485:                }
0486:
0487:                if (!isInherited(PROPERTY_FONT_SIZE) && newFontSize == fontSize) {
0488:                    return;
0489:                }
0490:
0491:                modifyingNode();
0492:                setInheritedQuiet(PROPERTY_FONT_SIZE, false);
0493:                setComputedFontSize(newFontSize);
0494:                propagateFloatPropertyState(PROPERTY_FONT_SIZE, newFontSize);
0495:                modifiedNode();
0496:            }
0497:
0498:            /**
0499:             * @param newFontSize the new computed font-size property value.
0500:             */
0501:            void setComputedFontSize(final float newFontSize) {
0502:                this .fontSize = newFontSize;
0503:            }
0504:
0505:            /**
0506:             * @return this node's computed fontStyle
0507:             */
0508:            public int getFontStyle() {
0509:                switch (pack & FONT_STYLE_MASK) {
0510:                case FONT_STYLE_NORMAL_IMPL:
0511:                    return FONT_STYLE_NORMAL;
0512:                case FONT_STYLE_ITALIC_IMPL:
0513:                    return FONT_STYLE_ITALIC;
0514:                default:
0515:                    return FONT_STYLE_OBLIQUE;
0516:                }
0517:            }
0518:
0519:            /**
0520:             * @param newFontStyle The fontStyle is used when the property is 
0521:             *        not inherited
0522:             */
0523:            public void setFontStyle(final int newFontStyle) {
0524:                if (!isInherited(PROPERTY_FONT_STYLE)
0525:                        && newFontStyle == getFontStyle()) {
0526:                    return;
0527:                }
0528:
0529:                modifyingNode();
0530:                setInheritedQuiet(PROPERTY_FONT_STYLE, false);
0531:                setComputedFontStyle(newFontStyle);
0532:                propagatePackedPropertyState(PROPERTY_FONT_STYLE, pack
0533:                        & FONT_STYLE_MASK);
0534:                modifiedNode();
0535:            }
0536:
0537:            /**
0538:             * @param newFontStyle the new computed font-style property.
0539:             */
0540:            void setComputedFontStyle(final int newFontStyle) {
0541:                pack &= ~FONT_STYLE_MASK;
0542:                switch (newFontStyle) {
0543:                case FONT_STYLE_NORMAL:
0544:                    pack |= FONT_STYLE_NORMAL_IMPL;
0545:                    break;
0546:                case FONT_STYLE_ITALIC:
0547:                    pack |= FONT_STYLE_ITALIC_IMPL;
0548:                    break;
0549:                default:
0550:                    pack |= FONT_STYLE_OBLIQUE_IMPL;
0551:                    break;
0552:                }
0553:            }
0554:
0555:            /**
0556:             * @return this node's computed fontWeight
0557:             */
0558:            public int getFontWeight() {
0559:                switch (pack & FONT_WEIGHT_MASK) {
0560:                case FONT_WEIGHT_100_IMPL:
0561:                    return FONT_WEIGHT_100;
0562:                case FONT_WEIGHT_200_IMPL:
0563:                    return FONT_WEIGHT_200;
0564:                case FONT_WEIGHT_300_IMPL:
0565:                    return FONT_WEIGHT_300;
0566:                case FONT_WEIGHT_400_IMPL:
0567:                    return FONT_WEIGHT_400;
0568:                case FONT_WEIGHT_500_IMPL:
0569:                    return FONT_WEIGHT_500;
0570:                case FONT_WEIGHT_600_IMPL:
0571:                    return FONT_WEIGHT_600;
0572:                case FONT_WEIGHT_700_IMPL:
0573:                    return FONT_WEIGHT_700;
0574:                case FONT_WEIGHT_800_IMPL:
0575:                    return FONT_WEIGHT_800;
0576:                case FONT_WEIGHT_900_IMPL:
0577:                    return FONT_WEIGHT_900;
0578:                case FONT_WEIGHT_LIGHTER_IMPL:
0579:                    return FONT_WEIGHT_LIGHTER;
0580:                default:
0581:                    return FONT_WEIGHT_BOLDER;
0582:                }
0583:            }
0584:
0585:            /**
0586:             * @param newFontWeight The fontWeight is used when the property is 
0587:             *        not inherited
0588:             */
0589:            public void setFontWeight(final int newFontWeight) {
0590:                if (!isInherited(PROPERTY_FONT_WEIGHT)
0591:                        && newFontWeight == getFontWeight()) {
0592:                    return;
0593:                }
0594:
0595:                modifyingNode();
0596:                setInheritedQuiet(PROPERTY_FONT_WEIGHT, false);
0597:
0598:                // Font weight is special: we need to account for relative values
0599:                // bolder and lighter.
0600:                int packedParentFontWeight = getInheritedPackedPropertyState(PROPERTY_FONT_WEIGHT);
0601:                setComputedFontWeight(computeFontWeight(packedParentFontWeight,
0602:                        newFontWeight));
0603:                propagatePackedPropertyState(PROPERTY_FONT_WEIGHT, pack
0604:                        & FONT_WEIGHT_MASK);
0605:                modifiedNode();
0606:            }
0607:
0608:            /**
0609:             * @param newFontWeight new computed value for the font-weight property.
0610:             */
0611:            void setComputedFontWeight(final int newFontWeight) {
0612:                pack &= ~FONT_WEIGHT_MASK;
0613:                pack |= newFontWeight;
0614:            }
0615:
0616:            /**
0617:             * @return this node's computed textAnchor
0618:             */
0619:            public int getTextAnchor() {
0620:                switch (pack & TEXT_ANCHOR_MASK) {
0621:                case TEXT_ANCHOR_START_IMPL:
0622:                    return TEXT_ANCHOR_START;
0623:                case TEXT_ANCHOR_MIDDLE_IMPL:
0624:                    return TEXT_ANCHOR_MIDDLE;
0625:                default:
0626:                    return TEXT_ANCHOR_END;
0627:                }
0628:            }
0629:
0630:            /**
0631:             * @param newTextAnchor The textAnchor is used when the property is not 
0632:             *        inherited
0633:             */
0634:            public void setTextAnchor(final int newTextAnchor) {
0635:                if (!isInherited(PROPERTY_TEXT_ANCHOR)
0636:                        && newTextAnchor == getTextAnchor()) {
0637:                    return;
0638:                }
0639:
0640:                modifyingNode();
0641:                setComputedTextAnchor(newTextAnchor);
0642:                setInheritedQuiet(PROPERTY_TEXT_ANCHOR, false);
0643:                propagatePackedPropertyState(PROPERTY_TEXT_ANCHOR, pack
0644:                        & TEXT_ANCHOR_MASK);
0645:                modifiedNode();
0646:            }
0647:
0648:            /**
0649:             * Sets the value of the computed text anchor property.
0650:             *
0651:             * @param newTextAnchor the new value for the computed text anchor property.
0652:             */
0653:            void setComputedTextAnchor(final int newTextAnchor) {
0654:                pack &= ~TEXT_ANCHOR_MASK;
0655:                switch (newTextAnchor) {
0656:                case TEXT_ANCHOR_START:
0657:                    pack |= TEXT_ANCHOR_START_IMPL;
0658:                    break;
0659:                case TEXT_ANCHOR_MIDDLE:
0660:                    pack |= TEXT_ANCHOR_MIDDLE_IMPL;
0661:                    break;
0662:                default:
0663:                    pack |= TEXT_ANCHOR_END_IMPL;
0664:                    break;
0665:                }
0666:            }
0667:
0668:            /**
0669:             * Handles the 'bolder' and 'lighter' values as follows:
0670:             *
0671:             * - bolder computes to font-weight + 300. If the result
0672:             *   is more than 900, then the computed value is 900.
0673:             * - lighter computes to font-weight - 300. If the result
0674:             *   is less than 100, then the comuted value is 100.
0675:             *
0676:             * *NOTE*
0677:             *
0678:             * This is not exactly implementing the CSS2 specification for bolder but
0679:             * that part of the CSS 2 specification is known to be
0680:             * underspecified. Handling of 'bolder' is being respecified for CSS
0681:             * 2.1. Furthermore, the CSS 2 specification does not address the needs for
0682:             * SVG Fonts well. For example, if you have the following fonts in the font
0683:             * data base:
0684:             *
0685:             * font A:  Arial, 100 to 500
0686:             * font B:  Arial, 600 to 900
0687:             *
0688:             * element 1: font-family="Arial" font-weight="normal" 
0689:             *     |
0690:             *     + - element 2: font-family="Arial" font-weight="bolder"
0691:             *
0692:             * font-weight for element 1 is 400. The font weight for element B should be
0693:             * that of the font for which there is a next bolder weight.  In our
0694:             * example, it is font A which has font weight 500. However, it is not the
0695:             * desired behavior in most cases.
0696:             *
0697:             * Secondly, the SVG Font format allows non consecutive font-weight values
0698:             * in the <font-face> element. For example:
0699:             *
0700:             * font C: Arial, 100,900
0701:             * font D: Arial, 200,400
0702:             *
0703:             * While this does not make a lot of sense, it is possible to specify such
0704:             * fonts and it is unclear what the behavior of bolder should be in that
0705:             * case. It seems that taking the matching font which has the most distance
0706:             * from the current font-weight could work, but that would be limiting
0707:             * 'bolder' to a one step change....
0708:             *
0709:             * The approach taken in the Perseus implementation is such that bolder will
0710:             * work for common cases with common Font specifications.
0711:             *
0712:             * @param refPackedFontWeight the reference font weight.
0713:             * @param relFontWeight the possibly relative font weight.
0714:             * @return the computed font weight.
0715:             */
0716:            int computeFontWeight(final int refPackedFontWeight,
0717:                    final int relFontWeight) {
0718:                // Handle bolder and lighter
0719:                if (relFontWeight == FONT_WEIGHT_BOLDER) {
0720:                    setMarker(FONT_WEIGHT_BOLDER_MARKER);
0721:                    clearMarker(FONT_WEIGHT_LIGHTER_MARKER);
0722:                    switch (refPackedFontWeight) {
0723:                    case FONT_WEIGHT_100_IMPL:
0724:                        return FONT_WEIGHT_400_IMPL;
0725:                    case FONT_WEIGHT_200_IMPL:
0726:                        return FONT_WEIGHT_500_IMPL;
0727:                    case FONT_WEIGHT_300_IMPL:
0728:                        return FONT_WEIGHT_600_IMPL;
0729:                    case FONT_WEIGHT_400_IMPL:
0730:                        return FONT_WEIGHT_700_IMPL;
0731:                    case FONT_WEIGHT_500_IMPL:
0732:                        return FONT_WEIGHT_800_IMPL;
0733:                    case FONT_WEIGHT_600_IMPL:
0734:                    case FONT_WEIGHT_700_IMPL:
0735:                    case FONT_WEIGHT_800_IMPL:
0736:                    case FONT_WEIGHT_900_IMPL:
0737:                    default:
0738:                        return FONT_WEIGHT_900_IMPL;
0739:                    }
0740:                } else if (relFontWeight == FONT_WEIGHT_LIGHTER) {
0741:                    setMarker(FONT_WEIGHT_LIGHTER_MARKER);
0742:                    clearMarker(FONT_WEIGHT_BOLDER_MARKER);
0743:                    switch (refPackedFontWeight) {
0744:                    default:
0745:                    case FONT_WEIGHT_100_IMPL:
0746:                    case FONT_WEIGHT_200_IMPL:
0747:                    case FONT_WEIGHT_300_IMPL:
0748:                    case FONT_WEIGHT_400_IMPL:
0749:                        return FONT_WEIGHT_100_IMPL;
0750:                    case FONT_WEIGHT_500_IMPL:
0751:                        return FONT_WEIGHT_200_IMPL;
0752:                    case FONT_WEIGHT_600_IMPL:
0753:                        return FONT_WEIGHT_300_IMPL;
0754:                    case FONT_WEIGHT_700_IMPL:
0755:                        return FONT_WEIGHT_400_IMPL;
0756:                    case FONT_WEIGHT_800_IMPL:
0757:                        return FONT_WEIGHT_500_IMPL;
0758:                    case FONT_WEIGHT_900_IMPL:
0759:                        return FONT_WEIGHT_600_IMPL;
0760:                    }
0761:                }
0762:
0763:                clearMarker(FONT_WEIGHT_BOLDER_MARKER);
0764:                clearMarker(FONT_WEIGHT_LIGHTER_MARKER);
0765:                switch (relFontWeight) {
0766:                default:
0767:                case FONT_WEIGHT_100:
0768:                    return FONT_WEIGHT_100_IMPL;
0769:                case FONT_WEIGHT_200:
0770:                    return FONT_WEIGHT_200_IMPL;
0771:                case FONT_WEIGHT_300:
0772:                    return FONT_WEIGHT_300_IMPL;
0773:                case FONT_WEIGHT_400:
0774:                    return FONT_WEIGHT_400_IMPL;
0775:                case FONT_WEIGHT_500:
0776:                    return FONT_WEIGHT_500_IMPL;
0777:                case FONT_WEIGHT_600:
0778:                    return FONT_WEIGHT_600_IMPL;
0779:                case FONT_WEIGHT_700:
0780:                    return FONT_WEIGHT_700_IMPL;
0781:                case FONT_WEIGHT_800:
0782:                    return FONT_WEIGHT_800_IMPL;
0783:                case FONT_WEIGHT_900:
0784:                    return FONT_WEIGHT_900_IMPL;
0785:                }
0786:            }
0787:
0788:            /**
0789:             * Utility method: computes the transform needed to fit the input 
0790:             * box into the given output box for the given input alignment 
0791:             * property.
0792:             *
0793:             * @param ix the x origin of the input box
0794:             * @param iy the y origin of the input box
0795:             * @param iw the width of the input box
0796:             * @param ih the height of the input box
0797:             * @param ox the x origin of the output box
0798:             * @param oy the y origin of the output box
0799:             * @param ow the width of the output box
0800:             * @param oh the height of the output box
0801:             * @param align the desired alignment. One of ALIGN_NONE, or ALIGN_XMIDYMID
0802:             * @param result the transform to which the fitting transform is 
0803:             *        concatenated
0804:             *
0805:             */
0806:            public static void getFittingTransform(final float ix,
0807:                    final float iy, final float iw, final float ih,
0808:                    final float ox, final float oy, final float ow,
0809:                    final float oh, final int align, final Transform result) {
0810:                float inAR = iw / ih;
0811:                float outAR = ow / oh;
0812:
0813:                // Move to output box location (ox,oy)
0814:                result.mTranslate(ox, oy);
0815:
0816:                if (align == ALIGN_NONE) {
0817:                    // Scale without preserving aspect ratio
0818:                    result.mScale(ow / iw, oh / ih);
0819:                    // Move to (0,0)
0820:                    result.mTranslate(-ix, -iy);
0821:                } else if (inAR < outAR) {
0822:                    float sf = oh / ih;
0823:                    result.mScale(sf);
0824:                    result.mTranslate(-ix - (iw - ow * ih / oh) / 2, -iy);
0825:                } else {
0826:                    float sf = ow / iw;
0827:                    result.mScale(sf);
0828:                    result.mTranslate(-ix, -iy - (ih - oh * iw / ow) / 2);
0829:                }
0830:            }
0831:
0832:            /**
0833:             * @return an adequate <code>ElementNodeProxy</code> for this node.
0834:             */
0835:            ElementNodeProxy buildProxy() {
0836:                return new StructureNodeProxy(this );
0837:            }
0838:
0839:            /**
0840:             * Paints this node into the input <code>RenderGraphics</code>.  By default,
0841:             * a <code>StructureNode</code> only renders its regular (DOM) children and
0842:             * it does not perform any rendering itself.
0843:             *
0844:             * @param rg the <tt>RenderGraphics</tt> where the node should paint itself
0845:             */
0846:            public void paint(final RenderGraphics rg) {
0847:                if (canRenderState != 0) {
0848:                    return;
0849:                }
0850:
0851:                paint(getFirstChildNode(), rg);
0852:            }
0853:
0854:            /**
0855:             * Supported traits: font-family, font-size, font-style, font-weight, 
0856:             * text-anchor.
0857:             *
0858:             * @param traitName the name of the trait which the element may support.
0859:             * @return true if this element supports the given trait in one of the
0860:             *         trait accessor methods.
0861:             */
0862:            boolean supportsTrait(final String traitName) {
0863:                if (SVGConstants.SVG_FONT_FAMILY_ATTRIBUTE == traitName
0864:                        || SVGConstants.SVG_FONT_SIZE_ATTRIBUTE == traitName
0865:                        || SVGConstants.SVG_FONT_STYLE_ATTRIBUTE == traitName
0866:                        || SVGConstants.SVG_FONT_WEIGHT_ATTRIBUTE == traitName
0867:                        || SVGConstants.SVG_TEXT_ANCHOR_ATTRIBUTE == traitName) {
0868:                    return true;
0869:                } else {
0870:                    return super .supportsTrait(traitName);
0871:                }
0872:            }
0873:
0874:            /**
0875:             * Supported traits: font-family, font-size, font-style, font-weight, 
0876:             * text-anchor.
0877:             *
0878:             * @param name the requested trait name (e.g., "font-family").
0879:             * @return the trait's value, as a string (e.g., "serif").
0880:             *
0881:             * @throws DOMException with error code NOT_SUPPORTED_ERROR if the requested
0882:             * trait is not supported on this element or null.
0883:             * @throws DOMException with error code TYPE_MISMATCH_ERR if requested
0884:             * trait's computed value cannot be converted to a String (SVG Tiny only).
0885:             */
0886:            String getSpecifiedTraitImpl(final String name) throws DOMException {
0887:                if ((SVGConstants.SVG_FONT_FAMILY_ATTRIBUTE == name && isInherited(PROPERTY_FONT_FAMILY))
0888:                        || (SVGConstants.SVG_FONT_SIZE_ATTRIBUTE == name && isInherited(PROPERTY_FONT_SIZE))
0889:                        || (SVGConstants.SVG_FONT_STYLE_ATTRIBUTE == name && isInherited(PROPERTY_FONT_STYLE))
0890:                        || (SVGConstants.SVG_FONT_WEIGHT_ATTRIBUTE == name && isInherited(PROPERTY_FONT_WEIGHT))
0891:                        || (SVGConstants.SVG_TEXT_ANCHOR_ATTRIBUTE == name && isInherited(PROPERTY_TEXT_ANCHOR))) {
0892:                    return SVGConstants.CSS_INHERIT_VALUE;
0893:                } else {
0894:                    return super .getSpecifiedTraitImpl(name);
0895:                }
0896:            }
0897:
0898:            /**
0899:             * Converts the input font-style value to a string trait value.
0900:             *
0901:             * @param fontStyle the font-style value to convert.
0902:             * @return the corresponding string trait value.
0903:             */
0904:            String fontWeightToStringTrait(final int fontWeight) {
0905:                switch (fontWeight) {
0906:                case StructureNode.FONT_WEIGHT_100_IMPL:
0907:                    return SVGConstants.CSS_100_VALUE;
0908:                case StructureNode.FONT_WEIGHT_200_IMPL:
0909:                    return SVGConstants.CSS_200_VALUE;
0910:                case StructureNode.FONT_WEIGHT_300_IMPL:
0911:                    return SVGConstants.CSS_300_VALUE;
0912:                case StructureNode.FONT_WEIGHT_400_IMPL:
0913:                    return SVGConstants.CSS_400_VALUE;
0914:                case StructureNode.FONT_WEIGHT_500_IMPL:
0915:                    return SVGConstants.CSS_500_VALUE;
0916:                case StructureNode.FONT_WEIGHT_600_IMPL:
0917:                    return SVGConstants.CSS_600_VALUE;
0918:                case StructureNode.FONT_WEIGHT_700_IMPL:
0919:                    return SVGConstants.CSS_700_VALUE;
0920:                case StructureNode.FONT_WEIGHT_800_IMPL:
0921:                    return SVGConstants.CSS_800_VALUE;
0922:                case StructureNode.FONT_WEIGHT_900_IMPL:
0923:                default:
0924:                    return SVGConstants.CSS_900_VALUE;
0925:                }
0926:            }
0927:
0928:            /**
0929:             * Converts the input text-anchor value to a string trait value.
0930:             *
0931:             * @param textAnchor the text-anchor value to convert.
0932:             * @return the corresponding string trait value.
0933:             */
0934:            String textAnchorToStringTrait(final int textAnchor) {
0935:                switch (textAnchor) {
0936:                case StructureNode.TEXT_ANCHOR_START_IMPL:
0937:                    return SVGConstants.CSS_START_VALUE;
0938:                case StructureNode.TEXT_ANCHOR_MIDDLE_IMPL:
0939:                    return SVGConstants.CSS_MIDDLE_VALUE;
0940:                case StructureNode.TEXT_ANCHOR_END_IMPL:
0941:                    return SVGConstants.CSS_END_VALUE;
0942:                default:
0943:                    // Should _never_ happen. 
0944:                    throw new Error();
0945:                }
0946:            }
0947:
0948:            /**
0949:             * Converts the input font-style value to a string trait value.
0950:             *
0951:             * @param fontStyle the font-style value to convert. In packed form, with
0952:             *        mask applied.
0953:             * @return the corresponding string trait value.
0954:             */
0955:            String fontStyleToStringTrait(final int fontStyle) {
0956:                switch (fontStyle) {
0957:                case StructureNode.FONT_STYLE_NORMAL_IMPL:
0958:                    return SVGConstants.CSS_NORMAL_VALUE;
0959:                case StructureNode.FONT_STYLE_OBLIQUE_IMPL:
0960:                    return SVGConstants.CSS_OBLIQUE_VALUE;
0961:                case StructureNode.FONT_STYLE_ITALIC_IMPL:
0962:                default:
0963:                    return SVGConstants.CSS_ITALIC_VALUE;
0964:                }
0965:            }
0966:
0967:            /**
0968:             * Supported traits: font-family, font-size, font-style, font-weight, 
0969:             * text-anchor.
0970:             *
0971:             * @param name the requested trait name (e.g., "font-family").
0972:             * @return the trait's value, as a string (e.g., "serif").
0973:             *
0974:             * @throws DOMException with error code NOT_SUPPORTED_ERROR if the requested
0975:             * trait is not supported on this element or null.
0976:             * @throws DOMException with error code TYPE_MISMATCH_ERR if requested
0977:             * trait's computed value cannot be converted to a String (SVG Tiny only).
0978:             */
0979:            public String getTraitImpl(final String name) throws DOMException {
0980:                if (SVGConstants.SVG_FONT_FAMILY_ATTRIBUTE == name) {
0981:                    return toStringTraitQuote(getFontFamily());
0982:                } else if (SVGConstants.SVG_FONT_SIZE_ATTRIBUTE == name) {
0983:                    return Float.toString(getFontSize());
0984:                } else if (SVGConstants.SVG_FONT_STYLE_ATTRIBUTE == name) {
0985:                    return fontStyleToStringTrait(pack & FONT_STYLE_MASK);
0986:                } else if (SVGConstants.SVG_FONT_WEIGHT_ATTRIBUTE == name) {
0987:                    return fontWeightToStringTrait(pack & FONT_WEIGHT_MASK);
0988:                } else if (SVGConstants.SVG_TEXT_ANCHOR_ATTRIBUTE == name) {
0989:                    return textAnchorToStringTrait(pack & TEXT_ANCHOR_MASK);
0990:                } else {
0991:                    return super .getTraitImpl(name);
0992:                }
0993:            }
0994:
0995:            /**
0996:             * Supported float traits: font-size
0997:             *
0998:             * @param name the requested trait name (e.g, "font-size")
0999:             * @return the trait's value, as a float.
1000:             *
1001:             * @throws DOMException with error code NOT_SUPPORTED_ERROR if the requested
1002:             * trait is not supported on this element or null.
1003:             * @throws DOMException with error code TYPE_MISMATCH_ERR if requested
1004:             * trait's computed value cannot be converted to a float
1005:             * @throws SecurityException if the application does not have the necessary
1006:             * privilege rights to access this (SVG) content.
1007:             */
1008:            float getFloatTraitImpl(final String name) throws DOMException {
1009:                if (SVGConstants.SVG_FONT_SIZE_ATTRIBUTE == name) {
1010:                    return getFontSize();
1011:                } else {
1012:                    return super .getFloatTraitImpl(name);
1013:                }
1014:            }
1015:
1016:            /**
1017:             * @param traitName the trait name.
1018:             */
1019:            TraitAnim createTraitAnimImpl(final String traitName) {
1020:                if (SVGConstants.SVG_FONT_SIZE_ATTRIBUTE == traitName) {
1021:                    return new FloatTraitAnim(this , traitName, TRAIT_TYPE_FLOAT);
1022:                } else if (SVGConstants.SVG_FONT_FAMILY_ATTRIBUTE == traitName
1023:                        || SVGConstants.SVG_FONT_STYLE_ATTRIBUTE == traitName
1024:                        || SVGConstants.SVG_FONT_WEIGHT_ATTRIBUTE == traitName
1025:                        || SVGConstants.SVG_TEXT_ANCHOR_ATTRIBUTE == traitName) {
1026:                    return new StringTraitAnim(this , NULL_NS, traitName);
1027:                } else {
1028:                    return super .createTraitAnimImpl(traitName);
1029:                }
1030:            }
1031:
1032:            /**
1033:             * Set the trait value as float.
1034:             *
1035:             * @param name the trait's name.
1036:             * @param value the trait's value.
1037:             *
1038:             * @throws DOMException with error code NOT_SUPPORTED_ERROR if the requested
1039:             * trait is not supported on this element.
1040:             * @throws DOMException with error code TYPE_MISMATCH_ERR if the requested
1041:             * trait's value cannot be specified as a float
1042:             * @throws DOMException with error code INVALID_ACCESS_ERR if the input
1043:             * value is an invalid value for the given trait.
1044:             */
1045:            void setFloatArrayTrait(final String name, final float[][] value)
1046:                    throws DOMException {
1047:                if (SVGConstants.SVG_FONT_SIZE_ATTRIBUTE == name) {
1048:                    checkPositive(name, value[0][0]);
1049:                    setFontSize(value[0][0]);
1050:                } else {
1051:                    super .setFloatArrayTrait(name, value);
1052:                }
1053:            }
1054:
1055:            /**
1056:             * Validates the input trait value.
1057:             *
1058:             * @param traitName the name of the trait to be validated.
1059:             * @param value the value to be validated
1060:             * @param reqNamespaceURI the namespace of the element requesting 
1061:             *        validation.
1062:             * @param reqLocalName the local name of the element requesting validation.
1063:             * @param reqTraitNamespace the namespace of the trait which has the values
1064:             *        value on the requesting element.
1065:             * @param reqTraitName the name of the trait which has the values value on 
1066:             *        the requesting element.
1067:             * @throws DOMException with error code INVALID_ACCESS_ERR if the input
1068:             *         value is incompatible with the given trait.
1069:             */
1070:            public float[][] validateFloatArrayTrait(final String traitName,
1071:                    final String value, final String reqNamespaceURI,
1072:                    final String reqLocalName, final String reqTraitNamespace,
1073:                    final String reqTraitName) throws DOMException {
1074:                if (SVGConstants.SVG_FONT_SIZE_ATTRIBUTE == traitName) {
1075:                    return new float[][] { { parsePositiveFloatTrait(traitName,
1076:                            value) } };
1077:                } else {
1078:                    return super .validateFloatArrayTrait(traitName, value,
1079:                            reqNamespaceURI, reqLocalName, reqTraitNamespace,
1080:                            reqTraitName);
1081:                }
1082:            }
1083:
1084:            /**
1085:             * Validates the input trait value.
1086:             *
1087:             * @param namespaceURI the trait's namespace URI.
1088:             * @param traitName the name of the trait to be validated.
1089:             * @param value the value to be validated
1090:             * @param reqNamespaceURI the namespace of the element requesting 
1091:             *        validation.
1092:             * @param reqLocalName the local name of the element requesting validation.
1093:             * @param reqTraitNamespace the namespace of the trait which has the values
1094:             *        value on the requesting element.
1095:             * @param reqTraitName the name of the trait which has the values value on 
1096:             *        the requesting element.
1097:             * @throws DOMException with error code INVALID_ACCESS_ERR if the input
1098:             *         value is incompatible with the given trait.
1099:             */
1100:            String validateTraitNS(final String namespaceURI,
1101:                    final String traitName, final String value,
1102:                    final String reqNamespaceURI, final String reqLocalName,
1103:                    final String reqTraitNamespace, final String reqTraitName)
1104:                    throws DOMException {
1105:                if (namespaceURI != null && namespaceURI != NULL_NS) {
1106:                    return super .validateTraitNS(namespaceURI, traitName,
1107:                            value, reqNamespaceURI, reqLocalName,
1108:                            reqTraitNamespace, reqTraitName);
1109:                }
1110:
1111:                if (SVGConstants.SVG_FONT_SIZE_ATTRIBUTE == traitName) {
1112:                    throw unsupportedTraitType(traitName, TRAIT_TYPE_FLOAT);
1113:                }
1114:
1115:                if (SVGConstants.SVG_FONT_FAMILY_ATTRIBUTE == traitName) {
1116:                    if (SVGConstants.CSS_INHERIT_VALUE.equals(value)) {
1117:                        return toStringTraitQuote((String[]) getInheritedPropertyState(PROPERTY_FONT_FAMILY));
1118:                    }
1119:
1120:                    return value;
1121:                } else if (SVGConstants.SVG_FONT_STYLE_ATTRIBUTE == traitName) {
1122:                    if (SVGConstants.CSS_INHERIT_VALUE.equals(value)) {
1123:                        return fontStyleToStringTrait(getInheritedPackedPropertyState(PROPERTY_FONT_STYLE));
1124:                    } else if (!SVGConstants.CSS_NORMAL_VALUE.equals(value)
1125:                            && !SVGConstants.CSS_ITALIC_VALUE.equals(value)
1126:                            && !SVGConstants.CSS_OBLIQUE_VALUE.equals(value)) {
1127:                        throw illegalTraitValue(traitName, value);
1128:                    }
1129:
1130:                    return value;
1131:                } else if (SVGConstants.SVG_FONT_WEIGHT_ATTRIBUTE == traitName) {
1132:                    if (SVGConstants.CSS_INHERIT_VALUE.equals(value)) {
1133:                        return fontWeightToStringTrait(getInheritedPackedPropertyState(PROPERTY_FONT_WEIGHT));
1134:                    } else if (SVGConstants.CSS_NORMAL_VALUE.equals(value)) {
1135:                        return SVGConstants.CSS_400_VALUE;
1136:                    } else if (SVGConstants.CSS_BOLD_VALUE.equals(value)) {
1137:                        return SVGConstants.CSS_700_VALUE;
1138:                    } else if (SVGConstants.CSS_BOLDER_VALUE.equals(value)) {
1139:                        // We need to base on the parent's animated value.
1140:                        int packedFontWeight = getInheritedPackedPropertyState(PROPERTY_FONT_WEIGHT);
1141:                        int fontWeight = computeFontWeight(packedFontWeight,
1142:                                FONT_WEIGHT_BOLDER);
1143:                        return fontWeightToStringTrait(fontWeight);
1144:                    } else if (SVGConstants.CSS_LIGHTER_VALUE.equals(value)) {
1145:                        // We need to base on the parent's animated value.
1146:                        int packedFontWeight = getInheritedPackedPropertyState(PROPERTY_FONT_WEIGHT);
1147:                        int fontWeight = computeFontWeight(packedFontWeight,
1148:                                FONT_WEIGHT_LIGHTER);
1149:                        return fontWeightToStringTrait(fontWeight);
1150:                    } else if (!SVGConstants.CSS_100_VALUE.equals(value)
1151:                            && !SVGConstants.CSS_200_VALUE.equals(value)
1152:                            && !SVGConstants.CSS_300_VALUE.equals(value)
1153:                            && !SVGConstants.CSS_400_VALUE.equals(value)
1154:                            && !SVGConstants.CSS_NORMAL_VALUE.equals(value)
1155:                            && !SVGConstants.CSS_500_VALUE.equals(value)
1156:                            && !SVGConstants.CSS_600_VALUE.equals(value)
1157:                            && !SVGConstants.CSS_700_VALUE.equals(value)
1158:                            && !SVGConstants.CSS_800_VALUE.equals(value)
1159:                            && !SVGConstants.CSS_900_VALUE.equals(value)) {
1160:                        throw illegalTraitValue(traitName, value);
1161:                    }
1162:                    return value;
1163:                } else if (SVGConstants.SVG_TEXT_ANCHOR_ATTRIBUTE == traitName) {
1164:                    if (SVGConstants.CSS_INHERIT_VALUE.equals(value)) {
1165:                        return textAnchorToStringTrait(getInheritedPackedPropertyState(PROPERTY_TEXT_ANCHOR));
1166:                    }
1167:                    if (!SVGConstants.CSS_START_VALUE.equals(value)
1168:                            && !SVGConstants.CSS_MIDDLE_VALUE.equals(value)
1169:                            && !SVGConstants.CSS_END_VALUE.equals(value)) {
1170:                        throw illegalTraitValue(traitName, value);
1171:                    }
1172:                    return value;
1173:                }
1174:
1175:                return super .validateTraitNS(namespaceURI, traitName, value,
1176:                        reqNamespaceURI, reqLocalName, reqTraitNamespace,
1177:                        reqTraitName);
1178:            }
1179:
1180:            /**
1181:             * Supported traits: font-family, font-size, font-style, font-weight, 
1182:             * text-anchor.
1183:             *
1184:             * Supported traits: stroke-width, stroke-miterlimit, stroke-dashoffset,
1185:             * fill-rule, stroke-linejoin, stroke-linecap, display, visibility, 
1186:             * color, fill, stroke, fill-opacity, stroke-opacity, stroke-dasharray
1187:             *
1188:             * @param name the trait name (e.g., "stroke-width")
1189:             * @param value the trait's string value (e.g, "3")
1190:             *
1191:             * @throws DOMException with error code NOT_SUPPORTED_ERROR if the requested
1192:             * trait is not supported on this element or null.
1193:             * @throws DOMException with error code TYPE_MISMATCH_ERR if the requested
1194:             * trait's value cannot be specified as a String
1195:             * @throws DOMException with error code INVALID_ACCESS_ERR if the input
1196:             * value is an invalid value for the given trait or null.
1197:             * @throws DOMException with error code NO_MODIFICATION_ALLOWED_ERR: if
1198:             * attempt is made to change readonly trait.
1199:             */
1200:            public void setTraitImpl(final String name, final String value)
1201:                    throws DOMException {
1202:                if (SVGConstants.SVG_FONT_FAMILY_ATTRIBUTE == name) {
1203:
1204:                    // ======================= font-family ====================== //
1205:
1206:                    if (SVGConstants.CSS_INHERIT_VALUE.equals(value)) {
1207:                        setInherited(PROPERTY_FONT_FAMILY, true);
1208:                    } else {
1209:                        setFontFamily(parseFontFamilyTrait(name, value));
1210:                    }
1211:                } else if (SVGConstants.SVG_FONT_SIZE_ATTRIBUTE == name) {
1212:
1213:                    // ======================= font-size ======================== //
1214:
1215:                    if (SVGConstants.CSS_INHERIT_VALUE.equals(value)) {
1216:                        setFloatInherited(PROPERTY_FONT_SIZE, true);
1217:                    } else {
1218:                        setFontSize(parsePositiveFloatTrait(name, value));
1219:                    }
1220:                } else if (SVGConstants.SVG_FONT_STYLE_ATTRIBUTE == name) {
1221:
1222:                    // ======================= font-style ======================= //
1223:
1224:                    if (SVGConstants.CSS_NORMAL_VALUE.equals(value)) {
1225:                        setFontStyle(TextProperties.FONT_STYLE_NORMAL);
1226:                    } else if (SVGConstants.CSS_ITALIC_VALUE.equals(value)) {
1227:                        setFontStyle(TextProperties.FONT_STYLE_ITALIC);
1228:                    } else if (SVGConstants.CSS_OBLIQUE_VALUE.equals(value)) {
1229:                        setFontStyle(TextProperties.FONT_STYLE_OBLIQUE);
1230:                    } else if (SVGConstants.CSS_INHERIT_VALUE.equals(value)) {
1231:                        setPackedInherited(PROPERTY_FONT_STYLE, true);
1232:                    } else {
1233:                        throw illegalTraitValue(name, value);
1234:                    }
1235:
1236:                } else if (SVGConstants.SVG_FONT_WEIGHT_ATTRIBUTE == name) {
1237:
1238:                    // ======================= font-weight ======================= //
1239:
1240:                    if (SVGConstants.CSS_100_VALUE.equals(value)) {
1241:                        setFontWeight(TextNode.FONT_WEIGHT_100);
1242:                    } else if (SVGConstants.CSS_200_VALUE.equals(value)) {
1243:                        setFontWeight(TextNode.FONT_WEIGHT_200);
1244:                    } else if (SVGConstants.CSS_300_VALUE.equals(value)) {
1245:                        setFontWeight(TextNode.FONT_WEIGHT_300);
1246:                    } else if (SVGConstants.CSS_400_VALUE.equals(value)) {
1247:                        setFontWeight(TextNode.FONT_WEIGHT_400);
1248:                    } else if (SVGConstants.CSS_NORMAL_VALUE.equals(value)) {
1249:                        setFontWeight(TextNode.FONT_WEIGHT_NORMAL);
1250:                    } else if (SVGConstants.CSS_500_VALUE.equals(value)) {
1251:                        setFontWeight(TextNode.FONT_WEIGHT_500);
1252:                    } else if (SVGConstants.CSS_600_VALUE.equals(value)) {
1253:                        setFontWeight(TextNode.FONT_WEIGHT_600);
1254:                    } else if (SVGConstants.CSS_700_VALUE.equals(value)) {
1255:                        setFontWeight(TextNode.FONT_WEIGHT_700);
1256:                    } else if (SVGConstants.CSS_BOLD_VALUE.equals(value)) {
1257:                        setFontWeight(TextNode.FONT_WEIGHT_BOLD);
1258:                    } else if (SVGConstants.CSS_800_VALUE.equals(value)) {
1259:                        setFontWeight(TextNode.FONT_WEIGHT_800);
1260:                    } else if (SVGConstants.CSS_900_VALUE.equals(value)) {
1261:                        setFontWeight(TextNode.FONT_WEIGHT_900);
1262:                    } else if (SVGConstants.CSS_BOLDER_VALUE.equals(value)) {
1263:                        setFontWeight(TextNode.FONT_WEIGHT_BOLDER);
1264:                    } else if (SVGConstants.CSS_LIGHTER_VALUE.equals(value)) {
1265:                        setFontWeight(TextNode.FONT_WEIGHT_LIGHTER);
1266:                    } else if (SVGConstants.CSS_INHERIT_VALUE.equals(value)) {
1267:                        setPackedInherited(PROPERTY_FONT_WEIGHT, true);
1268:                        clearMarker(FONT_WEIGHT_BOLDER_MARKER);
1269:                        clearMarker(FONT_WEIGHT_LIGHTER_MARKER);
1270:                    } else {
1271:                        throw illegalTraitValue(name, value);
1272:                    }
1273:                } else if (SVGConstants.SVG_TEXT_ANCHOR_ATTRIBUTE == name) {
1274:
1275:                    // ======================= text-anchor ====================== //
1276:
1277:                    if (SVGConstants.CSS_START_VALUE.equals(value)) {
1278:                        setTextAnchor(TextProperties.TEXT_ANCHOR_START);
1279:                    } else if (SVGConstants.CSS_MIDDLE_VALUE.equals(value)) {
1280:                        setTextAnchor(TextProperties.TEXT_ANCHOR_MIDDLE);
1281:                    } else if (SVGConstants.CSS_END_VALUE.equals(value)) {
1282:                        setTextAnchor(TextProperties.TEXT_ANCHOR_END);
1283:                    } else if (SVGConstants.CSS_INHERIT_VALUE.equals(value)) {
1284:                        setPackedInherited(PROPERTY_TEXT_ANCHOR, true);
1285:                    } else {
1286:                        throw illegalTraitValue(name, value);
1287:                    }
1288:                } else {
1289:                    super .setTraitImpl(name, value);
1290:                }
1291:            }
1292:
1293:            /**
1294:             * @param name the name of the trait to convert.
1295:             * @param value the float trait value to convert.
1296:             */
1297:            String toStringTrait(final String name, final float[][] value) {
1298:                if (SVGConstants.SVG_FONT_SIZE_ATTRIBUTE == name) {
1299:                    return Float.toString(value[0][0]);
1300:                } else {
1301:                    return super .toStringTrait(name, value);
1302:                }
1303:            }
1304:
1305:            /**
1306:             * Set the trait value as float.
1307:             * Supported float traits: font-size.
1308:             *
1309:             * @param name the trait name (e.g, "font-size")
1310:             * @param value the trait value (e.g, 10f)
1311:             *
1312:             * @throws DOMException with error code NOT_SUPPORTED_ERROR if the requested
1313:             * trait is not supported on this element.
1314:             * @throws DOMException with error code TYPE_MISMATCH_ERR if the requested
1315:             * trait's value cannot be specified as a float
1316:             * @throws DOMException with error code INVALID_ACCESS_ERR if the input
1317:             * value is an invalid value for the given trait.
1318:             * @throws SecurityException if the application does not have the necessary
1319:             * privilege rights to access this (SVG) content.
1320:             */
1321:            public void setFloatTraitImpl(final String name, final float value)
1322:                    throws DOMException {
1323:                if (SVGConstants.SVG_FONT_SIZE_ATTRIBUTE == name) {
1324:                    checkPositive(name, value);
1325:                    setFontSize(value);
1326:                } else {
1327:                    super.setFloatTraitImpl(name, value);
1328:                }
1329:            }
1330:
1331:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.