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]

Reply via email to