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 ga...@apache.org on 2014/11/09 08:35:58 UTC

svn commit: r1637636 - in /xmlgraphics/batik/branches/text-background/sources/org/apache/batik: bridge/ css/engine/ css/engine/value/css2/ gvt/renderer/ gvt/text/ util/

Author: gadams
Date: Sun Nov  9 07:35:57 2014
New Revision: 1637636

URL: http://svn.apache.org/r1637636
Log:
Handle nested backgrounds properly.

Added:
    xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/value/css2/BackgroundPaddingLengthManager.java
      - copied, changed from r1636251, xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/value/svg12/MarginLengthManager.java
    xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/value/css2/BackgroundPaddingShorthandManager.java
      - copied, changed from r1636251, xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/value/svg12/MarginShorthandManager.java
Modified:
    xmlgraphics/batik/branches/text-background/sources/org/apache/batik/bridge/SVGTextElementBridge.java
    xmlgraphics/batik/branches/text-background/sources/org/apache/batik/bridge/TextUtilities.java
    xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/SVGCSSEngine.java
    xmlgraphics/batik/branches/text-background/sources/org/apache/batik/gvt/renderer/StrokingTextPainter.java
    xmlgraphics/batik/branches/text-background/sources/org/apache/batik/gvt/text/GVTAttributedCharacterIterator.java
    xmlgraphics/batik/branches/text-background/sources/org/apache/batik/util/CSSConstants.java
    xmlgraphics/batik/branches/text-background/sources/org/apache/batik/util/SVGConstants.java

Modified: xmlgraphics/batik/branches/text-background/sources/org/apache/batik/bridge/SVGTextElementBridge.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/text-background/sources/org/apache/batik/bridge/SVGTextElementBridge.java?rev=1637636&r1=1637635&r2=1637636&view=diff
==============================================================================
--- xmlgraphics/batik/branches/text-background/sources/org/apache/batik/bridge/SVGTextElementBridge.java (original)
+++ xmlgraphics/batik/branches/text-background/sources/org/apache/batik/bridge/SVGTextElementBridge.java Sun Nov  9 07:35:57 2014
@@ -20,6 +20,7 @@ package org.apache.batik.bridge;
 
 import java.awt.AlphaComposite;
 import java.awt.Color;
+import java.awt.Paint;
 import java.awt.RenderingHints;
 import java.awt.Shape;
 import java.awt.font.TextAttribute;
@@ -143,6 +144,10 @@ public class SVGTextElementBridge extend
         AttributedCharacterIterator.Attribute LINE_HEIGHT
         = GVTAttributedCharacterIterator.TextAttribute.LINE_HEIGHT;
 
+    public static final
+        AttributedCharacterIterator.Attribute BACKGROUND_PADDING
+        = GVTAttributedCharacterIterator.TextAttribute.BACKGROUND_PADDING;
+
     protected AttributedString laidoutText;
 
     // This is used to track the TextPainterInfo for each element
@@ -926,6 +931,7 @@ public class SVGTextElementBridge extend
         Map map = initialAttributes == null
                 ? new HashMap()
                 : new HashMap(initialAttributes);
+        // augment initial attributes with this element's attribute map
         initialAttributes =
             getAttributeMap(ctx, element, textPath, bidiLevel, map);
         // retain top level text element's attributes
@@ -1626,12 +1632,15 @@ public class SVGTextElementBridge extend
         TextPaintInfo pi = new TextPaintInfo();
         // Set some basic props so we can get bounds info for complex paints.
         pi.visible   = true;
-        pi.backgroundPaint = TRANSPARENT;
-        pi.backgroundMode = BackgroundMode.LINE_HEIGHT;
         pi.fillPaint = Color.black;
         result.put(PAINT_INFO, pi);
         elemTPI.put(element, pi);
 
+        // Background padding
+        float[] backgroundPadding = TextUtilities.convertBackgroundPadding(element);
+        result.put(BACKGROUND_PADDING, backgroundPadding);
+
+        // Text path
         if (textPath != null) {
             result.put(TEXTPATH, textPath);
         }
@@ -1933,7 +1942,8 @@ public class SVGTextElementBridge extend
             (sm.isNullCascaded(SVGCSSEngine.STROKE_INDEX)) &&
             (sm.isNullCascaded(SVGCSSEngine.STROKE_WIDTH_INDEX)) &&
             (sm.isNullCascaded(SVGCSSEngine.OPACITY_INDEX)) &&
-            (sm.isNullCascaded(SVGCSSEngine.BACKGROUND_INDEX))) {
+            (sm.isNullCascaded(SVGCSSEngine.BACKGROUND_INDEX)) &&
+            (sm.isNullCascaded(SVGCSSEngine.BACKGROUND_MODE_INDEX))) {
             // If not, keep the same decorations.
             return pi;
         }
@@ -1954,8 +1964,13 @@ public class SVGTextElementBridge extend
             pi.composite    = AlphaComposite.SrcOver;
 
         pi.visible      = CSSUtilities.convertVisibility(element);
-        pi.backgroundPaint = PaintServer.convertBackgroundPaint(element, node, ctx);
-        pi.backgroundMode = TextUtilities.convertBackgroundMode(element);
+        StyleMap sm = ((CSSStylableElement)element).getComputedStyleMap(null);
+        Paint backgroundPaint = PaintServer.convertBackgroundPaint(element, node, ctx);
+        if (!sm.isNullCascaded(SVGCSSEngine.BACKGROUND_INDEX))
+            pi.backgroundPaint = backgroundPaint;
+        BackgroundMode backgroundMode = TextUtilities.convertBackgroundMode(element);
+        if (!sm.isNullCascaded(SVGCSSEngine.BACKGROUND_MODE_INDEX))
+            pi.backgroundMode = backgroundMode;
         pi.fillPaint    = PaintServer.convertFillPaint  (element, node, ctx);
         pi.strokePaint  = PaintServer.convertStrokePaint(element, node, ctx);
         pi.strokeStroke = PaintServer.convertStroke     (element);

Modified: xmlgraphics/batik/branches/text-background/sources/org/apache/batik/bridge/TextUtilities.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/text-background/sources/org/apache/batik/bridge/TextUtilities.java?rev=1637636&r1=1637635&r2=1637636&view=diff
==============================================================================
--- xmlgraphics/batik/branches/text-background/sources/org/apache/batik/bridge/TextUtilities.java (original)
+++ xmlgraphics/batik/branches/text-background/sources/org/apache/batik/bridge/TextUtilities.java Sun Nov  9 07:35:57 2014
@@ -286,7 +286,7 @@ public abstract class TextUtilities impl
     }
 
     /**
-     * Converts the backgorund-mode CSS value to a TextNode.BackgroundMode.
+     * Converts the background-mode CSS value to a TextNode.BackgroundMode.
      * @param e the element
      */
     public static TextNode.BackgroundMode convertBackgroundMode(Element e) {
@@ -303,6 +303,27 @@ public abstract class TextUtilities impl
     }
 
     /**
+     * Converts the background-padding CSS value to a floats[] instance.
+     * @param e the element
+     */
+    public static float[] convertBackgroundPadding(Element e) {
+        Value v;
+        v = CSSUtilities.getComputedStyle(e, SVGCSSEngine.BACKGROUND_PADDING_TOP_INDEX);
+        float top = v.getFloatValue();
+
+        v = CSSUtilities.getComputedStyle(e, SVGCSSEngine.BACKGROUND_PADDING_RIGHT_INDEX);
+        float right = v.getFloatValue();
+
+        v = CSSUtilities.getComputedStyle(e, SVGCSSEngine.BACKGROUND_PADDING_BOTTOM_INDEX);
+        float bottom = v.getFloatValue();
+
+        v = CSSUtilities.getComputedStyle(e, SVGCSSEngine.BACKGROUND_PADDING_LEFT_INDEX);
+        float left = v.getFloatValue();
+
+        return new float[] { top, right, bottom, left };
+    }
+
+    /**
      * Converts a baseline-shift CSS value to a value usable as a text
      * attribute, or null.
      * @param e the element

Modified: xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/SVGCSSEngine.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/SVGCSSEngine.java?rev=1637636&r1=1637635&r2=1637636&view=diff
==============================================================================
--- xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/SVGCSSEngine.java (original)
+++ xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/SVGCSSEngine.java Sun Nov  9 07:35:57 2014
@@ -22,6 +22,8 @@ import org.apache.batik.css.engine.value
 import org.apache.batik.css.engine.value.ValueConstants;
 import org.apache.batik.css.engine.value.ValueManager;
 import org.apache.batik.css.engine.value.css2.BackgroundModeManager;
+import org.apache.batik.css.engine.value.css2.BackgroundPaddingShorthandManager;
+import org.apache.batik.css.engine.value.css2.BackgroundPaddingLengthManager;
 import org.apache.batik.css.engine.value.css2.ClipManager;
 import org.apache.batik.css.engine.value.css2.CursorManager;
 import org.apache.batik.css.engine.value.css2.DirectionManager;
@@ -192,6 +194,10 @@ public class SVGCSSEngine extends CSSEng
         new AlignmentBaselineManager(),
         new SVGColorManager(CSSConstants.CSS_BACKGROUND_PROPERTY, ValueConstants.TRANSPARENT_VALUE),
         new BackgroundModeManager(),
+        new BackgroundPaddingLengthManager(CSSConstants.CSS_BACKGROUND_PADDING_BOTTOM_PROPERTY),
+        new BackgroundPaddingLengthManager(CSSConstants.CSS_BACKGROUND_PADDING_LEFT_PROPERTY),
+        new BackgroundPaddingLengthManager(CSSConstants.CSS_BACKGROUND_PADDING_RIGHT_PROPERTY),
+        new BackgroundPaddingLengthManager(CSSConstants.CSS_BACKGROUND_PADDING_TOP_PROPERTY),
         new BaselineShiftManager(),
         new ClipManager(),
         new ClipPathManager(),
@@ -271,6 +277,7 @@ public class SVGCSSEngine extends CSSEng
      * The shorthand managers for SVG.
      */
     public static final ShorthandManager[] SVG_SHORTHAND_MANAGERS = {
+        new BackgroundPaddingShorthandManager(),
         new FontShorthandManager(),
         new MarkerShorthandManager(),
     };
@@ -281,8 +288,12 @@ public class SVGCSSEngine extends CSSEng
     public static final int ALIGNMENT_BASELINE_INDEX = 0;
     public static final int BACKGROUND_INDEX = ALIGNMENT_BASELINE_INDEX + 1;
     public static final int BACKGROUND_MODE_INDEX = BACKGROUND_INDEX + 1;
+    public static final int BACKGROUND_PADDING_BOTTOM_INDEX = BACKGROUND_MODE_INDEX + 1;
+    public static final int BACKGROUND_PADDING_LEFT_INDEX = BACKGROUND_PADDING_BOTTOM_INDEX + 1;
+    public static final int BACKGROUND_PADDING_RIGHT_INDEX = BACKGROUND_PADDING_LEFT_INDEX + 1;
+    public static final int BACKGROUND_PADDING_TOP_INDEX = BACKGROUND_PADDING_RIGHT_INDEX + 1;
     public static final int BASELINE_SHIFT_INDEX =
-        BACKGROUND_MODE_INDEX + 1;
+        BACKGROUND_PADDING_TOP_INDEX + 1;
     public static final int CLIP_INDEX = BASELINE_SHIFT_INDEX + 1;
     public static final int CLIP_PATH_INDEX = CLIP_INDEX +1;
     public static final int CLIP_RULE_INDEX = CLIP_PATH_INDEX + 1;

Copied: xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/value/css2/BackgroundPaddingLengthManager.java (from r1636251, xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/value/svg12/MarginLengthManager.java)
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/value/css2/BackgroundPaddingLengthManager.java?p2=xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/value/css2/BackgroundPaddingLengthManager.java&p1=xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/value/svg12/MarginLengthManager.java&r1=1636251&r2=1637636&rev=1637636&view=diff
==============================================================================
--- xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/value/svg12/MarginLengthManager.java (original)
+++ xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/value/css2/BackgroundPaddingLengthManager.java Sun Nov  9 07:35:57 2014
@@ -17,29 +17,29 @@
 
 */
 
-package org.apache.batik.css.engine.value.svg12;
+package org.apache.batik.css.engine.value.css2;
 
 import org.apache.batik.css.engine.CSSEngine;
 import org.apache.batik.css.engine.value.LengthManager;
 import org.apache.batik.css.engine.value.Value;
+import org.apache.batik.css.engine.value.ValueConstants;
 import org.apache.batik.css.engine.value.ValueManager;
-import org.apache.batik.css.engine.value.svg.SVGValueConstants;
 import org.apache.batik.util.SVGTypes;
 
 import org.w3c.css.sac.LexicalUnit;
 import org.w3c.dom.DOMException;
 
 /**
- * This class provides a factory for the 'margin-*' properties values.
+ * This class provides a factory for the 'background-padding-*' properties values.
  *
- * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @author <a href="mailto:gadams@apache.org">Glenn Adams</a>
  * @version $Id$
  */
-public class MarginLengthManager extends LengthManager {
+public class BackgroundPaddingLengthManager extends LengthManager {
 
     protected String  prop;
 
-    public MarginLengthManager(String prop) {
+    public BackgroundPaddingLengthManager(String prop) {
         this.prop = prop;
     }
     
@@ -47,7 +47,7 @@ public class MarginLengthManager extends
      * Implements {@link ValueManager#isInheritedProperty()}.
      */
     public boolean isInheritedProperty() {
-        return true;
+        return false;
     }
 
     /**
@@ -82,7 +82,7 @@ public class MarginLengthManager extends
      * Implements {@link ValueManager#getDefaultValue()}.
      */
     public Value getDefaultValue() {
-        return SVGValueConstants.NUMBER_0;
+        return ValueConstants.NUMBER_0;
     }
 
     /**
@@ -91,7 +91,7 @@ public class MarginLengthManager extends
     public Value createValue(LexicalUnit lu, CSSEngine engine)
         throws DOMException {
         if (lu.getLexicalUnitType() == LexicalUnit.SAC_INHERIT) {
-            return SVGValueConstants.INHERIT_VALUE;
+            return ValueConstants.INHERIT_VALUE;
         }
         return super.createValue(lu, engine);
     }
@@ -102,7 +102,7 @@ public class MarginLengthManager extends
      * this manager.
      */
     protected int getOrientation() {
-        // Margins are always wrt to block width, event for top/bottom.
+        // background paddings are always wrt to block width, event for top/bottom.
         return HORIZONTAL_ORIENTATION;
     }
 }

Copied: xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/value/css2/BackgroundPaddingShorthandManager.java (from r1636251, xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/value/svg12/MarginShorthandManager.java)
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/value/css2/BackgroundPaddingShorthandManager.java?p2=xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/value/css2/BackgroundPaddingShorthandManager.java&p1=xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/value/svg12/MarginShorthandManager.java&r1=1636251&r2=1637636&rev=1637636&view=diff
==============================================================================
--- xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/value/svg12/MarginShorthandManager.java (original)
+++ xmlgraphics/batik/branches/text-background/sources/org/apache/batik/css/engine/value/css2/BackgroundPaddingShorthandManager.java Sun Nov  9 07:35:57 2014
@@ -16,34 +16,34 @@
    limitations under the License.
 
  */
-package org.apache.batik.css.engine.value.svg12;
+package org.apache.batik.css.engine.value.css2;
 
 import org.apache.batik.css.engine.CSSEngine;
 import org.apache.batik.css.engine.value.AbstractValueFactory;
 import org.apache.batik.css.engine.value.ShorthandManager;
 import org.apache.batik.css.engine.value.ValueManager;
-import org.apache.batik.util.SVG12CSSConstants;
+import org.apache.batik.util.CSSConstants;
 import org.w3c.css.sac.LexicalUnit;
 import org.w3c.dom.DOMException;
 
 /**
  * This class represents an object which provide support for the
- * 'margin' shorthand property.
+ * 'background-padding' shorthand property.
  *
- * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @author <a href="mailto:gadams@apache.org">Glenn Adams</a>
  * @version $Id$
  */
-public class MarginShorthandManager
+public class BackgroundPaddingShorthandManager
     extends AbstractValueFactory
     implements ShorthandManager {
 
-    public MarginShorthandManager() { }
+    public BackgroundPaddingShorthandManager() { }
     
     /**
      * Implements {@link ValueManager#getPropertyName()}.
      */
     public String getPropertyName() {
-        return SVG12CSSConstants.CSS_MARGIN_PROPERTY;
+        return CSSConstants.CSS_BACKGROUND_PADDING_PROPERTY;
     }
     
     /**
@@ -87,9 +87,9 @@ public class MarginShorthandManager
         default:
         }
 
-        ph.property(SVG12CSSConstants.CSS_MARGIN_TOP_PROPERTY,    lus[0], imp);
-        ph.property(SVG12CSSConstants.CSS_MARGIN_RIGHT_PROPERTY,  lus[1], imp);
-        ph.property(SVG12CSSConstants.CSS_MARGIN_BOTTOM_PROPERTY, lus[2], imp);
-        ph.property(SVG12CSSConstants.CSS_MARGIN_LEFT_PROPERTY,   lus[3], imp);
+        ph.property(CSSConstants.CSS_BACKGROUND_PADDING_TOP_PROPERTY,    lus[0], imp);
+        ph.property(CSSConstants.CSS_BACKGROUND_PADDING_RIGHT_PROPERTY,  lus[1], imp);
+        ph.property(CSSConstants.CSS_BACKGROUND_PADDING_BOTTOM_PROPERTY, lus[2], imp);
+        ph.property(CSSConstants.CSS_BACKGROUND_PADDING_LEFT_PROPERTY,   lus[3], imp);
     }
 }

Modified: xmlgraphics/batik/branches/text-background/sources/org/apache/batik/gvt/renderer/StrokingTextPainter.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/text-background/sources/org/apache/batik/gvt/renderer/StrokingTextPainter.java?rev=1637636&r1=1637635&r2=1637636&view=diff
==============================================================================
--- xmlgraphics/batik/branches/text-background/sources/org/apache/batik/gvt/renderer/StrokingTextPainter.java (original)
+++ xmlgraphics/batik/branches/text-background/sources/org/apache/batik/gvt/renderer/StrokingTextPainter.java Sun Nov  9 07:35:57 2014
@@ -30,6 +30,7 @@ import java.awt.font.TextAttribute;
 import java.awt.geom.GeneralPath;
 import java.awt.geom.Point2D;
 import java.awt.geom.Rectangle2D;
+import java.lang.ref.SoftReference;
 import java.text.AttributedCharacterIterator;
 import java.text.AttributedString;
 import java.text.CharacterIterator;
@@ -59,7 +60,6 @@ import org.apache.batik.gvt.text.TextPai
 import org.apache.batik.gvt.text.TextPath;
 import org.apache.batik.gvt.text.TextSpanLayout;
 
-
 /**
  * More sophisticated implementation of TextPainter which
  * renders the attributed character iterator of a <code>TextNode</code>.
@@ -139,6 +139,10 @@ public class StrokingTextPainter extends
         AttributedCharacterIterator.Attribute LINE_HEIGHT
         = GVTAttributedCharacterIterator.TextAttribute.LINE_HEIGHT;
 
+    public static final
+        AttributedCharacterIterator.Attribute BACKGROUND_PADDING
+        = GVTAttributedCharacterIterator.TextAttribute.BACKGROUND_PADDING;
+
     static Set extendedAtts = new HashSet();
 
     static {
@@ -176,7 +180,7 @@ public class StrokingTextPainter extends
         // 1. draw text node background
         paintBackground(node, textRuns, g2d);
         // 2. draw text run backgrounds
-        paintBackgrounds(textRuns, g2d);
+        paintBackgrounds(node, textRuns, g2d);
         // 3. draw text run underline and overline
         paintDecorations(textRuns, g2d, TextSpanLayout.DECORATION_UNDERLINE);
         paintDecorations(textRuns, g2d, TextSpanLayout.DECORATION_OVERLINE);
@@ -875,17 +879,20 @@ public class StrokingTextPainter extends
      */
     protected void paintBackground(TextNode node, List textRuns, Graphics2D g2d) {
         Map textAttributes = node.getTextAttributes();
-        TextPaintInfo tpi = (textAttributes != null) ? (TextPaintInfo) textAttributes.get(PAINT_INFO) : null;
-        if (tpi != null) {
-            if (tpi.visible) {
-                Paint paint = tpi.backgroundPaint;
-                BackgroundMode mode = tpi.backgroundMode;
-                if (paint != null) {
-                    if ((paint instanceof Color) && (((Color)paint).getAlpha() != 0)) {
-                        Rectangle2D bounds = computeBackgroundBounds(node, textRuns, mode);
-                        if (!bounds.isEmpty()) {
-                            g2d.setPaint(paint);
-                            g2d.fill(bounds);
+        if (textAttributes != null) {
+            TextPaintInfo tpi = (TextPaintInfo) textAttributes.get(PAINT_INFO);
+            if (tpi != null) {
+                if (tpi.visible) {
+                    Paint paint = tpi.backgroundPaint;
+                    BackgroundMode mode = tpi.backgroundMode;
+                    if (paint != null) {
+                        if ((paint instanceof Color) && (((Color)paint).getAlpha() != 0)) {
+                            float[] padding = (float[]) textAttributes.get(BACKGROUND_PADDING);
+                            Rectangle2D bounds = computeBackgroundBounds(node, textRuns, mode);
+                            if (!bounds.isEmpty()) {
+                                g2d.setPaint(paint);
+                                g2d.fill(bounds);
+                            }
                         }
                     }
                 }
@@ -895,7 +902,7 @@ public class StrokingTextPainter extends
 
     private Rectangle2D computeBackgroundBounds(TextNode node, List textRuns, BackgroundMode mode) {
         if (mode == BackgroundMode.BBOX) {
-            return node.getPrimitiveBounds();
+            return computeBBoxBounds(node.getPrimitiveBounds());
         } else if (mode == BackgroundMode.LINE_HEIGHT) {
             TextRun run = (TextRun) textRuns.get(0);
             TextSpanLayout layout = run.getLayout();
@@ -917,22 +924,51 @@ public class StrokingTextPainter extends
     /**
      * Paint text run backgrounds.
      */
-    protected void paintBackgrounds(List textRuns, Graphics2D g2d) {
-        for (int i = 0; i < textRuns.size(); i++) {
-            TextRun textRun = (TextRun)textRuns.get(i);
-            AttributedCharacterIterator runaci = textRun.getACI();
-            runaci.first();
-            TextPaintInfo tpi = (TextPaintInfo)runaci.getAttribute(PAINT_INFO);
-            if (tpi != null) {
-                if (tpi.visible) {
-                    Paint paint = tpi.backgroundPaint;
-                    BackgroundMode mode = tpi.backgroundMode;
-                    if (paint != null) {
-                        if ((paint instanceof Color) && (((Color)paint).getAlpha() != 0)) {
-                            Rectangle2D bounds = computeBackgroundBounds(textRun, mode);
-                            if (!bounds.isEmpty()) {
-                                g2d.setPaint(paint);
-                                g2d.fill(bounds);
+    protected void paintBackgrounds(TextNode node, List textRuns, Graphics2D g2d) {
+        Map textAttributes = node.getTextAttributes();
+        if (textAttributes != null) {
+            TextPaintInfo tpiText = (TextPaintInfo) textAttributes.get(PAINT_INFO);
+            if (tpiText != null) {
+                if (tpiText.visible) {
+                    int numRuns = textRuns.size();
+                    List elements = new java.util.ArrayList(numRuns);
+                    for (int i = 0; i < numRuns; i++) {
+                        TextRun textRun = (TextRun)textRuns.get(i);
+                        AttributedCharacterIterator runaci = textRun.getACI();
+                        runaci.first();
+                        elements.add(((SoftReference) runaci.getAttribute(TEXT_COMPOUND_ID)).get());
+                    }
+                    Set eDrawn = new HashSet();
+                    for (int i = 0; i < numRuns; i++) {
+                        TextRun textRun = (TextRun)textRuns.get(i);
+                        AttributedCharacterIterator runaci = textRun.getACI();
+                        runaci.first();
+                        TextPaintInfo tpi = (TextPaintInfo)runaci.getAttribute(PAINT_INFO);
+                        if (tpi != null) {
+                            Object e = elements.get(i);
+                            if ((tpi == tpiText) || eDrawn.contains(e))
+                                continue;
+                            else if (tpi.visible) {
+                                Paint paint = tpi.backgroundPaint;
+                                BackgroundMode mode = tpi.backgroundMode;
+                                if (paint != null) {
+                                    if ((paint instanceof Color) && (((Color)paint).getAlpha() != 0)) {
+                                        GeneralPath p = new GeneralPath();
+                                        for (int j = i; j < numRuns; j++) {
+                                            Object eRun = elements.get(j);
+                                            if (eRun == e) {
+                                                Rectangle2D bRun = computeBackgroundBounds((TextRun) textRuns.get(j), mode);
+                                                p.append(bRun, false);
+                                            }
+                                        }
+                                        Rectangle2D b = p.getBounds2D();
+                                        if (!b.isEmpty()) {
+                                            g2d.setPaint(paint);
+                                            g2d.fill(b);
+                                        }
+                                    }
+                                }
+                                eDrawn.add(e);
                             }
                         }
                     }
@@ -943,7 +979,7 @@ public class StrokingTextPainter extends
 
     private Rectangle2D computeBackgroundBounds(TextRun run, BackgroundMode mode) {
         if (mode == BackgroundMode.BBOX) {
-            return run.getLayout().getBounds2D();
+            return computeBBoxBounds(run.getLayout().getBounds2D());
         } else if (mode == BackgroundMode.LINE_HEIGHT) {
             TextSpanLayout layout = run.getLayout();
             GVTLineMetrics lineMetrics = layout.getLineMetrics();
@@ -962,9 +998,17 @@ public class StrokingTextPainter extends
         }
     }
 
-    private Rectangle2D computeLineHeightBounds(Point2D position, double ascent, double emHeight, double lineHeight, double width) {
-            double y = position.getY() - (ascent / emHeight) * lineHeight;
-            return new Rectangle2D.Double(position.getX(), y, width, lineHeight);
+    private Rectangle2D computeBBoxBounds(Rectangle2D bbox) {
+        return bbox;
+    }
+
+    private Rectangle2D computeLineHeightBounds(
+        Point2D position, double ascent, double emHeight, double lineHeight, double width) {
+        double x = position.getX();
+        double y = position.getY() - (ascent / emHeight) * lineHeight;
+        double w = width;
+        double h = lineHeight;
+        return new Rectangle2D.Double(x, y, w, h);
     }
 
     /**

Modified: xmlgraphics/batik/branches/text-background/sources/org/apache/batik/gvt/text/GVTAttributedCharacterIterator.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/text-background/sources/org/apache/batik/gvt/text/GVTAttributedCharacterIterator.java?rev=1637636&r1=1637635&r2=1637636&view=diff
==============================================================================
--- xmlgraphics/batik/branches/text-background/sources/org/apache/batik/gvt/text/GVTAttributedCharacterIterator.java (original)
+++ xmlgraphics/batik/branches/text-background/sources/org/apache/batik/gvt/text/GVTAttributedCharacterIterator.java Sun Nov  9 07:35:57 2014
@@ -351,8 +351,8 @@ public interface GVTAttributedCharacterI
         public static final TextAttribute LANGUAGE =
                                           new TextAttribute("LANGUAGE");
 
-        public static final TextAttribute BACKGROUND_MODE =
-                                          new TextAttribute("BACKGROUND_MODE");
+        public static final TextAttribute BACKGROUND_PADDING =
+                                          new TextAttribute("BACKGROUND_PADDING");
 
         // VALUES
 

Modified: xmlgraphics/batik/branches/text-background/sources/org/apache/batik/util/CSSConstants.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/text-background/sources/org/apache/batik/util/CSSConstants.java?rev=1637636&r1=1637635&r2=1637636&view=diff
==============================================================================
--- xmlgraphics/batik/branches/text-background/sources/org/apache/batik/util/CSSConstants.java (original)
+++ xmlgraphics/batik/branches/text-background/sources/org/apache/batik/util/CSSConstants.java Sun Nov  9 07:35:57 2014
@@ -38,6 +38,11 @@ public interface CSSConstants {
     String CSS_ALIGNMENT_BASELINE_PROPERTY = "alignment-baseline";
     String CSS_BACKGROUND_PROPERTY = "background";
     String CSS_BACKGROUND_MODE_PROPERTY = "background-mode";
+    String CSS_BACKGROUND_PADDING_PROPERTY = "background-padding";
+    String CSS_BACKGROUND_PADDING_BOTTOM_PROPERTY = "background-padding-bottom";
+    String CSS_BACKGROUND_PADDING_LEFT_PROPERTY = "background-padding-left";
+    String CSS_BACKGROUND_PADDING_RIGHT_PROPERTY = "background-padding-right";
+    String CSS_BACKGROUND_PADDING_TOP_PROPERTY = "background-padding-top";
     String CSS_BASELINE_SHIFT_PROPERTY = "baseline-shift";
     String CSS_CLIP_PROPERTY = "clip";
     String CSS_CLIP_PATH_PROPERTY = "clip-path";

Modified: xmlgraphics/batik/branches/text-background/sources/org/apache/batik/util/SVGConstants.java
URL: http://svn.apache.org/viewvc/xmlgraphics/batik/branches/text-background/sources/org/apache/batik/util/SVGConstants.java?rev=1637636&r1=1637635&r2=1637636&view=diff
==============================================================================
--- xmlgraphics/batik/branches/text-background/sources/org/apache/batik/util/SVGConstants.java (original)
+++ xmlgraphics/batik/branches/text-background/sources/org/apache/batik/util/SVGConstants.java Sun Nov  9 07:35:57 2014
@@ -442,6 +442,11 @@ public interface SVGConstants extends CS
     String SVG_ATTRIBUTE_TYPE_ATTRIBUTE = "attributeType";
     String SVG_BACKGROUND_ATTRIBUTE = CSS_BACKGROUND_PROPERTY;
     String SVG_BACKGROUND_MODE_ATTRIBUTE = CSS_BACKGROUND_MODE_PROPERTY;
+    String SVG_BACKGROUND_PADDING_ATTRIBUTE = CSS_BACKGROUND_PADDING_PROPERTY;
+    String SVG_BACKGROUND_PADDING_BOTTOM_ATTRIBUTE = CSS_BACKGROUND_PADDING_BOTTOM_PROPERTY;
+    String SVG_BACKGROUND_PADDING_LEFT_ATTRIBUTE = CSS_BACKGROUND_PADDING_LEFT_PROPERTY;
+    String SVG_BACKGROUND_PADDING_RIGHT_ATTRIBUTE = CSS_BACKGROUND_PADDING_RIGHT_PROPERTY;
+    String SVG_BACKGROUND_PADDING_TOP_ATTRIBUTE = CSS_BACKGROUND_PADDING_TOP_PROPERTY;
     String SVG_BASE_FREQUENCY_ATTRIBUTE = "baseFrequency";
     String SVG_BASE_PROFILE_ATTRIBUTE = "baseProfile";
     String SVG_BEGIN_ATTRIBUTE = "begin";