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]
