Attached is the patch to support override styles and a simple test file I was using. I decided to make CSSEngine.invalidateProperties public. It was too much of a hassle to do it otherwise. Please have a look and tell me if I've done anything wrong.
One thing I couldn't test properly is the handling of shorthand properties. I couldn't get the shorthand font property to work normally in Batik. For example, this: <svg xmlns="http://www.w3.org/2000/svg" width="400" height="400"> <text x="100" y="100" style="font: 48 serif">some text</text> </svg> just displays the text in the default font and size. I'll fax off the CLA later today some time. Cameron -- Cameron McCormack | Web: http://mcc.id.au/ | ICQ: 26955922
diff -ur -x CVS xml-batik/sources/org/apache/batik/css/engine/CSSEngine.java xml-batik.csvg/sources/org/apache/batik/css/engine/CSSEngine.java --- xml-batik/sources/org/apache/batik/css/engine/CSSEngine.java 2003-12-17 11:21:27.000000000 +1100 +++ xml-batik.csvg/sources/org/apache/batik/css/engine/CSSEngine.java 2003-12-17 12:15:13.000000000 +1100 @@ -70,6 +73,7 @@ import org.apache.batik.css.engine.value.Value; import org.apache.batik.css.engine.value.ValueManager; import org.apache.batik.css.parser.ExtendedParser; +import org.apache.batik.dom.svg.SVGStylableElement; import org.apache.batik.util.CSSConstants; import org.apache.batik.util.ParsedURL; import org.w3c.css.sac.CSSException; @@ -795,6 +821,23 @@ } } } + + // Apply the override rules to the result. + SVGStylableElement.OverrideStyleDeclaration over = + ((SVGStylableElement) elt).getOverrideStyleDeclaration(); + int ol = over.getLength(); + for (int i = 0; i < ol; i++) { + String nm = over.item(i); + Value val = over.getValue(nm); + boolean imp = over.isImportant(nm); + int idx = getPropertyIndex(nm); + short rorg = result.getOrigin(idx); + if (!result.isImportant(idx) || imp) { + result.putValue(idx, val); + result.putImportant(idx, imp); + result.putOrigin(idx, StyleMap.OVERRIDE_ORIGIN); + } + } } finally { element = null; cssBaseURI = null; @@ -1231,6 +1274,9 @@ case StyleMap.AUTHOR_ORIGIN: cond = !dimp || imp; break; + case StyleMap.OVERRIDE_ORIGIN: + cond = false; + break; default: cond = true; } @@ -1831,11 +1877,13 @@ // Check if the style map has cascaded styles which // come from the inline style attribute. for (int i = getNumberOfProperties() - 1; i >= 0; --i) { - if (style.isComputed(i) && - style.getOrigin(i) == StyleMap.INLINE_AUTHOR_ORIGIN && - !updated[i]) { - removed = true; - updated[i] = true; + if (style.isComputed(i) && !updated[i]) { + short origin = style.getOrigin(i); + if (origin == StyleMap.INLINE_AUTHOR_ORIGIN || + origin == StyleMap.OVERRIDE_ORIGIN) { + removed = true; + updated[i] = true; + } } } } @@ -1906,10 +1954,10 @@ * Invalidates all the properties of the given node. * */ - protected void invalidateProperties(Node node, - int [] properties, - boolean [] updated, - boolean recascade) { + public void invalidateProperties(Node node, + int [] properties, + boolean [] updated, + boolean recascade) { if (!(node instanceof CSSStylableElement)) return; // Not Stylable sub tree @@ -2146,9 +2194,7 @@ return; } - switch (style.getOrigin(idx)) { - case StyleMap.AUTHOR_ORIGIN: - case StyleMap.INLINE_AUTHOR_ORIGIN: + if (style.getOrigin(idx) >= StyleMap.AUTHOR_ORIGIN) { // The current value has a greater priority return; } diff -ur -x CVS xml-batik/sources/org/apache/batik/css/engine/StyleMap.java xml-batik.csvg/sources/org/apache/batik/css/engine/StyleMap.java --- xml-batik/sources/org/apache/batik/css/engine/StyleMap.java 2003-12-17 11:21:28.000000000 +1100 +++ xml-batik.csvg/sources/org/apache/batik/css/engine/StyleMap.java 2003-12-17 11:15:40.000000000 +1100 @@ -86,6 +86,7 @@ public final static short NON_CSS_ORIGIN = 0x4000; // 0100 public final static short AUTHOR_ORIGIN = 0x6000; // 0110 public final static short INLINE_AUTHOR_ORIGIN = (short)0x8000; // 1000 + public final static short OVERRIDE_ORIGIN = (short) 0xA000; // 1010 /** * The values. diff -ur -x CVS xml-batik/sources/org/apache/batik/dom/svg/SVGOMDocument.java xml-batik.csvg/sources/org/apache/batik/dom/svg/SVGOMDocument.java --- xml-batik/sources/org/apache/batik/dom/svg/SVGOMDocument.java 2003-12-17 11:21:41.000000000 +1100 +++ xml-batik.csvg/sources/org/apache/batik/dom/svg/SVGOMDocument.java 2003-12-17 11:15:41.000000000 +1100 @@ -456,7 +476,10 @@ */ public CSSStyleDeclaration getOverrideStyle(Element elt, String pseudoElt) { - throw new RuntimeException(" !!! Not implemented"); + if (elt instanceof SVGStylableElement) { + return ((SVGStylableElement) elt).getOverrideStyleDeclaration(); + } + return null; } /** diff -ur -x CVS xml-batik/sources/org/apache/batik/dom/svg/SVGStylableElement.java xml-batik.csvg/sources/org/apache/batik/dom/svg/SVGStylableElement.java --- xml-batik/sources/org/apache/batik/dom/svg/SVGStylableElement.java 2003-12-17 11:21:45.000000000 +1100 +++ xml-batik.csvg/sources/org/apache/batik/dom/svg/SVGStylableElement.java 2003-12-17 12:14:50.000000000 +1100 @@ -89,6 +89,11 @@ protected StyleMap computedStyleMap; /** + * The override style declaration. + */ + protected OverrideStyleDeclaration overrideStyleDeclaration; + + /** * Creates a new SVGStylableElement object. */ protected SVGStylableElement() { @@ -103,6 +108,18 @@ super(prefix, owner); } + /** + * Returns the override style map for this element. + */ + public OverrideStyleDeclaration getOverrideStyleDeclaration() { + if (overrideStyleDeclaration == null) { + CSSEngine cssEngine = + ((SVGOMDocument) getOwnerDocument()).getCSSEngine(); + overrideStyleDeclaration = new OverrideStyleDeclaration(cssEngine); + } + return overrideStyleDeclaration; + } + // CSSStylableElement ////////////////////////////////////////// /** @@ -536,36 +553,26 @@ } /** - * This class represents the 'style' attribute. + * Class from which StyleDeclaration and OverrideStyleDeclaration derive. */ - public class StyleDeclaration + protected abstract class AbstractStyleDeclaration extends CSSOMSVGStyleDeclaration - implements LiveAttributeValue, - CSSOMSVGStyleDeclaration.ValueProvider, - CSSOMSVGStyleDeclaration.ModificationHandler, + implements CSSOMSVGStyleDeclaration.ValueProvider, + CSSOMSVGStyleDeclaration.ModificationHandler, CSSEngine.MainPropertyReceiver { - + /** * The associated CSS object. */ protected org.apache.batik.css.engine.StyleDeclaration declaration; /** - * Whether the mutation comes from this object. + * Creates a new AbstractStyleDeclaration. */ - protected boolean mutate; - - /** - * Creates a new StyleDeclaration. - */ - public StyleDeclaration(CSSEngine eng) { + public AbstractStyleDeclaration(CSSEngine eng) { super(null, null, eng); valueProvider = this; setModificationHandler(this); - - declaration = cssEngine.parseStyleDeclaration - (SVGStylableElement.this, - getAttributeNS(null, SVG_STYLE_ATTRIBUTE)); } // ValueProvider //////////////////////////////////////// @@ -611,11 +618,35 @@ } /** - * Returns the value at the given. + * Returns the name of the property at the given index. */ public String item(int idx) { return cssEngine.getPropertyName(declaration.getIndex(idx)); } + } + + /** + * This class represents the 'style' attribute. + */ + public class StyleDeclaration + extends AbstractStyleDeclaration + implements LiveAttributeValue { + + /** + * Whether the mutation comes from this object. + */ + protected boolean mutate; + + /** + * Creates a new StyleDeclaration. + */ + public StyleDeclaration(CSSEngine eng) { + super(eng); + + declaration = cssEngine.parseStyleDeclaration + (SVGStylableElement.this, + getAttributeNS(null, SVG_STYLE_ATTRIBUTE)); + } // LiveAttributeValue ////////////////////////////////////// @@ -652,7 +683,7 @@ // ModificationHandler //////////////////////////////////// /** - * Called when the value text has changed. + * Called when the declaration text has changed. */ public void textChanged(String text) throws DOMException { declaration = cssEngine.parseStyleDeclaration @@ -700,7 +731,7 @@ */ public void propertyChanged(String name, String value, String prio) throws DOMException { - boolean important = ((prio != null) && (prio.length() >0)); + boolean important = ((prio != null) && (prio.length() > 0)); cssEngine.setMainProperties(SVGStylableElement.this, this, name, value, important); mutate = true; @@ -709,11 +740,98 @@ mutate = false; } } -} + /** + * This class is a CSSStyleDeclaration for the override style of + * an element. + */ + public class OverrideStyleDeclaration + extends AbstractStyleDeclaration { + /** + * Array to hold which properties have been changed by a call to + * CSSEngine.setMainProperties. + */ + boolean[] mainPropertiesChanged; + /** + * Creates a new OverrideStyleDeclaration. + */ + public OverrideStyleDeclaration(CSSEngine eng) { + super(eng); + declaration = new org.apache.batik.css.engine.StyleDeclaration(); + } + // ModificationHandler //////////////////////////////////// + /** + * Called when the declaration text has changed. + */ + public void textChanged(String text) throws DOMException { + int ds = declaration.size(); + boolean[] updated = new boolean[cssEngine.getNumberOfProperties()]; + for (int i = 0; i < ds; i++) { + updated[declaration.getIndex(i)] = true; + } + declaration = cssEngine.parseStyleDeclaration + (SVGStylableElement.this, text); + ds = declaration.size(); + for (int i = 0; i < ds; i++) { + updated[declaration.getIndex(i)] = true; + } + cssEngine.invalidateProperties + (SVGStylableElement.this, null, updated, true); + } + + // CSSEngine.MainPropertyReceiver ///////////////////////// + + public void setMainProperty(String name, Value v, boolean important) { + int idx = cssEngine.getPropertyIndex(name); + if (idx == -1) + return; // unknown property + mainPropertiesChanged[idx] = true; + int i=0; + for (; i < declaration.size(); i++) { + if (idx == declaration.getIndex(i)) + break; + } + if (i < declaration.size()) + declaration.put(i, v, idx, important); + else + declaration.append(v, idx, important); + } + + /** + * Called when a property was removed. + */ + public void propertyRemoved(String name) throws DOMException { + int idx = cssEngine.getPropertyIndex(name); + for (int i = 0; i < declaration.size(); i++) { + if (idx == declaration.getIndex(i)) { + declaration.remove(i); + int[] props = { idx }; + cssEngine.invalidateProperties + (SVGStylableElement.this, props, null, true); + return; + } + } + } + + /** + * Called when a property was changed. + */ + public void propertyChanged(String name, String value, String prio) + throws DOMException { + boolean important = ((prio != null) && (prio.length() > 0)); + int np = cssEngine.getNumberOfProperties(); + mainPropertiesChanged = new boolean[np]; + cssEngine.setMainProperties(SVGStylableElement.this, + this, name, value, important); + cssEngine.invalidateProperties + (SVGStylableElement.this, null, mainPropertiesChanged, true); + } + } + +}
<<attachment: test1.svg>>
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]