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: * Use is subject to license terms.
0026: */
0027: package com.sun.perseus.model;
0028:
0029: import com.sun.perseus.j2d.RenderGraphics;
0030:
0031: import com.sun.perseus.j2d.Box;
0032: import com.sun.perseus.j2d.GraphicsProperties;
0033: import com.sun.perseus.j2d.PaintServer;
0034: import com.sun.perseus.j2d.PaintTarget;
0035: import com.sun.perseus.j2d.RGB;
0036: import com.sun.perseus.j2d.Tile;
0037: import com.sun.perseus.j2d.Transform;
0038:
0039: import org.w3c.dom.svg.SVGRect;
0040:
0041: /**
0042: * A <code>CompositeGraphicsNodeProxy</code> delegates its rendering to a
0043: * proxied <code>CompositeGraphics</code> object and also keeps a cached
0044: * transform and inverse transform.
0045: *
0046: * @version $Id: CompositeGraphicsNodeProxy.java,v 1.4 2006/06/29 10:47:30 ln156897 Exp $
0047: */
0048: public class CompositeGraphicsNodeProxy extends ElementNodeProxy
0049: implements GraphicsProperties, PaintTarget {
0050: /**
0051: * Cached Transform
0052: */
0053: protected Transform txf = null;
0054:
0055: /**
0056: * Cached inverse transform
0057: */
0058: protected Transform inverseTxf = null;
0059:
0060: // ====================================================================
0061: // Property values
0062: // ====================================================================
0063: /**
0064: * The current color. The fill and stroke colors may be
0065: * relative to the current color
0066: */
0067: protected RGB color = CompositeGraphicsNode.INITIAL_COLOR;
0068:
0069: /**
0070: * The fill paint used to fill this node
0071: */
0072: protected PaintServer fill = CompositeGraphicsNode.INITIAL_FILL;
0073:
0074: /**
0075: * The stroke paint used to stroke the outline of
0076: * this ShapeNode
0077: */
0078: protected PaintServer stroke = CompositeGraphicsNode.INITIAL_STROKE;
0079:
0080: /**
0081: * The winding rule for this node
0082: */
0083: protected int fillRule = CompositeGraphicsNode.INITIAL_FILL_RULE;
0084:
0085: /**
0086: * The stroke width
0087: */
0088: protected float strokeWidth = CompositeGraphicsNode.INITIAL_STROKE_WIDTH;
0089:
0090: /**
0091: * The stroke miter limit
0092: */
0093: protected float strokeMiterLimit = CompositeGraphicsNode.INITIAL_STROKE_MITER_LIMIT;
0094:
0095: /**
0096: * The stroke dash array
0097: */
0098: protected float[] strokeDashArray = CompositeGraphicsNode.INITIAL_STROKE_DASH_ARRAY;
0099:
0100: /**
0101: * The stroke dash offset
0102: */
0103: protected float strokeDashOffset = CompositeGraphicsNode.INITIAL_STROKE_DASH_OFFSET;
0104:
0105: /**
0106: * Same structure as the CompositeGraphicsNode pack and pack2 fields.
0107: */
0108: protected int pack = CompositeGraphicsNode.INITIAL_PACK;
0109: protected int pack2 = CompositeGraphicsNode.INITIAL_PACK2;
0110:
0111: /**
0112: * @param proxiedNode <tt>ElementNode</tt> to proxy
0113: */
0114: protected CompositeGraphicsNodeProxy(
0115: final CompositeGraphicsNode proxiedNode) {
0116: super (proxiedNode);
0117:
0118: // By default, a CompositeGraphicsNodeProxy is renderable
0119: canRenderState &= CAN_RENDER_RENDERABLE_MASK;
0120: canRenderState |= (proxiedNode.canRenderState & CAN_RENDER_PROXY_BITS_MASK);
0121:
0122: // We copy the computed value for all properties upon initialization.
0123: // When the node is hooked in the tree, inherited properties will be
0124: // recomputed.
0125: fill = proxiedNode.fill;
0126: stroke = proxiedNode.stroke;
0127: color = proxiedNode.color;
0128: pack = proxiedNode.pack;
0129: pack2 = proxiedNode.pack2;
0130: strokeWidth = proxiedNode.strokeWidth;
0131: strokeMiterLimit = proxiedNode.strokeMiterLimit;
0132: strokeDashArray = proxiedNode.strokeDashArray;
0133: strokeDashOffset = proxiedNode.strokeDashOffset;
0134: }
0135:
0136: /**
0137: * A <code>CompositeGraphicsNodeProxy</code> contributes to its parent
0138: * bounding box only if its display property is turned on.
0139: *
0140: * @return true if the node's bounding box should be accounted for.
0141: */
0142: protected boolean contributeBBox() {
0143: return (pack & CompositeGraphicsNode.DISPLAY_MASK) != 0;
0144: }
0145:
0146: /**
0147: * Recomputes all inherited properties.
0148: */
0149: void recomputeInheritedProperties() {
0150: ModelNode p = ownerDocument;
0151: if (parent != null) {
0152: p = parent;
0153: }
0154: recomputePropertyState(GraphicsNode.PROPERTY_FILL, p
0155: .getPropertyState(GraphicsNode.PROPERTY_FILL));
0156: recomputePropertyState(GraphicsNode.PROPERTY_STROKE, p
0157: .getPropertyState(GraphicsNode.PROPERTY_STROKE));
0158: recomputePropertyState(GraphicsNode.PROPERTY_COLOR, p
0159: .getPropertyState(GraphicsNode.PROPERTY_COLOR));
0160: recomputePackedPropertyState(
0161: GraphicsNode.PROPERTY_FILL_RULE,
0162: p
0163: .getPackedPropertyState(GraphicsNode.PROPERTY_FILL_RULE));
0164: recomputeFloatPropertyState(
0165: GraphicsNode.PROPERTY_STROKE_WIDTH,
0166: p
0167: .getFloatPropertyState(GraphicsNode.PROPERTY_STROKE_WIDTH));
0168: recomputePackedPropertyState(
0169: GraphicsNode.PROPERTY_STROKE_LINE_JOIN,
0170: p
0171: .getPackedPropertyState(GraphicsNode.PROPERTY_STROKE_LINE_JOIN));
0172: recomputePackedPropertyState(
0173: GraphicsNode.PROPERTY_STROKE_LINE_CAP,
0174: p
0175: .getPackedPropertyState(GraphicsNode.PROPERTY_STROKE_LINE_CAP));
0176: recomputeFloatPropertyState(
0177: GraphicsNode.PROPERTY_STROKE_MITER_LIMIT,
0178: p
0179: .getFloatPropertyState(GraphicsNode.PROPERTY_STROKE_MITER_LIMIT));
0180: recomputePropertyState(
0181: GraphicsNode.PROPERTY_STROKE_DASH_ARRAY,
0182: p
0183: .getPropertyState(GraphicsNode.PROPERTY_STROKE_DASH_ARRAY));
0184: recomputeFloatPropertyState(
0185: GraphicsNode.PROPERTY_STROKE_DASH_OFFSET,
0186: p
0187: .getFloatPropertyState(GraphicsNode.PROPERTY_STROKE_DASH_OFFSET));
0188: recomputePackedPropertyState(GraphicsNode.PROPERTY_DISPLAY, p
0189: .getPackedPropertyState(GraphicsNode.PROPERTY_DISPLAY));
0190: recomputePackedPropertyState(
0191: GraphicsNode.PROPERTY_VISIBILITY,
0192: p
0193: .getPackedPropertyState(GraphicsNode.PROPERTY_VISIBILITY));
0194: recomputePackedPropertyState(
0195: GraphicsNode.PROPERTY_FILL_OPACITY,
0196: p
0197: .getPackedPropertyState(GraphicsNode.PROPERTY_FILL_OPACITY));
0198: recomputePackedPropertyState(
0199: GraphicsNode.PROPERTY_STROKE_OPACITY,
0200: p
0201: .getPackedPropertyState(GraphicsNode.PROPERTY_STROKE_OPACITY));
0202: recomputePackedPropertyState(GraphicsNode.PROPERTY_OPACITY, p
0203: .getPackedPropertyState(GraphicsNode.PROPERTY_OPACITY));
0204: }
0205:
0206: // JAVADOC COMMENT ELIDED
0207: public SVGRect getBBox() {
0208: return null;
0209: }
0210:
0211: /**
0212: * Returns the value of the given Object-valued property.
0213: *
0214: * @return the value of the given property.
0215: */
0216: protected Object getPropertyState(final int propertyIndex) {
0217: switch (propertyIndex) {
0218: case GraphicsNode.PROPERTY_FILL:
0219: return fill;
0220: case GraphicsNode.PROPERTY_STROKE:
0221: return stroke;
0222: case GraphicsNode.PROPERTY_COLOR:
0223: return color;
0224: case GraphicsNode.PROPERTY_STROKE_DASH_ARRAY:
0225: return getStrokeDashArray();
0226: default:
0227: return super .getPropertyState(propertyIndex);
0228: }
0229: }
0230:
0231: /**
0232: * Returns the value of the given float-valued property.
0233: *
0234: * @return the value of the given property.
0235: */
0236: protected float getFloatPropertyState(final int propertyIndex) {
0237: switch (propertyIndex) {
0238: case GraphicsNode.PROPERTY_STROKE_WIDTH:
0239: return strokeWidth;
0240: case GraphicsNode.PROPERTY_STROKE_MITER_LIMIT:
0241: return strokeMiterLimit;
0242: case GraphicsNode.PROPERTY_STROKE_DASH_OFFSET:
0243: return strokeDashOffset;
0244: default:
0245: return super .getFloatPropertyState(propertyIndex);
0246: }
0247: }
0248:
0249: /**
0250: * Returns the value of the given packed property.
0251: *
0252: * @return the value of the given property.
0253: */
0254: protected int getPackedPropertyState(final int propertyIndex) {
0255: switch (propertyIndex) {
0256: case GraphicsNode.PROPERTY_FILL_RULE:
0257: return pack & CompositeGraphicsNode.FILL_RULE_MASK;
0258: case GraphicsNode.PROPERTY_STROKE_LINE_JOIN:
0259: return pack & CompositeGraphicsNode.STROKE_LINE_JOIN_MASK;
0260: case GraphicsNode.PROPERTY_STROKE_LINE_CAP:
0261: return pack & CompositeGraphicsNode.STROKE_LINE_CAP_MASK;
0262: case GraphicsNode.PROPERTY_DISPLAY:
0263: return pack & CompositeGraphicsNode.DISPLAY_MASK;
0264: case GraphicsNode.PROPERTY_VISIBILITY:
0265: return pack & CompositeGraphicsNode.VISIBILITY_MASK;
0266: case GraphicsNode.PROPERTY_FILL_OPACITY:
0267: return pack & CompositeGraphicsNode.FILL_OPACITY_MASK;
0268: case GraphicsNode.PROPERTY_STROKE_OPACITY:
0269: return pack & CompositeGraphicsNode.STROKE_OPACITY_MASK;
0270: case GraphicsNode.PROPERTY_OPACITY:
0271: return pack2 & CompositeGraphicsNode.OPACITY_MASK;
0272: default:
0273: return super .getPackedPropertyState(propertyIndex);
0274: }
0275: }
0276:
0277: /**
0278: * Checks the state of the Object type property value.
0279: *
0280: * @param propertyIndex the property index
0281: * @param propertyValue the computed value for the property.
0282: */
0283: protected boolean isPropertyState(final int propertyIndex,
0284: final Object propertyValue) {
0285: switch (propertyIndex) {
0286: case GraphicsNode.PROPERTY_FILL:
0287: return fill == propertyValue;
0288: case GraphicsNode.PROPERTY_STROKE:
0289: return stroke == propertyValue;
0290: case GraphicsNode.PROPERTY_COLOR:
0291: return color == propertyValue;
0292: case GraphicsNode.PROPERTY_STROKE_DASH_ARRAY:
0293: return strokeDashArray == propertyValue;
0294: default:
0295: return super .isPropertyState(propertyIndex, propertyValue);
0296: }
0297: }
0298:
0299: /**
0300: * Checks the state of the float type property value.
0301: *
0302: * @param propertyIndex the property index
0303: * @param propertyValue the computed value for the property.
0304: */
0305: protected boolean isFloatPropertyState(final int propertyIndex,
0306: final float propertyValue) {
0307: switch (propertyIndex) {
0308: case GraphicsNode.PROPERTY_STROKE_WIDTH:
0309: return strokeWidth == propertyValue;
0310: case GraphicsNode.PROPERTY_STROKE_MITER_LIMIT:
0311: return strokeMiterLimit == propertyValue;
0312: case GraphicsNode.PROPERTY_STROKE_DASH_OFFSET:
0313: return strokeDashOffset == propertyValue;
0314: default:
0315: return super .isFloatPropertyState(propertyIndex,
0316: propertyValue);
0317: }
0318: }
0319:
0320: /**
0321: * Checks the state of the packed property value.
0322: *
0323: * @param propertyIndex the property index
0324: * @param propertyValue the computed value for the property.
0325: */
0326: protected boolean isPackedPropertyState(final int propertyIndex,
0327: final int propertyValue) {
0328: switch (propertyIndex) {
0329: case GraphicsNode.PROPERTY_FILL_RULE:
0330: return (propertyValue == (pack & CompositeGraphicsNode.FILL_RULE_MASK));
0331: case GraphicsNode.PROPERTY_STROKE_LINE_JOIN:
0332: return (propertyValue == (pack & CompositeGraphicsNode.STROKE_LINE_JOIN_MASK));
0333: case GraphicsNode.PROPERTY_STROKE_LINE_CAP:
0334: return (propertyValue == (pack & CompositeGraphicsNode.STROKE_LINE_CAP_MASK));
0335: case GraphicsNode.PROPERTY_DISPLAY:
0336: return (propertyValue == (pack & CompositeGraphicsNode.DISPLAY_MASK));
0337: case GraphicsNode.PROPERTY_VISIBILITY:
0338: return (propertyValue == (pack & CompositeGraphicsNode.DISPLAY_MASK));
0339: case GraphicsNode.PROPERTY_FILL_OPACITY:
0340: return (propertyValue == (pack & CompositeGraphicsNode.FILL_OPACITY_MASK));
0341: case GraphicsNode.PROPERTY_STROKE_OPACITY:
0342: return (propertyValue == (pack & CompositeGraphicsNode.STROKE_OPACITY_MASK));
0343: case GraphicsNode.PROPERTY_OPACITY:
0344: return (propertyValue == (pack2 & CompositeGraphicsNode.OPACITY_MASK));
0345: default:
0346: return super .isPackedPropertyState(propertyIndex,
0347: propertyValue);
0348: }
0349: }
0350:
0351: /**
0352: * Sets the computed value of the given Object-valued property.
0353: *
0354: * @param propertyIndex the property index
0355: * @param propertyValue the computed value of the property.
0356: */
0357: protected void setPropertyState(final int propertyIndex,
0358: final Object propertyValue) {
0359: switch (propertyIndex) {
0360: case GraphicsNode.PROPERTY_FILL:
0361: setFill((PaintServer) propertyValue);
0362: break;
0363: case GraphicsNode.PROPERTY_STROKE:
0364: setStroke((PaintServer) propertyValue);
0365: break;
0366: case GraphicsNode.PROPERTY_COLOR:
0367: setColor((RGB) propertyValue);
0368: break;
0369: case GraphicsNode.PROPERTY_STROKE_DASH_ARRAY:
0370: setStrokeDashArray((float[]) propertyValue);
0371: break;
0372: default:
0373: super .setPropertyState(propertyIndex, propertyValue);
0374: break;
0375: }
0376: }
0377:
0378: /**
0379: * Sets the computed value of the given float-valued property.
0380: *
0381: * @param propertyIndex the property index
0382: * @param propertyValue the computed value of the property.
0383: */
0384: protected void setFloatPropertyState(final int propertyIndex,
0385: final float propertyValue) {
0386: switch (propertyIndex) {
0387: case GraphicsNode.PROPERTY_STROKE_WIDTH:
0388: setStrokeWidth(propertyValue);
0389: break;
0390: case GraphicsNode.PROPERTY_STROKE_MITER_LIMIT:
0391: setStrokeMiterLimit(propertyValue);
0392: break;
0393: case GraphicsNode.PROPERTY_STROKE_DASH_OFFSET:
0394: setStrokeDashOffset(propertyValue);
0395: break;
0396: default:
0397: super .setFloatPropertyState(propertyIndex, propertyValue);
0398: break;
0399: }
0400: }
0401:
0402: /**
0403: * Sets the computed value of the given packed property.
0404: *
0405: * @param propertyIndex the property index
0406: * @param propertyValue the computed value for the property.
0407: */
0408: protected void setPackedPropertyState(final int propertyIndex,
0409: final int propertyValue) {
0410: switch (propertyIndex) {
0411: case GraphicsNode.PROPERTY_FILL_RULE:
0412: if (propertyValue == 0) {
0413: setFillRule(WIND_EVEN_ODD);
0414: } else {
0415: setFillRule(WIND_NON_ZERO);
0416: }
0417: break;
0418: case GraphicsNode.PROPERTY_STROKE_LINE_JOIN:
0419: switch (propertyValue) {
0420: case CompositeGraphicsNode.JOIN_MITER_IMPL:
0421: setStrokeLineJoin(JOIN_MITER);
0422: break;
0423: case CompositeGraphicsNode.JOIN_ROUND_IMPL:
0424: setStrokeLineJoin(JOIN_ROUND);
0425: break;
0426: case CompositeGraphicsNode.JOIN_BEVEL_IMPL:
0427: default:
0428: setStrokeLineJoin(JOIN_BEVEL);
0429: break;
0430: }
0431: break;
0432: case GraphicsNode.PROPERTY_STROKE_LINE_CAP:
0433: switch (propertyValue) {
0434: case CompositeGraphicsNode.CAP_BUTT_IMPL:
0435: setStrokeLineCap(CAP_BUTT);
0436: break;
0437: case CompositeGraphicsNode.CAP_ROUND_IMPL:
0438: setStrokeLineCap(CAP_ROUND);
0439: break;
0440: case CompositeGraphicsNode.CAP_SQUARE_IMPL:
0441: default:
0442: setStrokeLineCap(CAP_SQUARE);
0443: break;
0444: }
0445: break;
0446: case GraphicsNode.PROPERTY_DISPLAY:
0447: if (propertyValue != 0) {
0448: setDisplay(true);
0449: } else {
0450: setDisplay(false);
0451: }
0452: break;
0453: case GraphicsNode.PROPERTY_VISIBILITY:
0454: if (propertyValue != 0) {
0455: setVisibility(true);
0456: } else {
0457: setVisibility(false);
0458: }
0459: break;
0460: case GraphicsNode.PROPERTY_FILL_OPACITY:
0461: setFillOpacity((propertyValue >> 7) / 200.0f);
0462: break;
0463: case GraphicsNode.PROPERTY_STROKE_OPACITY:
0464: setStrokeOpacity((propertyValue >> 15) / 200.0f);
0465: break;
0466: case GraphicsNode.PROPERTY_OPACITY:
0467: setOpacity(propertyValue / 200.0f);
0468: break;
0469: default:
0470: super .setPackedPropertyState(propertyIndex, propertyValue);
0471: break;
0472: }
0473: }
0474:
0475: /**
0476: * Recomputes the given Object-valued property's state given the new
0477: * parent property.
0478: *
0479: * @param propertyIndex index of the property whose value is changing.
0480: * @param parentPropertyValue the value that children of this node should
0481: * now inherit.
0482: */
0483: protected void recomputePropertyState(final int propertyIndex,
0484: final Object parentPropertyValue) {
0485: // We do not need to recompute the property value if:
0486: // - the property is _not_ inherited
0487: // or
0488: // - the property is inherited by the new parent property computed value
0489: // is the same as the current value.
0490: if (!((CompositeGraphicsNode) proxied)
0491: .isInherited(propertyIndex)
0492: || isPropertyState(propertyIndex, parentPropertyValue)) {
0493: // If the property is color relative, the propagation happens
0494: // through the color property changes. This means that with
0495: // currentColor, we inherit the computed value, not the specified
0496: // currentColor indirection.
0497: return;
0498: }
0499:
0500: setPropertyState(propertyIndex, parentPropertyValue);
0501: propagatePropertyState(propertyIndex, parentPropertyValue);
0502: }
0503:
0504: /**
0505: * Recomputes the given float-valued property's state given the new
0506: * parent property.
0507: *
0508: * @param propertyIndex index of the property whose value is changing.
0509: * @param parentPropertyValue the value that children of this node should
0510: * now inherit.
0511: */
0512: protected void recomputeFloatPropertyState(final int propertyIndex,
0513: final float parentPropertyValue) {
0514: // We do not need to recompute the property value if:
0515: // - the property is _not_ inherited
0516: // or
0517: // - the property is inherited by the new parent property computed value
0518: // is the same as the current value.
0519: if (!((CompositeGraphicsNode) proxied)
0520: .isInherited(propertyIndex)
0521: || isFloatPropertyState(propertyIndex,
0522: parentPropertyValue)) {
0523: // If the property is color relative, the propagation happens
0524: // through the color property changes. This means that with
0525: // currentColor, we inherit the computed value, not the specified
0526: // currentColor indirection.
0527: return;
0528: }
0529:
0530: setFloatPropertyState(propertyIndex, parentPropertyValue);
0531: propagateFloatPropertyState(propertyIndex, parentPropertyValue);
0532: }
0533:
0534: /**
0535: * Recomputes the given packed property's state given the new parent
0536: * property.
0537: *
0538: * @param propertyIndex index of the property whose value is changing.
0539: * @param parentPropertyValue the value that children of this node should
0540: * now inherit.
0541: */
0542: protected void recomputePackedPropertyState(
0543: final int propertyIndex, final int parentPropertyValue) {
0544: // We do not need to recompute the property value if:
0545: // - the property is _not_ inherited
0546: // or
0547: // - the property is inherited by the new parent property computed value
0548: // is the same as the current value.
0549: if (!((CompositeGraphicsNode) proxied)
0550: .isInherited(propertyIndex)
0551: || isPackedPropertyState(propertyIndex,
0552: parentPropertyValue)) {
0553: // If the property is color relative, the propagation happens
0554: // through the color property changes. This means that with
0555: // currentColor, we inherit the computed value, not the specified
0556: // currentColor indirection.
0557: return;
0558: }
0559:
0560: setPackedPropertyState(propertyIndex, parentPropertyValue);
0561: propagatePackedPropertyState(propertyIndex, parentPropertyValue);
0562: }
0563:
0564: /**
0565: * Called when the computed value of the given Object-valued property
0566: * has changed.
0567: *
0568: * @param propertyIndex index of the property whose value has changed.
0569: * @param parentPropertyValue the value that children of this node should
0570: * now inherit.
0571: *
0572: */
0573: protected void propagatePropertyState(final int propertyIndex,
0574: final Object parentPropertyValue) {
0575: // Propagate to expanded children.
0576: ModelNode node = firstExpandedChild;
0577: while (node != null) {
0578: node.recomputePropertyState(propertyIndex,
0579: parentPropertyValue);
0580: node = node.nextSibling;
0581: }
0582: }
0583:
0584: /**
0585: * Called when the computed value of the given float-valued property
0586: * has changed.
0587: *
0588: * @param propertyIndex index of the property whose value has changed.
0589: * @param parentPropertyValue the value that children of this node should
0590: * now inherit.
0591: *
0592: */
0593: protected void propagateFloatPropertyState(final int propertyIndex,
0594: final float parentPropertyValue) {
0595: // Propagate to expanded children.
0596: ModelNode node = firstExpandedChild;
0597: while (node != null) {
0598: node.recomputeFloatPropertyState(propertyIndex,
0599: parentPropertyValue);
0600: node = node.nextSibling;
0601: }
0602: }
0603:
0604: /**
0605: * Called when the computed value of the given packed property has changed.
0606: *
0607: * @param propertyIndex index of the property whose value has changed.
0608: * @param parentPropertyValue the value that children of this node should
0609: * now inherit.
0610: *
0611: */
0612: protected void propagatePackedPropertyState(
0613: final int propertyIndex, final int parentPropertyValue) {
0614: // Propagate to expanded children.
0615: ModelNode node = firstExpandedChild;
0616: while (node != null) {
0617: node.recomputePackedPropertyState(propertyIndex,
0618: parentPropertyValue);
0619: node = node.nextSibling;
0620: }
0621: }
0622:
0623: /**
0624: * Called by the proxied node when the given Object-valued property's
0625: * computed value has changed.
0626: *
0627: * @param propertyIndex index of the property whose value is changing.
0628: * @param proxiedComputedValue computed value for the proxied node.
0629: *
0630: */
0631: protected void proxiedPropertyStateChange(final int propertyIndex,
0632: final Object proxiedComputedValue) {
0633: if (!((CompositeGraphicsNode) proxied)
0634: .isInherited(propertyIndex)) {
0635: // The property is specified on the proxied node, update the
0636: // state with that specified value.
0637: setPropertyState(propertyIndex, proxiedComputedValue);
0638: } else {
0639: // The property is unspecified on the proxied node. Inherit from
0640: // the proxy's parent (and not the proxied's parent).
0641: setPropertyState(propertyIndex,
0642: getInheritedPropertyState(propertyIndex));
0643: }
0644:
0645: // Do not propagate changes to the proxy children: propagation happens
0646: // through the proxied's tree, so children will be notified if needed.
0647: }
0648:
0649: /**
0650: * Called by the proxied node when the given float-valued property's
0651: * computed value has changed.
0652: *
0653: * @param propertyIndex index of the property whose value is changing.
0654: * @param proxiedComputedValue computed value for the proxied node.
0655: *
0656: */
0657: protected final void proxiedFloatPropertyStateChange(
0658: final int propertyIndex, final float proxiedComputedValue) {
0659: if (!((CompositeGraphicsNode) proxied)
0660: .isInherited(propertyIndex)) {
0661: // The property is specified on the proxied node, update the
0662: // state with that specified value.
0663: setFloatPropertyState(propertyIndex, proxiedComputedValue);
0664: } else {
0665: // The property is unspecified on the proxied node. Inherit from
0666: // the proxy's parent (and not the proxied's parent).
0667: setFloatPropertyState(propertyIndex,
0668: getInheritedFloatPropertyState(propertyIndex));
0669: }
0670:
0671: // Do not propagate changes to the proxy children: propagation happens
0672: // through the proxied's tree, so children will be notified if needed.
0673: }
0674:
0675: /**
0676: * Called by the proxied node when the given packed property's computed
0677: * value has changed.
0678: *
0679: * @param propertyIndex index of the property whose value is changing.
0680: * @param proxiedComputedValue computed value for the proxied node.
0681: *
0682: */
0683: protected final void proxiedPackedPropertyStateChange(
0684: final int propertyIndex, final int proxiedComputedValue) {
0685: if (!((CompositeGraphicsNode) proxied)
0686: .isInherited(propertyIndex)) {
0687: // The property is specified on the proxied node, update the
0688: // state with that specified value.
0689: setPackedPropertyState(propertyIndex, proxiedComputedValue);
0690: } else {
0691: // The property is unspecified on the proxied node. Inherit from
0692: // the proxy's parent (and not the proxied's parent).
0693: setPackedPropertyState(propertyIndex,
0694: getInheritedPackedPropertyState(propertyIndex));
0695: }
0696:
0697: // Do not propagate changes to the proxy children: propagation happens
0698: // through the proxied's tree, so children will be notified if needed.
0699: }
0700:
0701: /**
0702: * Recomputes the transform cache, if one exists. This should recursively
0703: * call recomputeTransformState on children node or expanded content, if
0704: * any.
0705: *
0706: * By default, because a ModelNode has no transform and no cached transform,
0707: * this only does a pass down.
0708: *
0709: * @param parentTransform the Transform applied to this node's parent.
0710: */
0711: protected void recomputeTransformState(
0712: final Transform parentTransform) {
0713: txf = proxied.appendTransform(parentTransform, txf);
0714: computeCanRenderTransformBit(txf);
0715: inverseTxf = null;
0716: // inverseTxf = computeInverseTransform(txf, parentTransform,
0717: // inverseTxf);
0718: recomputeTransformState(txf, firstExpandedChild);
0719: }
0720:
0721: /**
0722: * @return this node's cached transform.
0723: */
0724: public Transform getTransformState() {
0725: return txf;
0726: }
0727:
0728: /**
0729: * @return this node's cached inverse transform.
0730: */
0731: public Transform getInverseTransformState() {
0732: if (((canRenderState & CAN_RENDER_NON_INVERTIBLE_TXF_BIT) == 0)) {
0733: if (inverseTxf == null) {
0734: // If there is a parent, check if this node's transform is the
0735: // same as the parent's in which cahse
0736: if (parent != null && txf == parent.getTransformState()) {
0737: inverseTxf = parent.getInverseTransformState();
0738: } else {
0739: inverseTxf = new Transform(null);
0740: try {
0741: inverseTxf = (Transform) txf
0742: .inverse(inverseTxf);
0743: } catch (Exception e) {
0744: // If we get an exception, then we have a real error
0745: // condition, because we just checked that the
0746: // transform was invertible.
0747: throw new Error();
0748: }
0749: }
0750: }
0751: } else {
0752: inverseTxf = null;
0753: }
0754: return inverseTxf;
0755: }
0756:
0757: /**
0758: * @return the context's fill property value
0759: */
0760: public PaintServer getFill() {
0761: return fill;
0762: }
0763:
0764: /**
0765: * @param newFill the new computed fill property.
0766: */
0767: public void setFill(final PaintServer newFill) {
0768: this .fill = newFill;
0769: }
0770:
0771: /**
0772: * @return the context's stroke property value
0773: */
0774: public PaintServer getStroke() {
0775: return stroke;
0776: }
0777:
0778: /**
0779: * @param newStroke the new computed stroke property.
0780: */
0781: public void setStroke(final PaintServer newStroke) {
0782: this .stroke = newStroke;
0783: }
0784:
0785: /**
0786: * @return the context's color property value
0787: */
0788: public RGB getColor() {
0789: return this .color;
0790: }
0791:
0792: /**
0793: * @param newColor the new computed color property.
0794: */
0795: public void setColor(final RGB newColor) {
0796: color = newColor;
0797: }
0798:
0799: /**
0800: * @return the context's fill rule property value
0801: */
0802: public int getFillRule() {
0803: if ((pack & CompositeGraphicsNode.FILL_RULE_MASK) == CompositeGraphicsNode.FILL_RULE_MASK) {
0804: return WIND_NON_ZERO;
0805: }
0806: return WIND_EVEN_ODD;
0807: }
0808:
0809: /**
0810: * @param newFillRule the new computed fillRule property value.
0811: */
0812: public final void setFillRule(final int newFillRule) {
0813: if (newFillRule == WIND_NON_ZERO) {
0814: pack |= CompositeGraphicsNode.FILL_RULE_MASK;
0815: } else {
0816: pack &= ~CompositeGraphicsNode.FILL_RULE_MASK;
0817: }
0818: }
0819:
0820: /**
0821: * @return the context's stroke-width.
0822: */
0823: public float getStrokeWidth() {
0824: return strokeWidth;
0825: }
0826:
0827: /**
0828: * @param newStrokeWidth the new computed stroke-width property value.
0829: */
0830: public void setStrokeWidth(final float newStrokeWidth) {
0831: strokeWidth = newStrokeWidth;
0832: }
0833:
0834: /**
0835: * @return the context's stroke-linecap.
0836: */
0837: public int getStrokeLineCap() {
0838: switch (pack & CompositeGraphicsNode.STROKE_LINE_CAP_MASK) {
0839: case CompositeGraphicsNode.CAP_BUTT_IMPL:
0840: return CAP_BUTT;
0841: case CompositeGraphicsNode.CAP_ROUND_IMPL:
0842: return CAP_ROUND;
0843: default:
0844: return CAP_SQUARE;
0845: }
0846: }
0847:
0848: /**
0849: * @param newStrokeLineCap the new value for the stroke-linecap property.
0850: */
0851: public void setStrokeLineCap(final int newStrokeLineCap) {
0852: // Clear stroke-linecap
0853: pack &= ~CompositeGraphicsNode.STROKE_LINE_CAP_MASK;
0854:
0855: switch (newStrokeLineCap) {
0856: case CAP_BUTT:
0857: pack |= CompositeGraphicsNode.CAP_BUTT_IMPL;
0858: break;
0859: case CAP_ROUND:
0860: pack |= CompositeGraphicsNode.CAP_ROUND_IMPL;
0861: break;
0862: default:
0863: pack |= CompositeGraphicsNode.CAP_SQUARE_IMPL;
0864: break;
0865: }
0866: }
0867:
0868: /**
0869: * @return the stroke line join property value
0870: */
0871: public int getStrokeLineJoin() {
0872: switch (pack & CompositeGraphicsNode.STROKE_LINE_JOIN_MASK) {
0873: case CompositeGraphicsNode.JOIN_MITER_IMPL:
0874: return JOIN_MITER;
0875: case CompositeGraphicsNode.JOIN_ROUND_IMPL:
0876: return JOIN_ROUND;
0877: default:
0878: return JOIN_BEVEL;
0879: }
0880: }
0881:
0882: /**
0883: * @param newStrokeLineJoin the new computed value for stroke-line-join
0884: */
0885: public void setStrokeLineJoin(final int newStrokeLineJoin) {
0886: // Clear stroke-linejoin
0887: pack &= ~CompositeGraphicsNode.STROKE_LINE_JOIN_MASK;
0888:
0889: switch (newStrokeLineJoin) {
0890: case JOIN_MITER:
0891: pack |= CompositeGraphicsNode.JOIN_MITER_IMPL;
0892: break;
0893: case JOIN_ROUND:
0894: pack |= CompositeGraphicsNode.JOIN_ROUND_IMPL;
0895: break;
0896: default:
0897: pack |= CompositeGraphicsNode.JOIN_BEVEL_IMPL;
0898: break;
0899: }
0900: }
0901:
0902: /**
0903: * @return the context's stroke miter limit property value
0904: */
0905: public float getStrokeMiterLimit() {
0906: return strokeMiterLimit;
0907: }
0908:
0909: /**
0910: * @param newStrokeMiterLimit the new computed stroke-miterlimit property.
0911: */
0912: public void setStrokeMiterLimit(final float newStrokeMiterLimit) {
0913: strokeMiterLimit = newStrokeMiterLimit;
0914: }
0915:
0916: /**
0917: * @return the stroke dash offset property
0918: */
0919: public float getStrokeDashOffset() {
0920: return strokeDashOffset;
0921: }
0922:
0923: /**
0924: * @param newStrokeDashOffset the new stroke-dashoffset computed property
0925: * value.
0926: */
0927: public void setStrokeDashOffset(final float newStrokeDashOffset) {
0928: strokeDashOffset = newStrokeDashOffset;
0929: }
0930:
0931: /**
0932: * @return the stroke dash array property
0933: */
0934: public float[] getStrokeDashArray() {
0935: return strokeDashArray;
0936: }
0937:
0938: /**
0939: * @param newStrokeDashArray the new computed stroke-dasharray property
0940: * value.
0941: */
0942: public void setStrokeDashArray(final float[] newStrokeDashArray) {
0943: strokeDashArray = newStrokeDashArray;
0944: }
0945:
0946: /**
0947: * @return the context' display property value
0948: */
0949: public boolean getDisplay() {
0950: return ((pack & CompositeGraphicsNode.DISPLAY_MASK) == CompositeGraphicsNode.DISPLAY_MASK);
0951: }
0952:
0953: /**
0954: * @param newDisplay the new computed display value
0955: */
0956: public void setDisplay(final boolean newDisplay) {
0957: if (newDisplay) {
0958: pack |= CompositeGraphicsNode.DISPLAY_MASK;
0959: } else {
0960: pack &= ~CompositeGraphicsNode.DISPLAY_MASK;
0961: }
0962:
0963: computeCanRenderDisplayBit(newDisplay);
0964: }
0965:
0966: /**
0967: * @return the visibility property value.
0968: */
0969: public boolean getVisibility() {
0970: return ((pack & CompositeGraphicsNode.VISIBILITY_MASK) == CompositeGraphicsNode.VISIBILITY_MASK);
0971: }
0972:
0973: /**
0974: * @param newVisibility the new computed visibility property.
0975: */
0976: public void setVisibility(final boolean newVisibility) {
0977: if (newVisibility) {
0978: pack |= CompositeGraphicsNode.VISIBILITY_MASK;
0979: } else {
0980: pack &= ~CompositeGraphicsNode.VISIBILITY_MASK;
0981: }
0982: }
0983:
0984: /**
0985: * @return the context's fill opacity property value
0986: */
0987: public float getFillOpacity() {
0988: return ((pack & CompositeGraphicsNode.FILL_OPACITY_MASK) >> 7) / 200.0f;
0989: }
0990:
0991: /**
0992: * @param newFillOpacity the new computed value for the fill opacity
0993: * property.
0994: */
0995: public void setFillOpacity(final float newFillOpacity) {
0996: pack &= ~CompositeGraphicsNode.FILL_OPACITY_MASK;
0997: pack |= ((((int) (newFillOpacity * 200)) << 7) & CompositeGraphicsNode.FILL_OPACITY_MASK);
0998: }
0999:
1000: /**
1001: * @return the stroke opacity value
1002: */
1003: public float getStrokeOpacity() {
1004: return ((pack & CompositeGraphicsNode.STROKE_OPACITY_MASK) >> 15) / 200.0f;
1005: }
1006:
1007: /**
1008: * @param newStrokeOpacity the new computed stroke-opacity property.
1009: */
1010: public void setStrokeOpacity(final float newStrokeOpacity) {
1011: pack &= ~CompositeGraphicsNode.STROKE_OPACITY_MASK;
1012: pack |= ((((int) (newStrokeOpacity * 200)) << 15) & CompositeGraphicsNode.STROKE_OPACITY_MASK);
1013: }
1014:
1015: /**
1016: * @return the opacity value
1017: */
1018: public float getOpacity() {
1019: return (pack2 & CompositeGraphicsNode.OPACITY_MASK) / 200.0f;
1020: }
1021:
1022: /**
1023: * @param newOpacity the new computed opacity property.
1024: */
1025: public void setOpacity(final float newOpacity) {
1026: pack2 &= ~CompositeGraphicsNode.OPACITY_MASK;
1027: pack2 |= (((int) (newOpacity * 200)) & CompositeGraphicsNode.OPACITY_MASK);
1028: }
1029:
1030: /**
1031: * This method is used to implement the PaintTarget interface which is used
1032: * to compute the rendering area. However, the paint server updates are
1033: * handled by the proxied node, so this should _never_ be called.
1034: *
1035: * @param paintType the key provided by the PaintTarget when it subscribed
1036: * to associated PaintServer.
1037: * @param paintServer the PaintServer generating the update.
1038: */
1039: public void onPaintServerUpdate(final String paintType,
1040: final PaintServer paintServer) {
1041: // Do nothing.
1042: }
1043: }
|