You are viewing a plain text version of this content. The canonical link for it is here.
Posted to batik-commits@xmlgraphics.apache.org by de...@apache.org on 2006/04/22 18:05:18 UTC

svn commit: r396138 [2/3] - in /xmlgraphics/batik/trunk/sources/org/apache/batik: apps/rasterizer/ apps/svgbrowser/ bridge/ css/dom/ css/engine/ css/engine/value/ dom/svg/ ext/awt/image/rendered/ extension/ gvt/event/ swing/gvt/ swing/svg/ transcoder/p...

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSEngine.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSEngine.java?rev=396138&r1=396137&r2=396138&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSEngine.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/CSSEngine.java Sat Apr 22 09:05:15 2006
@@ -1,6 +1,6 @@
 /*
 
-   Copyright 2002-2006  The Apache Software Foundation 
+   Copyright 2002-2006  The Apache Software Foundation
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -39,6 +39,7 @@
 import org.apache.batik.css.parser.ExtendedParser;
 import org.apache.batik.util.CSSConstants;
 import org.apache.batik.util.ParsedURL;
+
 import org.w3c.css.sac.CSSException;
 import org.w3c.css.sac.DocumentHandler;
 import org.w3c.css.sac.InputSource;
@@ -56,6 +57,7 @@
 import org.w3c.dom.events.EventTarget;
 import org.w3c.dom.events.MutationEvent;
 
+
 /**
  * This is the base class for all the CSS engines.
  *
@@ -127,7 +129,7 @@
      * The CSS context.
      */
     protected CSSContext cssContext;
-    
+
     /**
      * The associated document.
      */
@@ -223,7 +225,7 @@
      * The style attribute local name.
      */
     protected String styleLocalName;
-    
+
     /**
      * The class attribute namespace URI.
      */
@@ -233,7 +235,7 @@
      * The class attribute local name.
      */
     protected String classLocalName;
-    
+
     /**
      * The non CSS presentational hints.
      */
@@ -754,11 +756,19 @@
                     Node attr = attrs.item(i);
                     String an = attr.getNodeName();
                     if (nonCSSPresentationalHints.contains(an)) {
+                      String attrValue = attr.getNodeValue();          // -- dvh
                         try {
                             LexicalUnit lu;
                             lu = parser.parsePropertyValue(attr.getNodeValue());
                             ph.property(an, lu, false);
                         } catch (Exception e) {
+
+                          System.err.println("\n***** CSSEngine: exception property.syntax.error:" + e );  // ---
+                          System.err.println("\nAttrValue:" + attrValue );
+                          System.err.println("\nException:" + e.getClass().getName() );
+                          e.printStackTrace( System.err );                           // ---
+                          System.err.println("\n***** CSSEngine: exception...." );   // ---
+
                             String m = e.getMessage();
                             if (m == null) m = "";
                             String u = ((documentURI == null)?"<unknown>":
@@ -808,6 +818,11 @@
                         parser.parseStyleDeclaration(style);
                         styleDeclarationDocumentHandler.styleMap = null;
                     } catch (Exception e) {
+                      System.err.println("\n***** CSSEngine: exception style.syntax.error:" + e );  // ---
+                      System.err.println("\nException:" + e.getClass().getName() );
+                      e.printStackTrace( System.err );                           // ---
+                      System.err.println("\n***** CSSEngine: exception...." );   // ---
+
                         String m = e.getMessage();
                         if (m == null) m = "";
                         String u = ((documentURI == null)?"<unknown>":
@@ -861,14 +876,14 @@
         }
 
         Value value = sm.getValue(propidx);
-        if (sm.isComputed(propidx)) 
+        if (sm.isComputed(propidx))
             return value;
 
         Value result = value;
         ValueManager vm = valueManagers[propidx];
         CSSStylableElement p = getParentCSSStylableElement(elt);
         if (value == null) {
-            if ((p == null) || !vm.isInheritedProperty()) 
+            if ((p == null) || !vm.isInheritedProperty())
                 result = vm.getDefaultValue();
         } else if ((p != null) && (value == InheritValue.INSTANCE)) {
             result = null;
@@ -974,7 +989,7 @@
          * Called with a non-shorthand property name and it's value.
          */
         public void setMainProperty(String name, Value v, boolean important);
-    };
+    }
 
     public void setMainProperties
         (CSSStylableElement elt, final MainPropertyReceiver dst,
@@ -1004,7 +1019,7 @@
             ph.property(pname, lu, important);
         } catch (Exception e) {
             String m = e.getMessage();
-            if (m == null) m = "";
+            if (m == null) m = "";                  // todo - better handling of NPE
             String u = ((documentURI == null)?"<unknown>":
                         documentURI.toString());
             String s = Messages.formatMessage
@@ -1151,7 +1166,7 @@
             return;
         }
 
-	try {
+    try {
             // Check that access to the uri is allowed
              ParsedURL pDocURL = null;
              if (documentURI != null) {
@@ -1159,10 +1174,10 @@
              }
              ParsedURL pURL = new ParsedURL(uri);
              cssContext.checkLoadExternalResource(pURL, pDocURL);
-             
+
              parseStyleSheet(ss, new InputSource(uri.toString()), uri);
-	} catch (SecurityException e) {
-            throw e; 
+    } catch (SecurityException e) {
+            throw e;
         } catch (Exception e) {
             String m = e.getMessage();
             if (m == null) m = "";
@@ -1408,23 +1423,23 @@
      * CSSEngine object.
      */
     protected boolean mediaMatch(SACMediaList ml) {
-	if (media == null ||
+    if (media == null ||
             ml == null ||
             media.getLength() == 0 ||
             ml.getLength() == 0) {
-	    return true;
-	}
-	for (int i = 0; i < ml.getLength(); i++) {
+        return true;
+    }
+    for (int i = 0; i < ml.getLength(); i++) {
             if (ml.item(i).equalsIgnoreCase("all"))
                 return true;
-	    for (int j = 0; j < media.getLength(); j++) {
-		if (media.item(j).equalsIgnoreCase("all") ||
+        for (int j = 0; j < media.getLength(); j++) {
+        if (media.item(j).equalsIgnoreCase("all") ||
                     ml.item(i).equalsIgnoreCase(media.item(j))) {
-		    return true;
-		}
-	    }
-	}
-	return false;
+            return true;
+        }
+        }
+    }
+    return false;
     }
 
     /**
@@ -1434,7 +1449,7 @@
         extends DocumentAdapter
         implements ShorthandManager.PropertyHandler {
         public StyleMap styleMap;
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * DocumentHandler#property(String,LexicalUnit,boolean)}.
@@ -1467,7 +1482,7 @@
         extends DocumentAdapter
         implements ShorthandManager.PropertyHandler {
         public StyleDeclaration styleDeclaration;
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * DocumentHandler#property(String,LexicalUnit,boolean)}.
@@ -1509,27 +1524,27 @@
         public void startDocument(InputSource source)
             throws CSSException {
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * DocumentHandler#endDocument(InputSource)}.
          */
         public void endDocument(InputSource source) throws CSSException {
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * org.w3c.css.sac.DocumentHandler#ignorableAtRule(String)}.
          */
         public void ignorableAtRule(String atRule) throws CSSException {
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * DocumentHandler#importStyle(String,SACMediaList,String)}.
          */
         public void importStyle(String       uri,
-                                SACMediaList media, 
+                                SACMediaList media,
                                 String       defaultNamespaceURI)
             throws CSSException {
             ImportRule ir = new ImportRule();
@@ -1545,7 +1560,7 @@
             }
             styleSheet.append(ir);
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * org.w3c.css.sac.DocumentHandler#startMedia(SACMediaList)}.
@@ -1557,7 +1572,7 @@
             styleSheet.append(mr);
             styleSheet = mr;
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * org.w3c.css.sac.DocumentHandler#endMedia(SACMediaList)}.
@@ -1565,15 +1580,15 @@
         public void endMedia(SACMediaList media) throws CSSException {
             styleSheet = styleSheet.getParent();
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * org.w3c.css.sac.DocumentHandler#startPage(String,String)}.
-         */    
+         */
         public void startPage(String name, String pseudo_page)
             throws CSSException {
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * org.w3c.css.sac.DocumentHandler#endPage(String,String)}.
@@ -1581,7 +1596,7 @@
         public void endPage(String name, String pseudo_page)
             throws CSSException {
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * org.w3c.css.sac.DocumentHandler#startFontFace()}.
@@ -1589,7 +1604,7 @@
         public void startFontFace() throws CSSException {
             styleDeclaration = new StyleDeclaration();
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * org.w3c.css.sac.DocumentHandler#endFontFace()}.
@@ -1602,7 +1617,7 @@
                 sm.putValue(idx, styleDeclaration.getValue(i));
                 sm.putImportant(idx, styleDeclaration.getPriority(i));
                 // Not sure on this..
-                sm.putOrigin(idx, StyleMap.AUTHOR_ORIGIN); 
+                sm.putOrigin(idx, StyleMap.AUTHOR_ORIGIN);
             }
             styleDeclaration = null;
 
@@ -1615,7 +1630,7 @@
             if (base != null) purl = new ParsedURL(base);
             fontFaces.add(new FontFaceRule(sm, purl));
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * org.w3c.css.sac.DocumentHandler#startSelector(SelectorList)}.
@@ -1627,7 +1642,7 @@
             styleRule.setStyleDeclaration(styleDeclaration);
             styleSheet.append(styleRule);
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * org.w3c.css.sac.DocumentHandler#endSelector(SelectorList)}.
@@ -1662,7 +1677,9 @@
     }
 
     /**
-     * Provides an adapter for the DocumentHandler interface.
+     * Provides an (empty) adapter for the DocumentHandler interface.
+     * Most methods just throw an UnsupportedOperationException, so
+     * the subclasses <i>must</i> override them with 'real' methods.
      */
     protected static class DocumentAdapter implements DocumentHandler {
 
@@ -1670,131 +1687,130 @@
          * <b>SAC</b>: Implements {@link
          * DocumentHandler#startDocument(InputSource)}.
          */
-        public void startDocument(InputSource source)
-            throws CSSException {
-            throw new InternalError();
+        public void startDocument(InputSource source){
+            throwUnsupportedEx();
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * DocumentHandler#endDocument(InputSource)}.
          */
-        public void endDocument(InputSource source) throws CSSException {
-            throw new InternalError();
+        public void endDocument(InputSource source) {
+            throwUnsupportedEx();
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * DocumentHandler#comment(String)}.
          */
-        public void comment(String text) throws CSSException {
+        public void comment(String text) {
             // We always ignore the comments.
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * DocumentHandler#ignorableAtRule(String)}.
          */
-        public void ignorableAtRule(String atRule) throws CSSException {
-            throw new InternalError();
+        public void ignorableAtRule(String atRule) {
+            throwUnsupportedEx();
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * DocumentHandler#namespaceDeclaration(String,String)}.
          */
-        public void namespaceDeclaration(String prefix, String uri) 
-            throws CSSException {
-            throw new InternalError();
+        public void namespaceDeclaration(String prefix, String uri) {
+            throwUnsupportedEx();
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * DocumentHandler#importStyle(String,SACMediaList,String)}.
          */
         public void importStyle(String       uri,
-                                SACMediaList media, 
-                                String       defaultNamespaceURI)
-            throws CSSException {
-            throw new InternalError();
+                                SACMediaList media,
+                                String       defaultNamespaceURI) {
+            throwUnsupportedEx();
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * DocumentHandler#startMedia(SACMediaList)}.
          */
-        public void startMedia(SACMediaList media) throws CSSException {
-            throw new InternalError();
+        public void startMedia(SACMediaList media) {
+            throwUnsupportedEx();
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * DocumentHandler#endMedia(SACMediaList)}.
          */
-        public void endMedia(SACMediaList media) throws CSSException {
-            throw new InternalError();
+        public void endMedia(SACMediaList media) {
+            throwUnsupportedEx();
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * DocumentHandler#startPage(String,String)}.
-         */    
-        public void startPage(String name, String pseudo_page)
-            throws CSSException {
-            throw new InternalError();
+         */
+        public void startPage(String name, String pseudo_page) {
+            throwUnsupportedEx();
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * DocumentHandler#endPage(String,String)}.
          */
-        public void endPage(String name, String pseudo_page)
-            throws CSSException {
-            throw new InternalError();
+        public void endPage(String name, String pseudo_page) {
+            throwUnsupportedEx();
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link DocumentHandler#startFontFace()}.
          */
-        public void startFontFace() throws CSSException {
-            throw new InternalError();
+        public void startFontFace() {
+            throwUnsupportedEx();
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link DocumentHandler#endFontFace()}.
          */
-        public void endFontFace() throws CSSException {
-            throw new InternalError();
+        public void endFontFace() {
+            throwUnsupportedEx();
         }
-        
+
         /**
          * <b>SAC</b>: Implements {@link
          * DocumentHandler#startSelector(SelectorList)}.
          */
-        public void startSelector(SelectorList selectors) throws CSSException {
-            throw new InternalError();
+        public void startSelector(SelectorList selectors) {
+            throwUnsupportedEx();
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * DocumentHandler#endSelector(SelectorList)}.
          */
-        public void endSelector(SelectorList selectors) throws CSSException {
-            throw new InternalError();
+        public void endSelector(SelectorList selectors) {
+            throwUnsupportedEx();
         }
-    
+
         /**
          * <b>SAC</b>: Implements {@link
          * DocumentHandler#property(String,LexicalUnit,boolean)}.
          */
-        public void property(String name, LexicalUnit value, boolean important)
-            throws CSSException {
-            throw new InternalError();
+        public void property(String name, LexicalUnit value, boolean important) {
+            throwUnsupportedEx();
+        }
+
+
+        private void throwUnsupportedEx(){
+            throw new UnsupportedOperationException("you try to use an empty method in Adapter-class" );
         }
     }
 
     // CSS events /////////////////////////////////////////////////////////
-    
+
     protected final static CSSEngineListener[] LISTENER_ARRAY =
         new CSSEngineListener[0];
 
@@ -1829,7 +1845,7 @@
     }
 
     // Dynamic updates ////////////////////////////////////////////////////
-    
+
     /**
      * Called when the inline style of the given element has been updated.
      */
@@ -1844,7 +1860,7 @@
         }
 
         switch (attrChange) {
-        case MutationEvent.ADDITION:
+        case MutationEvent.ADDITION:            // intentional fall-through
         case MutationEvent.MODIFICATION:
             if (newValue.length() > 0) {
                 element = elt;
@@ -1904,11 +1920,11 @@
                 boolean cl = (colorIndex == -1)
                     ? false
                     : updated[colorIndex];
-                
+
                 for (int i = getNumberOfProperties() - 1; i >= 0; --i) {
                     if (updated[i]) {
                         count++;
-                    } 
+                    }
                     else if ((fs && style.isFontSizeRelative(i)) ||
                              (lh && style.isLineHeightRelative(i)) ||
                              (cl && style.isColorRelative(i))) {
@@ -1933,7 +1949,7 @@
 
         default:
             // Must not happen
-            throw new InternalError("Invalid attrChangeType");
+            throw new IllegalStateException("Invalid attrChangeType");
         }
     }
 
@@ -1954,10 +1970,10 @@
 
     /**
      * Invalidates all the properties of the given node.
-     * 
+     *
      */
-    protected void invalidateProperties(Node node, 
-                                        int [] properties, 
+    protected void invalidateProperties(Node node,
+                                        int [] properties,
                                         boolean [] updated,
                                         boolean recascade) {
 
@@ -1968,12 +1984,10 @@
         StyleMap style = elt.getComputedStyleMap(null);
         if (style == null)
             return;  // Nothing to invalidate.
-        
+
         boolean [] diffs = new boolean[getNumberOfProperties()];
         if (updated != null) {
-            for (int i=0; i< updated.length; i++) {
-                diffs[i] = updated[i];
-            }
+            System.arraycopy( updated, 0, diffs, 0, updated.length );
         }
         if (properties != null) {
             for (int i=0; i<properties.length; i++) {
@@ -2038,7 +2052,7 @@
      * again to see if the any new rules apply (or old rules don't
      * apply).
      */
-    protected void propagateChanges(Node node, int[] props, 
+    protected void propagateChanges(Node node, int[] props,
                                     boolean recascade) {
         if (!(node instanceof CSSStylableElement))
             return;
@@ -2098,7 +2112,7 @@
 
         int [] inherited = props;
         if (props != null) {
-            // Filter out uninheritable properties when we 
+            // Filter out uninheritable properties when we
             // propogate to children.
             int count = 0;
             for (int i=0; i<props.length; i++) {
@@ -2106,7 +2120,7 @@
                 if (vm.isInheritedProperty()) count++;
                 else props[i] = -1;
             }
-            
+
             if (count == 0) {
                 // nothing to propogate for sure
                 inherited = null;
@@ -2123,10 +2137,7 @@
              n != null;
              n = getCSSNextSibling(n)) {
             if (n.getNodeType() == Node.ELEMENT_NODE) {
-                // XXX Should this invalidateProperties be called on eng?
-                // In r216064 with CSSImportedElementRoot, the imported
-                // element's CSSEngine was indeed used.
-                // CSSEngine eng = cssContext.getCSSEngineForElement((Element) n);
+                CSSEngine eng = cssContext.getCSSEngineForElement((Element) n);
                 invalidateProperties(n, inherited, null, recascade);
             }
         }
@@ -2196,9 +2207,9 @@
             // The current value has a greater priority
             return;
         }
-        
+
         switch (attrChange) {
-        case MutationEvent.ADDITION:
+        case MutationEvent.ADDITION:   // intentional fall-through
         case MutationEvent.MODIFICATION:
             element = elt;
             try {
@@ -2226,7 +2237,7 @@
             }
             break;
 
-        case MutationEvent.REMOVAL: 
+        case MutationEvent.REMOVAL:
             {
                 int [] invalid = { idx };
                 invalidateProperties(elt, invalid, null, true);
@@ -2288,10 +2299,10 @@
         }
 
         String attrNS = attr.getNamespaceURI();
-        String name   = ((attrNS == null) ? 
+        String name   = ((attrNS == null) ?
                          attr.getNodeName() :
                          attr.getLocalName());
-            
+
         CSSStylableElement elt = (CSSStylableElement)e;
         StyleMap style = elt.getComputedStyleMap(null);
         if (style != null) {
@@ -2358,7 +2369,7 @@
             if (newNode instanceof CSSStyleSheetNode) {
                 styleSheetNodes = null;
                 // Invalidate all the CSSStylableElements in the document.
-                invalidateProperties(document.getDocumentElement(), 
+                invalidateProperties(document.getDocumentElement(),
                                      null, null, true);
             } else if (newNode instanceof CSSStylableElement) {
                 // Invalidate the CSSStylableElement siblings, to
@@ -2399,7 +2410,7 @@
                 styleSheetNodes = null;
 
                 // Invalidate all the CSSStylableElements in the document.
-                invalidateProperties(document.getDocumentElement(), 
+                invalidateProperties(document.getDocumentElement(),
                                      null, null, true);
             } else if (removedStylableElementSibling != null) {
                 // Invalidate the CSSStylableElement siblings, to
@@ -2421,7 +2432,7 @@
             if (getCSSParentNode(text) instanceof CSSStyleSheetNode) {
                 styleSheetNodes = null;
                 // Invalidate all the CSSStylableElements in the document.
-                invalidateProperties(document.getDocumentElement(), 
+                invalidateProperties(document.getDocumentElement(),
                                      null, null, true);
             }
         }
@@ -2535,7 +2546,7 @@
             if (et instanceof CSSStyleSheetNode) {
                 styleSheetNodes = null;
                 // Invalidate all the CSSStylableElements in the document.
-                invalidateProperties(document.getDocumentElement(), 
+                invalidateProperties(document.getDocumentElement(),
                                      null, null, true);
                 return;
             }
@@ -2584,7 +2595,7 @@
                 styleSheetNodes = null;
 
                 // Invalidate all the CSSStylableElements in the document.
-                invalidateProperties(document.getDocumentElement(), 
+                invalidateProperties(document.getDocumentElement(),
                                      null, null, true);
             } else if (removedStylableElementSibling != null) {
                 // Invalidate the CSSStylableElement siblings, to
@@ -2609,7 +2620,7 @@
             if (n.getParentNode() instanceof CSSStyleSheetNode) {
                 styleSheetNodes = null;
                 // Invalidate all the CSSStylableElements in the document.
-                invalidateProperties(document.getDocumentElement(), 
+                invalidateProperties(document.getDocumentElement(),
                                      null, null, true);
             }
         }

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/value/AbstractColorManager.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/value/AbstractColorManager.java?rev=396138&r1=396137&r2=396138&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/value/AbstractColorManager.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/css/engine/value/AbstractColorManager.java Sat Apr 22 09:05:15 2006
@@ -1,6 +1,6 @@
 /*
 
-   Copyright 2002-2003  The Apache Software Foundation 
+   Copyright 2002-2003  The Apache Software Foundation
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -33,7 +33,7 @@
  * @version $Id$
  */
 public abstract class AbstractColorManager extends IdentifierManager {
-    
+
     /**
      * The identifier values.
      */
@@ -205,7 +205,7 @@
             }
             // Must be a system color...
             if (values.get(ident) == null) {
-                throw new InternalError();
+                throw new IllegalStateException("Not a system-color:" + ident );
             }
             return engine.getCSSContext().getSystemColor(ident);
         }

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGDOMImplementation.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGDOMImplementation.java?rev=396138&r1=396137&r2=396138&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGDOMImplementation.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGDOMImplementation.java Sat Apr 22 09:05:15 2006
@@ -1,6 +1,6 @@
 /*
 
-   Copyright 2000-2003  The Apache Software Foundation 
+   Copyright 2000-2003  The Apache Software Foundation
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -26,24 +26,18 @@
 import org.apache.batik.css.engine.value.ShorthandManager;
 import org.apache.batik.css.engine.value.ValueManager;
 import org.apache.batik.css.parser.ExtendedParser;
-import org.apache.batik.css.parser.ExtendedParserWrapper;
 import org.apache.batik.dom.AbstractDocument;
 import org.apache.batik.dom.AbstractStylableDocument;
 import org.apache.batik.dom.ExtensibleDOMImplementation;
 import org.apache.batik.dom.GenericDocumentType;
-import org.apache.batik.dom.GenericElement;
-import org.apache.batik.dom.GenericElementNS;
-import org.apache.batik.dom.StyleSheetFactory;
 import org.apache.batik.dom.events.DocumentEventSupport;
 import org.apache.batik.dom.util.CSSStyleDeclarationFactory;
 import org.apache.batik.dom.util.DOMUtilities;
 import org.apache.batik.dom.util.HashTable;
 import org.apache.batik.i18n.LocalizableSupport;
 import org.apache.batik.util.SVGConstants;
-import org.apache.batik.util.XMLResourceDescriptor;
 
 import org.w3c.css.sac.InputSource;
-import org.w3c.css.sac.Parser;
 import org.w3c.dom.DOMException;
 import org.w3c.dom.DOMImplementation;
 import org.w3c.dom.Document;
@@ -52,7 +46,6 @@
 import org.w3c.dom.Node;
 import org.w3c.dom.css.CSSStyleDeclaration;
 import org.w3c.dom.css.CSSStyleSheet;
-import org.w3c.dom.css.DOMImplementationCSS;
 import org.w3c.dom.css.ViewCSS;
 import org.w3c.dom.events.Event;
 import org.w3c.dom.stylesheets.StyleSheet;
@@ -65,9 +58,9 @@
  * @version $Id$
  */
 public class SVGDOMImplementation
-    extends    ExtensibleDOMImplementation 
+    extends    ExtensibleDOMImplementation
     implements CSSStyleDeclarationFactory {
-    
+
     /**
      * The SVG namespace uri.
      */
@@ -105,12 +98,12 @@
             (RESOURCES, getClass().getClassLoader());
     }
 
-    public CSSEngine createCSSEngine(AbstractStylableDocument doc, 
+    public CSSEngine createCSSEngine(AbstractStylableDocument doc,
                                      CSSContext               ctx,
                                      ExtendedParser           ep,
-                                     ValueManager     []      vms, 
+                                     ValueManager     []      vms,
                                      ShorthandManager []      sms) {
-                                     
+
         URL durl = ((SVGOMDocument)doc).getURLObject();
         CSSEngine result = new SVGCSSEngine(doc, durl, ep, vms, sms, ctx);
 
@@ -164,7 +157,8 @@
      * DOMImplementationCSS#createCSSStyleSheet(String,String)}.
      */
     public CSSStyleSheet createCSSStyleSheet(String title, String media) {
-        throw new InternalError("Not implemented");
+
+        throw new UnsupportedOperationException("Not implemented");
     }
 
     // CSSStyleDeclarationFactory ///////////////////////////////////////////
@@ -174,7 +168,7 @@
      * @return a CSSOMStyleDeclaration instance.
      */
     public CSSStyleDeclaration createCSSStyleDeclaration() {
-        throw new InternalError("Not implemented");
+        throw new UnsupportedOperationException("Not implemented");
     }
 
     // StyleSheetFactory /////////////////////////////////////////////
@@ -184,14 +178,14 @@
      * processing instruction or return null.
      */
     public StyleSheet createStyleSheet(Node n, HashTable attrs) {
-        throw new InternalError("Not implemented");
+        throw new UnsupportedOperationException("Not implemented");
     }
 
     /**
      * Returns the user-agent stylesheet.
      */
     public CSSStyleSheet getUserAgentStyleSheet() {
-        throw new InternalError("Not implemented");
+        throw new UnsupportedOperationException("Not implemented");
     }
 
     /**
@@ -494,7 +488,7 @@
             return new SVGOMAElement(prefix, (AbstractDocument)doc);
         }
     }
-    
+
     /**
      * To create a 'altGlyph' element.
      */

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMStyleElement.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMStyleElement.java?rev=396138&r1=396137&r2=396138&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMStyleElement.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGOMStyleElement.java Sat Apr 22 09:05:15 2006
@@ -1,6 +1,6 @@
 /*
 
-   Copyright 2000-2003  The Apache Software Foundation 
+   Copyright 2000-2003  The Apache Software Foundation
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -115,15 +115,15 @@
                     text = sb.toString();
                 }
                 URL burl = null;
+                String bu= "";
                 try {
-                    String bu = getBaseURI();
+                    bu = getBaseURI();
                     if (bu != null) {
                         burl = new URL(bu);
                     }
                 } catch (MalformedURLException ex) {
-                    // !!! TODO
-                    ex.printStackTrace();
-                    throw new InternalError();
+                    String msg = "MalformedURLException:" + ex.getMessage() + ':' + bu;
+                    throw new IllegalArgumentException( msg );
                 }
                 String  media = getAttributeNS(null, SVG_MEDIA_ATTRIBUTE);
                 styleSheet = e.parseStyleSheet(text, burl, media);

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGStylableElement.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGStylableElement.java?rev=396138&r1=396137&r2=396138&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGStylableElement.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/dom/svg/SVGStylableElement.java Sat Apr 22 09:05:15 2006
@@ -1,6 +1,6 @@
 /*
 
-   Copyright 2001-2006  The Apache Software Foundation 
+   Copyright 2001-2006  The Apache Software Foundation
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -76,7 +76,7 @@
     protected SVGStylableElement(String prefix, AbstractDocument owner) {
         super(prefix, owner);
     }
-    
+
     /**
      * Returns the override style declaration for this element.
      */
@@ -89,7 +89,7 @@
     }
 
     // CSSStylableElement //////////////////////////////////////////
-    
+
     /**
      * Returns the computed style of this element/pseudo-element.
      */
@@ -120,21 +120,22 @@
 
     /**
      * Returns the CSS base URL of this element.
+     * @throws IllegalArgumentException when the result of getBaseURI() 
+     *         cannot be used as an URL.
      */
     public URL getCSSBase() {
+        if (getXblBoundElement() != null) {
+            return null;
+        }
+        String bu = getBaseURI();
+        if (bu == null) {
+            return null;
+        }
         try {
-            if (getXblBoundElement() != null) {
-                return null;
-            }
-            String bu = getBaseURI();
-            if (bu == null) {
-                return null;
-            }
             return new URL(bu);
         } catch (MalformedURLException e) {
-            // !!! TODO
-            e.printStackTrace();
-            throw new InternalError();
+            String msg = "MalformedURLException:" + e.getMessage() + ':' + bu;
+            throw new IllegalArgumentException( msg );
         }
     }
 
@@ -189,7 +190,7 @@
 
         CSSEngine eng = ((SVGOMDocument)getOwnerDocument()).getCSSEngine();
         int idx = eng.getPropertyIndex(name);
-        if (idx == -1) 
+        if (idx == -1)
             return null;
 
         if (idx > SVGCSSEngine.FINAL_INDEX) {
@@ -205,13 +206,13 @@
             case SVGCSSEngine.STROKE_INDEX:
                 result = new PresentationAttributePaintValue(eng, name);
                 break;
-                
+
             case SVGCSSEngine.FLOOD_COLOR_INDEX:
             case SVGCSSEngine.LIGHTING_COLOR_INDEX:
             case SVGCSSEngine.STOP_COLOR_INDEX:
                 result = new PresentationAttributeColorValue(eng, name);
                 break;
-                
+
             default:
                 result = new PresentationAttributeValue(eng, name);
             }
@@ -539,7 +540,7 @@
         extends CSSOMStoredStyleDeclaration
         implements LiveAttributeValue,
                    CSSEngine.MainPropertyReceiver {
-        
+
         /**
          * Whether the mutation comes from this object.
          */
@@ -640,7 +641,7 @@
          */
         public void setMainProperty(String name, Value v, boolean important) {
             int idx = cssEngine.getPropertyIndex(name);
-            if (idx == -1) 
+            if (idx == -1)
                 return;   // unknown property
 
             int i;
@@ -648,7 +649,7 @@
                 if (idx == declaration.getIndex(i))
                     break;
             }
-            if (i < declaration.size()) 
+            if (i < declaration.size())
                 declaration.put(i, v, idx, important);
             else
                 declaration.append(v, idx, important);
@@ -665,7 +666,7 @@
         /**
          * Creates a new OverrideStyleDeclaration.
          */
-        public OverrideStyleDeclaration(CSSEngine eng) {
+        protected OverrideStyleDeclaration(CSSEngine eng) {
             super(eng);
             declaration = new org.apache.batik.css.engine.StyleDeclaration();
         }

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/ext/awt/image/rendered/IndexImage.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/ext/awt/image/rendered/IndexImage.java?rev=396138&r1=396137&r2=396138&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/ext/awt/image/rendered/IndexImage.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/ext/awt/image/rendered/IndexImage.java Sat Apr 22 09:05:15 2006
@@ -1,6 +1,6 @@
 /*
 
-   Copyright 2002-2003  The Apache Software Foundation 
+   Copyright 2002-2003,2006  The Apache Software Foundation
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -29,49 +29,94 @@
 import java.awt.image.SampleModel;
 import java.awt.image.WritableRaster;
 import java.util.Iterator;
-import java.util.Vector;
+import java.util.List;
+import java.util.ArrayList;
 
 import org.apache.batik.ext.awt.image.GraphicsUtil;
 
 /**
- * This implements an adaptive pallete generator to reduce images to a
+ * This class implements an adaptive palette generator to reduce images to a
  * specified number of colors.
  *
  * Ideally this would also support a better dither option than just 
  * the JDK's pattern dither.
  *
+ * The algorithm used is the 'Median Cut Algorithm' published by
+ * Paul Heckbert in early '80s.
+ *
  * @author <a href="mailto:deweese@apache.org">Thomas DeWeese</a>
  * @author <a href="mailto:jun@oop-reserch.com">Jun Inamori</a>
- * @version $Id$ */
+ * @version $Id$ 
+ */
+
 public class IndexImage{
 
     /**
      * Used to track a color and the number of pixels of that colors
      */
     private static class Counter {
-        public int val;
-        public int count=1;
-        public Counter(int val) {  this.val = val; }
-        public boolean add(int val) {
+
+        /**
+         * contains the 'packed' rgb-color for this point.
+         * Must not change after construction!
+         */
+        final int val;
+
+        /**
+         * the number of image-pixels with this color.
+         */
+        int count=1;
+
+        Counter(int val) {  this.val = val; }
+
+        boolean add(int val) {
             // See if the value matches us...
             if (this.val != val)
                 return false;
             count++;
             return true;
         }
-    }
+
+        /**
+         * convert the color-point of this counter to an rgb-array.
+         * To avoid creating lots of arrays, the caller passes the
+         * array to store the result.
+         *
+         * @param rgb an int[ 3 ] to store the result.
+         * @return an int-array with rgb-color-values (same as rgb-parameter)
+         */
+        int[] getRgb( int[] rgb ){
+            rgb[ Cube.RED ] = (val&0xFF0000)>>16;
+            rgb[ Cube.GRN ] = (val&0x00FF00)>>8;
+            rgb[ Cube.BLU ] = (val&0x0000FF);
+            return rgb;
+        }
+   }
 
     /**
      * Used to define a cube of the colorspace.  The cube can be split
-     * approximagely in half to generate two cubes.  
+     * approximagely in half to generate two cubes.
      */
     private static class Cube {
-        int []min={0, 0, 0}, max={255,255,255};
+        static final byte[] RGB_BLACK= new byte[]{ 0, 0, 0 };
+
+        int[] min = {0, 0, 0}, max={255,255,255};
 
         boolean done = false;
         
-        Vector []colors = null;
+
+        /**
+         * the colors-array is not modified - in fact, all cubes use
+         * the same colors-array.  The Counter contains the
+         * rgb-color-code and the count of pixels with this color.
+         */
+        final Counter[][] colors;
+
+        /**
+         * the number of color-points in this cube.
+         */
         int count=0;
+
         static final int RED = 0;
         static final int GRN = 1;
         static final int BLU = 2;
@@ -81,7 +126,7 @@
          * @param colors contains the 3D color histogram to be subdivided
          * @param count the total number of pixels in the 3D histogram.
          */
-        public Cube(Vector []colors, int count) {
+        Cube( Counter[][] colors, int count) {
             this.colors = colors;
             this.count = count;
         }
@@ -91,122 +136,193 @@
          * further
          */
         public boolean isDone() { return done; }
+
+        /**
+         * check, if the color defined by val[] is inside this cube.
+         *
+         * @param val int[ 3 ] containing r,g,b-values
+         * @return true when color is inside this cube
+         */
+        private boolean contains( int[] val ){
+
+            int vRed = val[ RED ]; // just save some array-accesses
+            int vGrn = val[ GRN ];
+            int vBlu = val[ BLU ];
+
+            return (
+                ( ( min[ RED ] <= vRed ) && ( vRed <= max[ RED ]))&&
+                ( ( min[ GRN ] <= vGrn ) && ( vGrn <= max[ GRN ]))&&
+                ( ( min[ BLU ] <= vBlu ) && ( vBlu <= max[ BLU ])));
+        }
+
         /**
          * Splits the cube into two parts.  This cube is
          * changed to be one half and the returned cube is the other half.
          * This tries to pick the right channel to split on.
          */
-        public Cube split() {
-            int dr = max[0]-min[0]+1;
-            int dg = max[1]-min[1]+1;
-            int db = max[2]-min[2]+1;
+        Cube split() {
+            int dr = max[ RED ]-min[ RED ]+1;
+            int dg = max[ GRN ]-min[ GRN ]+1;
+            int db = max[ BLU ]-min[ BLU ]+1;
             int c0, c1, splitChannel;
 
             // Figure out which axis is the longest and split along
             // that axis (this tries to keep cubes square-ish).
             if (dr >= dg) {
-                c0 = GRN;
-                if (dr >= db) { splitChannel = RED; c1=BLU; }
-                else          { splitChannel = BLU; c1=RED; }
+                if (dr >= db) { splitChannel = RED; c0=GRN; c1=BLU; }
+                else          { splitChannel = BLU; c0=RED; c1=GRN; }
             } else if (dg >= db) {
                 splitChannel = GRN;
                 c0=RED;
                 c1=BLU;
             } else {
                 splitChannel = BLU;
-                c0=RED;
-                c1=GRN;
+                c0=GRN;
+                c1=RED;
             }
 
+//            System.out.println("Red:" + dr
+//                    + " Grn:" + dg
+//                    + " Blu:" + db
+//                    + " Split:" + splitChannel
+//                    + " c0:" + c0
+//                    + " c1:" + c1 );
+
             Cube ret;
+
+            // try to split the longest axis
             ret = splitChannel(splitChannel, c0, c1);
             if (ret != null ) return ret;
 
+            // try to split along the 2nd longest axis
             ret = splitChannel(c0, splitChannel, c1);
             if (ret != null ) return ret;
 
+            // only one left
             ret = splitChannel(c1, splitChannel, c0);
             if (ret != null) return ret;
-            
+
+            // so far, no split was possible trying all 3 colors: this
+            // cube can't be split further
             done = true;
             return null;
         }
 
         /**
+         * Adjust (normalize) min/max of this cube so that they span
+         * the actual content.  This method is called on the two cubes
+         * resulting from a split.  <br> We search the counts[] from
+         * min to max for the leftmost non-null entry.  That is the
+         * new min.  Then we search counts[] from max to min for the
+         * rightmost non-null entry.  That is the new max.  <br>This
+         * requires, that {@link #computeCounts } really computes
+         * <i>all</i> counts-values (and does not stop after the
+         * necessary number of points for a split is found, as it was
+         * done in the previous version of this class).
+         *
+         * @param splitChannel the color used for the last split
+         * @param counts contains the number of points along the splitChannel
+         *        - only counts[ min .. max ] is valid.
+         */
+        private void normalize( int splitChannel, int[] counts ){
+
+            if ( count == 0 ){
+                // empty cube: nothing to normalize
+                return;
+            }
+
+            int iMin = min[ splitChannel ];
+            int iMax = max[ splitChannel ];
+            int loBound = -1;
+            int hiBound = -1;
+
+            // we search from left to right for the first non-null
+            // entry in counts[]
+            for( int i = iMin; i <= iMax; i++ ){
+                if ( counts[ i ] == 0 ){
+                    // this entry is 0: search more
+                    continue;
+                }
+
+                // we reached a non-null entry: stop looking further
+                loBound = i;
+                break;
+            }
+
+            // we search from right to left for the first non-null
+            // entry in counts[]
+            for( int i= iMax; i >= iMin; i-- ){
+                if ( counts[ i ] == 0 ){
+                    // this entry is 0: search more
+                    continue;
+                }
+                // we reached a non-null entry: stop looking further
+                hiBound = i;
+                break;
+            }
+
+            boolean flagChangedLo = (loBound != -1 ) && ( iMin != loBound );
+            boolean flagChangedHi = (hiBound != -1 ) && ( iMax != hiBound );
+//            if ( flagChangedLo || flagChangedHi ){
+//                System.out.println("old min:" + min[ splitChannel ] + "/max:" + max[ splitChannel ]
+//                + " new: " + loBound + "/" + hiBound );
+//                StringBuffer buff = new StringBuffer( 100 );
+//                for( int i= min[ splitChannel ]; i <= max[ splitChannel]; i++ ){
+//                    buff.append( counts[ i ] );
+//                    buff.append( ',' );
+//                }
+//                System.out.println("Counts:" + buff );
+//            }
+
+            if ( flagChangedLo ){
+                min[ splitChannel ]= loBound;
+            }
+            if ( flagChangedHi ){
+                max[ splitChannel ]= hiBound;
+            }
+        }
+
+
+        /**
          * Splits the image according to the parameters.  It tries
          * to find a location where half the pixels are on one side
          * and half the pixels are on the other.
          */
-        public Cube splitChannel(int splitChannel, int c0, int c1) {
-            if (min[splitChannel] == max[splitChannel]) return null;
-            
-            int splitSh4 = (2-splitChannel)*4;
-            int c0Sh4    = (2-c0)*4;
-            int c1Sh4    = (2-c1)*4;
+        Cube splitChannel(int splitChannel, int c0, int c1) {
+
+            if (min[splitChannel] == max[splitChannel]) {
+                // thickness along the splitChannel is only one point: cannot split
+                return null;
+            }
+
+            if ( count == 0 ){
+                // this Cube has no points: cannot split
+                return null;
+            }
+
+            // System.out.println( toString() );
 
             int half = count/2;
             // Each entry is the number of pixels that have that value
             // in the split channel within the cube (so pixels
             // that have that value in the split channel aren't counted
             // if they are outside the cube in the other color channels.
-            int counts [] = new int[256];
-            int tcount = 0;
-
-            // System.out.println("Cube: [" + 
-            //                    min[0] + "-" + max[0] + "] [" +
-            //                    min[1] + "-" + max[1] + "] [" +
-            //                    min[2] + "-" + max[2] + "]");
+            int[] counts = computeCounts( splitChannel, c0, c1 );
 
-            int [] minIdx = {min[0]>>4, min[1]>>4, min[2]>>4};
-            int [] maxIdx = {max[0]>>4, max[1]>>4, max[2]>>4};
-            int minR=min[0], minG=min[1], minB=min[2];
-            int maxR=max[0], maxG=max[1], maxB=max[2];
-            int val = 0;
-            int [] vals = {0, 0, 0};
-            for (int i=minIdx[splitChannel]; i<=maxIdx[splitChannel]; i++) {
-                int idx1 = i<<splitSh4;
-                for (int j=minIdx[c0]; j<=maxIdx[c0]; j++) {
-                    int idx2 = idx1 | (j<<c0Sh4);
-                    for (int k=minIdx[c1]; k<=maxIdx[c1]; k++) {
-                        int idx = idx2 | (k<<c1Sh4);
-                        Vector v = colors[idx];
-                        if (v==null) continue;
-                        Iterator itr = v.iterator();
-                        Counter c;
-                        while (itr.hasNext()) {
-                            c = (Counter)itr.next();
-                            val = c.val;
-                            vals[0] = (val&0xFF0000)>>16;
-                            vals[1] = (val&0xFF00)>>8;
-                            vals[2] = (val&0xFF);
-                            if (((vals[0] >= minR) && (vals[0] <= maxR))&&
-                                ((vals[1] >= minG) && (vals[1] <= maxG))&&
-                                ((vals[2] >= minB) && (vals[2] <= maxB))) {
-                                // The val lies within this cube so count it.
-                                counts[vals[splitChannel]] += c.count;
-                                tcount += c.count;
-                            }
-                        }
-                    }
-                }
-                // We've found the half way point.  Note that the
-                // rest of counts is not filled out.
-                if (tcount >= half) break;
-            }
-
-            tcount=0;
+            int tcount=0;
             int lastAdd=-1;
             // These indicate what the top value for the low cube and
             // the low value of the high cube should be in the split channel
             // (they may not be one off if there are 'dead' spots in the
             // counts array.
-            int splitLo=min[splitChannel], splitHi=max[splitChannel];
+            int splitLo=min[splitChannel];
+            int splitHi=max[splitChannel];
             for (int i=min[splitChannel]; i<=max[splitChannel]; i++) {
                 int c = counts[i];
                 if (c == 0) {
                     // No counts below this so move up bottom of cube.
                     if ((tcount == 0) && (i < max[splitChannel]))
-                        this.min[splitChannel] = i+1;
+                        min[splitChannel] = i+1;
                     continue;
                 }
 
@@ -219,24 +335,25 @@
                     // Then lastAdd is a better top idx for this then i.
                     if (lastAdd == -1) {
                         // No lower place to break.
-                        if (c == this.count) {
+                        if (c == count) {
                             // All pixels are at this value so make min/max
                             // reflect that.
-                            this.max[splitChannel] = i;
+                            max[splitChannel] = i;
                             return null; // no split to make.
                         } else {
                             // There are values about this one so
                             // split above.
                             splitLo = i;
                             splitHi = i+1;
+                            tcount += c;    // fix 35683
                             break;
                         }
                     }
                     splitLo = lastAdd;
                     splitHi = i;
                 } else {
-                    if (i == this.max[splitChannel]) {
-                        if ( c == this.count) {
+                    if (i == max[splitChannel]) {
+                        if ( c == count) {
                             // would move min up but that should
                             // have happened already.
                             return null; // no split to make.
@@ -256,104 +373,263 @@
                 break;
             }
 
-            // System.out.println("Split: " + splitChannel + "@" 
-            //                    + splitLo + "-"+splitHi + 
+            // System.out.println("Split: " + splitChannel + "@"
+            //                    + splitLo + "-"+splitHi +
             //                    " Count: " + tcount  + " of " + count +
             //                    " LA: " + lastAdd);
 
-            // Create the new cube and update everone's bounds & counts.
+            // Create the new cube and update everyone's bounds & counts.
             Cube ret = new Cube(colors, tcount);
-            this.count = this.count-tcount;
-            ret.min[splitChannel] = this.min[splitChannel];
+            count = count-tcount;
+            ret.min[splitChannel] = min[splitChannel];
             ret.max[splitChannel] = splitLo;
-            this.min[splitChannel] = splitHi;
-            ret.min[c0] = this.min[c0];
-            ret.max[c0] = this.max[c0];
-            ret.min[c1] = this.min[c1];
-            ret.max[c1] = this.max[c1];
+            min[splitChannel] = splitHi;
+
+            // the cube was split along splitChannel, the other
+            // dimensions dont change
+            ret.min[c0] = min[c0];
+            ret.max[c0] = max[c0];
+            ret.min[c1] = min[c1];
+            ret.max[c1] = max[c1];
+
+//            if ( count <= 0 ){
+//                System.out.println("This cube has no points after split:" + toString() );
+//            }
+//            if ( ret.count <= 0 ){
+//                System.out.println("That cube has no points after split:" + ret.toString() + "    this:" + toString() );
+//                System.out.println("SplitLo:"  + splitLo + "  SplitHi:" + splitHi );
+//            }
+
+            // after a split we 'normalize' both cubes, so that their
+            // min/max reflect the actual bounds of the cube.  comment
+            // the next two lines when you want to see the impact of
+            // using non-normalized cubes
+            normalize( splitChannel, counts );
+            ret.normalize( splitChannel, counts );
+
             return ret;
         }
 
         /**
-         * Returns the average color for this cube
+         * create an array, which contains the number of pixels for
+         * each point along the splitChannel (between min and max of
+         * this cube).
+         *
+         * @param splitChannel one of RED | GRN | BLU
+         * @param c0 one of the other channels
+         * @param c1 the third channel
+         * @return an int[ 255 ] where only int[ min .. max ] contain
+         *         valid counts.
+         */
+        private int[] computeCounts( int splitChannel, int c0, int c1) {
+
+            int splitSh4 = (2-splitChannel)*4;
+            int c0Sh4    = (2-c0)*4;
+            int c1Sh4    = (2-c1)*4;
+
+            // after split, each half should have half of the cube's points
+            int half = count/2;
+
+            // Each entry is the number of pixels that have that value
+            // in the split channel within the cube (so pixels
+            // that have that value in the split channel aren't counted
+            // if they are outside the cube in the other color channels.
+            int[] counts = new int[256];
+            int tcount = 0;
+
+            int minR=min[0], minG=min[1], minB=min[2];
+            int maxR=max[0], maxG=max[1], maxB=max[2];
+
+            int[] minIdx = { minR >> 4, minG >> 4, minB >> 4 };
+            int[] maxIdx = { maxR >> 4, maxG >> 4, maxB >> 4 };
+
+            int [] vals = {0, 0, 0};
+            for (int i=minIdx[splitChannel]; i<=maxIdx[splitChannel]; i++) {
+                int idx1 = i<<splitSh4;
+                for (int j=minIdx[c0]; j <=maxIdx[c0]; j++) {
+                    int idx2 = idx1 | (j<<c0Sh4);
+                    for (int k=minIdx[c1]; k<=maxIdx[c1]; k++) {
+                        int idx = idx2 | (k<<c1Sh4);
+                        Counter[] v = colors[idx];
+                        for( int iColor = 0; iColor < v.length; iColor++ ){
+                            Counter c = v[ iColor ];
+                            vals = c.getRgb( vals );
+                            if ( contains( vals )){
+                                // The vals[] lies completly within
+                                // this cube so count it.
+                                counts[ vals[splitChannel] ] += c.count;
+                                tcount += c.count;
+                            }
+                        }
+                    }
+                }
+                // the next statement-line stops the loop after we
+                // found the split-point.  however, we continue to
+                // fill the counts[] because that is needed for
+                // normalization
+//                // We've found the half way point.  Note that the
+//                // rest of counts is not filled out.
+//                if (( tcount > 0 ) && (tcount >= half)) break;  // fix 35683
+            }
+
+            // the result so far is the filled counts[]
+            return counts;
+        }
+
+
+        /**
+         * convert the cube-content to String-representation for logging.
+         * @return the min/max-boundarys of the rgb-channels and
+         *         pixel-count of this Cube.
+         */
+        public String toString() {
+            return "Cube: [" +
+                    min[ RED ] + '-' + max[ RED ] + "] [" +
+                    min[ GRN ] + '-' + max[ GRN ] + "] [" +
+                    min[ BLU ] + '-' + max[ BLU ] + "] n:" + count;
+        }
+
+
+        /**
+         * Returns the average color for this cube (no alpha).
          */
         public int averageColor() {
-            if (this.count == 0) return 0;
+            if (count == 0) {
+                // cube is empty: return black
+                return 0;
+            }
+
+            byte[] rgb = averageColorRGB( null );
+
+            return (( rgb[ RED ] << 16 ) & 0x00FF0000)
+                 | (( rgb[ GRN ] <<  8 ) & 0x0000FF00)
+                 | (( rgb[ BLU ]       ) & 0x000000FF);
+        }
+
+        /**
+         * Returns the average color for this cube
+         */
+        public byte[] averageColorRGB( byte[] rgb ) {
+
+            if (count == 0) return RGB_BLACK;
 
             float red=0, grn=0, blu=0;
 
+            // the boundarys of this cube
             int minR=min[0], minG=min[1], minB=min[2];
             int maxR=max[0], maxG=max[1], maxB=max[2];
             int [] minIdx = {minR>>4, minG>>4, minB>>4};
             int [] maxIdx = {maxR>>4, maxG>>4, maxB>>4};
-            int val, ired, igrn, iblu;
-            float weight;
+            int[] vals = new int[3];
+
             for (int i=minIdx[0]; i<=maxIdx[0]; i++) {
                 int idx1 = i<<8;
                 for (int j=minIdx[1]; j<=maxIdx[1]; j++) {
                     int idx2 = idx1 | (j<<4);
                     for (int k=minIdx[2]; k<=maxIdx[2]; k++) {
                         int idx = idx2 | k;
-                        Vector v = colors[idx];
-                        if (v==null) continue;
-                        Iterator itr = v.iterator();
-                        Counter c;
-                        while (itr.hasNext()) {
-                            c = (Counter)itr.next();
-                            val = c.val;
-                            ired = (val&0xFF0000)>>16;
-                            igrn = (val&0x00FF00)>>8;
-                            iblu = (val&0x0000FF);
-                            if (((ired >= minR) && (ired <= maxR))&&
-                                ((igrn >= minG) && (igrn <= maxG))&&
-                                ((iblu >= minB) && (iblu <= maxB))) {
-                                weight = (c.count/(float)this.count);
-                                red += (ired*weight);
-                                grn += (igrn*weight);
-                                blu += (iblu*weight);
+                        Counter[] v = colors[idx];
+                        for( int iColor = 0; iColor < v.length; iColor++ ){
+                            Counter c = v[ iColor ];
+                            vals = c.getRgb( vals );
+                            if ( contains( vals ) ) {
+                                float weight = (c.count/(float)count);
+                                red += (vals[0]*weight);
+                                grn += (vals[1]*weight);
+                                blu += (vals[2]*weight);
                             }
                         }
                     }
                 }
             }
-            // System.out.println("RGB: [" + red + ", " + 
-            //                    grn + ", " + blu + "]");
-            return (((int)(red+0.5))<<16 |
-                    ((int)(grn+0.5))<<8  | 
-                    ((int)(blu+0.5)));
+            byte[] result = (rgb == null) ? new byte[3] : rgb;
+            result[ RED ] = (byte)(red + 0.5f);
+            result[ GRN ] = (byte)(grn + 0.5f);
+            result[ BLU ] = (byte)(blu + 0.5f);
+
+            return result;
         }
+
     }
 
     /**
-     * Converts the input image (must be TYPE_INT_RGB or
-     * TYPE_INT_ARGB) to an indexed image.  Generating an adaptive
-     * palette with number of colors specified.
-     * @param bi the image to be processed.
-     * @param nColors number of colors in the palette
+     * create an array of rgb-colors from the cubes-array.
+     * The color of each cube is computed as the sum of all colors in the cube,
+     * where each pixel is weighted according to it's count.
+     *
+     * @param nCubes number of entries to use in cubes
+     * @param cubes contains the Cubes resulting from running the split-algorithm.
+     * @return a byte[][] which is arranged as [ r|g|b ][ 0..nCubes-1 ]
      */
-    static public BufferedImage getIndexedImage
-        (BufferedImage bi, int nColors) {
-        int w=bi.getWidth();
-        int h=bi.getHeight();
+    static byte[][] computeRGB( int nCubes, Cube[] cubes ){
+
+        byte[] r = new byte[nCubes];
+        byte[] g = new byte[nCubes];
+        byte[] b = new byte[nCubes];
+
+        byte[] rgb = new byte[3];
+        for (int i=0; i<nCubes; i++) {
+            rgb = cubes[i].averageColorRGB( rgb );
+            r[i] = rgb[ Cube.RED ];
+            g[i] = rgb[ Cube.GRN ];
+            b[i] = rgb[ Cube.BLU ];
+        }
+
+        byte[][] result = new byte[3][];
+        result[ Cube.RED ] = r;
+        result[ Cube.GRN ] = g;
+        result[ Cube.BLU ] = b;
+
+//        logRGB( r, g, b );
+
+        return result;
+    }
+
+    /**
+     * helper-method to print the complete rgb-arrays.
+     * @param r
+     * @param g
+     * @param b
+     */
+    static void logRGB( byte[] r, byte[] g, byte[] b ){
+
+        StringBuffer buff = new StringBuffer( 100 );
+        int nColors = r.length;
+        for( int i= 0; i < nColors; i++ ) {
+            String rgbStr= "(" + (r[i]+128) + ',' + (g[i] +128 ) + ',' + (b[i] + 128) + ")," ;
+            buff.append( rgbStr );
+        }
+        System.out.println("RGB:" + nColors + buff );
+    }
+
+
+    /**
+     * step 1: fill a data-structure with the count of each color in the image.
+     * @param bi input-image
+     * @return a List[] where each slot is a List of Counters (or null)
+     */
+    static List[] createColorList( BufferedImage bi ){
+
+        int w= bi.getWidth();
+        int h= bi.getHeight();
 
         // Using 4 bits from RG & B.
-        Vector [] colors = new Vector[1<<12]; 
+        List[] colors = new ArrayList[1<<12];
 
-        int rgb=0;
         for(int i_w=0; i_w<w; i_w++){
             for(int i_h=0; i_h<h; i_h++){
-                rgb=(bi.getRGB(i_w,i_h) & 0xFFFFFF);
+                int rgb=(bi.getRGB(i_w,i_h) & 0x00FFFFFF);  // mask away alpha
                 // Get index from high four bits of each component.
                 int idx = (((rgb&0xF00000)>>> 12) |
                            ((rgb&0x00F000)>>>  8) |
                            ((rgb&0x0000F0)>>>  4));
 
-                    // Get the 'hash vector' for that key.
-                Vector v = colors[idx];
+                // Get the 'hash vector' for that key.
+                List v = colors[idx];
                 if (v == null) {
-                    // No colors in this bin yet so create vector and
+                    // No colors in this bin yet so create list and
                     // add color.
-                    v = new Vector();
+                    v = new ArrayList();
                     v.add(new Counter(rgb));
                     colors[idx] = v;
                 } else {
@@ -372,27 +648,92 @@
             }
         }
 
+        return colors;
+    }
+
+
+    /**
+     * step 2: convert the result of step 1 to an Cube[][] which is
+     * more efficient in the following iterations. All slots in the
+     * result are filled with at least an empty array - thus we avoid
+     * tests for null.  <br>Note: the converted slots in colors are no
+     * longer needed and removed.
+     *
+     * @param colors the data-structure to convert. Note that it is
+     * empty after conversion!
+     * @return same data as in colors, but Lists are converted to arrays.
+     */
+    static Counter[][] convertColorList( List[] colors ){
+
+        // used to fill empty slots
+        final Counter[] EMPTY_COUNTER = new Counter[0];
+
+        Counter[][] colorTbl= new Counter[ 1<< 12 ][];
+        for( int i= 0; i < colors.length; i++ ){
+            List cl = colors[ i ];
+            if ( cl == null ){
+                colorTbl[ i ] = EMPTY_COUNTER;
+                continue;
+            }
+            int nSlots = cl.size();
+            colorTbl[i] = (Counter[])cl.toArray( new Counter[ nSlots ] );
+
+            // the colors[ i ] - data is no longer needed: discard
+            colors[ i ] = null;
+        }
+
+        return colorTbl;
+    }
+
+    /**
+     * Converts the input image (must be TYPE_INT_RGB or
+     * TYPE_INT_ARGB) to an indexed image.  Generating an adaptive
+     * palette with number of colors specified.
+     * @param bi the image to be processed.
+     * @param nColors number of colors in the palette
+     */
+    public static BufferedImage getIndexedImage( BufferedImage bi, int nColors) {
+        int w=bi.getWidth();
+        int h=bi.getHeight();
+
+        // Using 4 bits from RG & B.
+        List[] colors = createColorList( bi );
+
+        // now we have initialized the colors[] with lists of Counters.
+        // from now on, this data-structure is just read, not modified.
+        // convert it to Counter[][] for faster iteration
+        Counter[][] colorTbl = convertColorList( colors );
+
+        // this is no longer needed: discard
+        colors = null;
+
         int nCubes=1;
         int fCube=0;
         Cube [] cubes = new Cube[nColors];
-        cubes[0] = new Cube(colors, w*h);
-        
+        cubes[0] = new Cube(colorTbl, w*h);
+
         while (nCubes < nColors) {
             while (cubes[fCube].isDone()) {
                 fCube++;
                 if (fCube == nCubes) break;
             }
-            if (fCube == nCubes) break;
+            if (fCube == nCubes) {
+                // System.out.println("fCube == nCubes" + fCube );
+                break;
+            }
             Cube c = cubes[fCube];
             Cube nc = c.split();
             if (nc != null) {
+                // store the cube with less points towards the end of
+                // the array, so that fat cubes get more splits
                 if (nc.count > c.count) {
+                    // new cube has more points: swap
                     Cube tmp = c; c= nc; nc = tmp;
                 }
                 int j = fCube;
                 int cnt = c.count;
                 for (int i=fCube+1; i<nCubes; i++) {
-                    if (cubes[i].count < cnt) 
+                    if (cubes[i].count < cnt)
                         break;
                     cubes[j++] = cubes[i];
                 }
@@ -400,7 +741,7 @@
 
                 cnt = nc.count;
                 while (j<nCubes) {
-                    if (cubes[j].count < cnt) 
+                    if (cubes[j].count < cnt)
                         break;
                     j++;
                 }
@@ -411,28 +752,16 @@
             }
         }
 
-        byte [] r = new byte[nCubes];
-        byte [] g = new byte[nCubes]; 
-        byte [] b = new byte[nCubes]; 
-        for (int i=0; i<nCubes; i++) {
-            int val = cubes[i].averageColor();
-            r[i] = (byte)((val>>16)&0xFF);
-            g[i] = (byte)((val>> 8)&0xFF);
-            b[i] = (byte)((val    )&0xFF);
-
-            // System.out.println("Color [" + i + "]: #" + 
-            //                    (((val>>16)<16)?"0":"") +
-            //                    Integer.toHexString(val));
-        }
-        BufferedImage indexed;
-
+        // convert the remaining cubes to the colors they represent
+        byte[][] rgbTbl = computeRGB( nCubes, cubes );
 
         // The JDK doesn't seem to dither the image correctly if I go
-        // below 8bits per pixel.  So I dither to an 8bit pallete
+        // below 8bits per pixel.  So I dither to an 8bit palette
         // image that only has nCubes colors.  Then I copy the data to
         // a lower bit depth image that I return.
-        IndexColorModel icm=new IndexColorModel(8,nCubes,r,g,b);
-        indexed =new BufferedImage
+        IndexColorModel icm= new IndexColorModel( 8, nCubes, rgbTbl[0], rgbTbl[1], rgbTbl[2] );
+
+        BufferedImage indexed =new BufferedImage
             (w, h, BufferedImage.TYPE_BYTE_INDEXED, icm);
         Graphics2D g2d=indexed.createGraphics();
         g2d.setRenderingHint
@@ -446,24 +775,24 @@
         for (bits=1; bits <=8; bits++) {
             if ((1<<bits) >= nCubes) break;
         }
-        // System.out.println("Bits: " + bits + " Cubes: " + nCubes);
+//        System.out.println("Bits: " + bits + " Cubes: " + nCubes);
 
-        if (bits > 4)
+        if (bits > 4) {
             // 8 bit image we are done...
             return indexed;
+        }
 
         // Create our low bit depth image...
         if (bits ==3) bits = 4;
-        ColorModel cm=new IndexColorModel(bits,nCubes,r,g,b);
-        SampleModel sm = new MultiPixelPackedSampleModel
-            (DataBuffer.TYPE_BYTE, w, h, bits);
-        WritableRaster ras = Raster.createWritableRaster
-            (sm, new Point(0,0));
+        ColorModel cm = new IndexColorModel(bits,nCubes, 
+                                            rgbTbl[0], rgbTbl[1], rgbTbl[2] );
+        SampleModel sm;
+        sm = new MultiPixelPackedSampleModel(DataBuffer.TYPE_BYTE, w, h, bits);
+        WritableRaster ras = Raster.createWritableRaster( sm, new Point(0,0));
 
         // Copy the data to the low bitdepth image.
         bi = indexed;
-        indexed = new BufferedImage(cm, ras, 
-                                    bi.isAlphaPremultiplied(), null);
+        indexed = new BufferedImage(cm, ras, bi.isAlphaPremultiplied(), null);
         GraphicsUtil.copyData(bi, indexed);
         return indexed;
     }

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/extension/StylableExtensionElement.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/extension/StylableExtensionElement.java?rev=396138&r1=396137&r2=396138&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/extension/StylableExtensionElement.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/extension/StylableExtensionElement.java Sat Apr 22 09:05:15 2006
@@ -1,6 +1,6 @@
 /*
 
-   Copyright 1999-2003,2006  The Apache Software Foundation 
+   Copyright 1999-2003,2006  The Apache Software Foundation
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -25,6 +25,7 @@
 import org.apache.batik.css.engine.StyleDeclarationProvider;
 import org.apache.batik.css.engine.StyleMap;
 import org.apache.batik.dom.AbstractDocument;
+
 import org.w3c.dom.Node;
 import org.w3c.dom.css.CSSStyleDeclaration;
 import org.w3c.dom.css.CSSValue;
@@ -71,7 +72,7 @@
     }
 
     // CSSStylableElement //////////////////////////////////////////
-    
+
     /**
      * Returns the computed style of this element/pseudo-element.
      */
@@ -102,19 +103,23 @@
 
     /**
      * Returns the CSS base URL of this element.
+     * @throws IllegalArgumentException when {@link #getBaseURI } returns an invalid URL.
+     *         The information from the MalformedURLException
+     *         is passed to the IllegalArgumentException
+     *
      */
     public URL getCSSBase() {
+        String bu = "";
         if (cssBase == null) {
             try {
-                String bu = getBaseURI();
+                bu = getBaseURI();
                 if (bu == null) {
                     return null;
                 }
                 cssBase = new URL(bu);
             } catch (MalformedURLException e) {
-                // !!! TODO
-                e.printStackTrace();
-                throw new InternalError();
+                String msg = "MalformedURLException:" + e.getMessage() + ':' + bu;
+                throw new IllegalArgumentException( msg );
             }
         }
         return cssBase;
@@ -150,7 +155,7 @@
      * <b>DOM</b>: Implements {@link org.w3c.dom.svg.SVGStylable#getStyle()}.
      */
     public CSSStyleDeclaration getStyle() {
-        throw new InternalError("Not implemented");
+        throw new UnsupportedOperationException("Not implemented");
     }
 
     /**
@@ -158,7 +163,7 @@
      * org.w3c.dom.svg.SVGStylable#getPresentationAttribute(String)}.
      */
     public CSSValue getPresentationAttribute(String name) {
-        throw new InternalError("Not implemented");
+        throw new UnsupportedOperationException("Not implemented");
     }
 
     /**
@@ -166,6 +171,6 @@
      * org.w3c.dom.svg.SVGStylable#getClassName()}.
      */
     public SVGAnimatedString getClassName() {
-        throw new InternalError("Not implemented");
+        throw new UnsupportedOperationException("Not implemented");
     }
 }

Modified: xmlgraphics/batik/trunk/sources/org/apache/batik/gvt/event/AbstractAWTEventDispatcher.java
URL: http://svn.apache.org/viewcvs/xmlgraphics/batik/trunk/sources/org/apache/batik/gvt/event/AbstractAWTEventDispatcher.java?rev=396138&r1=396137&r2=396138&view=diff
==============================================================================
--- xmlgraphics/batik/trunk/sources/org/apache/batik/gvt/event/AbstractAWTEventDispatcher.java (original)
+++ xmlgraphics/batik/trunk/sources/org/apache/batik/gvt/event/AbstractAWTEventDispatcher.java Sat Apr 22 09:05:15 2006
@@ -1,6 +1,6 @@
 /*
 
-   Copyright 2001-2003  The Apache Software Foundation 
+   Copyright 2001-2003  The Apache Software Foundation
 
    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
@@ -139,7 +139,7 @@
             ((baseTransform == null) || (!baseTransform.equals(t))))
             // new Display transform so events are not where user
             // thinks they were.
-            eventQueue.clear(); 
+            eventQueue.clear();
         baseTransform = t;
     }
 
@@ -326,6 +326,10 @@
      * @param listenerType the type of the listeners to return
      */
     public EventListener [] getListeners(Class listenerType) {
+
+        // TODO the listeners should be cached per class in a map.
+        // this list is build again and again in mouse-event-handling...
+        // note: the cache must be flushed when the gListeners is modified
         Object array =
             Array.newInstance(listenerType,
                               glisteners.getListenerCount(listenerType));
@@ -356,6 +360,7 @@
     public void setEventQueueMaxSize(int n) {
         eventQueueMaxSize = n;
         if (n == 0) eventQueue.clear();
+        // the current size is larger than the new size: shrink
         while(eventQueue.size() > eventQueueMaxSize)
             eventQueue.remove(0);
     }
@@ -373,7 +378,7 @@
                 while (eventQueue.size() > eventQueueMaxSize)
                     // Limit how many events we queue - don't want
                     // user waiting forever for them to clear.
-                    eventQueue.remove(0); 
+                    eventQueue.remove(0);
             }
             return;
         }
@@ -401,28 +406,28 @@
             if (t.getLockingKeyState(KeyEvent.VK_KANA_LOCK)) {
                 lockState++;
             }
-        } catch (java.lang.UnsupportedOperationException ex) {
+        } catch (UnsupportedOperationException ex) {
         }
         lockState <<= 1;
         try {
             if (t.getLockingKeyState(KeyEvent.VK_SCROLL_LOCK)) {
                 lockState++;
             }
-        } catch (java.lang.UnsupportedOperationException ex) {
+        } catch (UnsupportedOperationException ex) {
         }
         lockState <<= 1;
         try {
             if (t.getLockingKeyState(KeyEvent.VK_NUM_LOCK)) {
                 lockState++;
             }
-        } catch (java.lang.UnsupportedOperationException ex) {
+        } catch (UnsupportedOperationException ex) {
         }
         lockState <<= 1;
         try {
             if (t.getLockingKeyState(KeyEvent.VK_CAPS_LOCK)) {
                 lockState++;
             }
-        } catch (java.lang.UnsupportedOperationException ex) {
+        } catch (UnsupportedOperationException ex) {
         }
         return lockState;
     }
@@ -434,7 +439,7 @@
      * @param evt the key event to dispatch
      */
     protected abstract void dispatchKeyEvent(KeyEvent evt);
-    
+
     /**
      * Dispatches the specified AWT mouse event.
      * @param evt the mouse event to dispatch
@@ -448,7 +453,7 @@
         }
 
         GraphicsNode node = root.nodeHitAt(gnp);
-        
+
         // If the receiving node has changed, send a notification
         // check if we enter a new node
         Point screenPos;
@@ -460,6 +465,8 @@
             screenPos.y += evt.getY();
         }
 
+        int currentLockState = getCurrentLockState();
+
         if (lastHit != node) {
             // post a MOUSE_EXITED event
             if (lastHit != null) {
@@ -468,11 +475,11 @@
                                                     MOUSE_EXITED,
                                                     evt.getWhen(),
                                                     evt.getModifiers(),
-                                                    getCurrentLockState(),
+                                                    currentLockState,
                                                     (float)gnp.getX(),
                                                     (float)gnp.getY(),
-                                                    (int)Math.floor(p.getX()),
-                                                    (int)Math.floor(p.getY()),
+                                                    (int)Math.floor(p.getX()),  // evt.getX() ??
+                                                    (int)Math.floor(p.getY()),  // evt.getY() ??
                                                     screenPos.x,
                                                     screenPos.y,
                                                     evt.getClickCount(),
@@ -486,9 +493,8 @@
                                                     MouseEvent.
                                                     MOUSE_ENTERED,
                                                     evt.getWhen(),
-                                                    evt.
-                                                    getModifiers(),
-                                                    getCurrentLockState(),
+                                                    evt.getModifiers(),
+                                                    currentLockState,
                                                     (float)gnp.getX(),
                                                     (float)gnp.getY(),
                                                     (int)Math.floor(p.getX()),
@@ -507,7 +513,7 @@
                                                 evt.getID(),
                                                 evt.getWhen(),
                                                 evt.getModifiers(),
-                                                getCurrentLockState(),
+                                                currentLockState,
                                                 (float)gnp.getX(),
                                                 (float)gnp.getY(),
                                                 (int)Math.floor(p.getX()),
@@ -526,7 +532,7 @@
                                                 evt.getID(),
                                                 evt.getWhen(),
                                                 evt.getModifiers(),
-                                                getCurrentLockState(),
+                                                currentLockState,
                                                 (float)gnp.getX(),
                                                 (float)gnp.getY(),
                                                 (int)Math.floor(p.getX()),
@@ -588,7 +594,7 @@
                 }
                 break;
             default:
-                throw new Error("Unknown Mouse Event type: "+evt.getID());
+                throw new IllegalArgumentException("Unknown Mouse Event type: "+evt.getID());
             }
         }
     }
@@ -622,7 +628,7 @@
                 }
                 break;
             default:
-                throw new Error("Unknown Key Event type: "+evt.getID());
+                throw new IllegalArgumentException("Unknown Key Event type: "+evt.getID());
             }
         }
         evt.consume();
@@ -630,12 +636,12 @@
 
     private void incrementKeyTarget() {
         // <!> FIXME TODO: Not implemented.
-        throw new Error("Increment not implemented.");
+        throw new UnsupportedOperationException("Increment not implemented.");
     }
 
     private void decrementKeyTarget() {
         // <!> FIXME TODO: Not implemented.
-        throw new Error("Decrement not implemented.");
+        throw new UnsupportedOperationException("Decrement not implemented.");
     }
 
     /**
@@ -670,11 +676,31 @@
      * @param e the input event
      */
     protected boolean isNodeIncrementEvent(InputEvent e) {
-        // TODO: Improve code readability!
-        return ((e.getID() == nodeIncrementEventID) &&
-                ((e instanceof KeyEvent) ?
-                     (((KeyEvent) e).getKeyCode() == nodeIncrementEventCode) : true) &&
-                ((e.getModifiers() & nodeIncrementEventModifiers) != 0));
+        // DONE: Improve code readability!
+        //        return ((e.getID() == nodeIncrementEventID) &&
+        //                ((e instanceof KeyEvent) ?
+        //                     (((KeyEvent) e).getKeyCode() == nodeIncrementEventCode) : true) &&
+        //                ((e.getModifiers() & nodeIncrementEventModifiers) != 0));
+
+        if ( e.getID() != nodeIncrementEventID ){
+            // not an incrementEvent: false
+            return false;
+        }
+
+        if (( e instanceof KeyEvent ) ){
+            if (( (KeyEvent) e).getKeyCode() != nodeIncrementEventCode ){
+                // it was a KeyEvent, but not a nodeIncrementEventCode : false
+                return false;
+            }
+        }
+        // here: it was not a KeyEvent at all OR a KeyEvent with nodeIncrementEventCode
+        if (( e.getModifiers() & nodeIncrementEventModifiers ) == 0 ) {
+            // no nodeIncrementEventModifiers were set: false
+            return false;
+        }
+
+        // this is the only path to success...
+        return true;
     }
 
     /**
@@ -682,11 +708,30 @@
      * false otherwise.
      */
     protected boolean isNodeDecrementEvent(InputEvent e) {
-        // TODO: Improve code readability!
-        return ((e.getID() == nodeDecrementEventID) &&
-                ((e instanceof KeyEvent) ?
-                     ( ((KeyEvent) e).getKeyCode() == nodeDecrementEventCode) : true) &&
-                ((e.getModifiers() & nodeDecrementEventModifiers) != 0  ));
+        // DONE: Improve code readability!   YES !!
+        //        return ((e.getID() == nodeDecrementEventID) &&
+        //                ((e instanceof KeyEvent) ?
+        //                     ( ((KeyEvent) e).getKeyCode() == nodeDecrementEventCode) : true) &&
+        //                ((e.getModifiers() & nodeDecrementEventModifiers) != 0  ));
+
+        if ( e.getID() != nodeDecrementEventID ){
+            // not an nodeDecrementEvent: false
+            return false;
+        }
+
+        if (( e instanceof KeyEvent ) ){
+            if (( (KeyEvent) e).getKeyCode() != nodeDecrementEventCode ){
+                // it was a KeyEvent, but not a nodeDecrementEventCode : false
+                return false;
+            }
+        }
+        // here: it was not a KeyEvent at all OR a KeyEvent with nodeIncrementEventCode
+        if (( e.getModifiers() & nodeDecrementEventModifiers ) == 0 ) {
+            // no nodeDecrementEventModifiers were set: false
+            return false;
+        }
 
+        // this is the only path to success...
+        return true;
     }
 }