BATIK-1092: Add text background support (preliminary).
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/batik/branches/text-background-integration@1816962 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/batik-bridge/src/main/java/org/apache/batik/bridge/PaintServer.java b/batik-bridge/src/main/java/org/apache/batik/bridge/PaintServer.java
index 4caa51a..53014a5 100644
--- a/batik-bridge/src/main/java/org/apache/batik/bridge/PaintServer.java
+++ b/batik-bridge/src/main/java/org/apache/batik/bridge/PaintServer.java
@@ -27,6 +27,8 @@
import java.io.IOException;
import org.apache.batik.css.engine.SVGCSSEngine;
+import org.apache.batik.css.engine.value.ComputedValue;
+import org.apache.batik.css.engine.value.RGBAColorValue;
import org.apache.batik.css.engine.value.Value;
import org.apache.batik.css.engine.value.svg.ICCColor;
import org.apache.batik.css.engine.value.svg12.CIELabColor;
@@ -247,6 +249,28 @@
}
/**
+ * Converts for the specified element, its background paint properties
+ * to a Paint object.
+ *
+ * @param backgroundElement the element interested in a Paint
+ * @param backgroundNode the graphics node to fill
+ * @param ctx the bridge context
+ */
+ public static Paint convertBackgroundPaint(Element backgroundElement,
+ GraphicsNode backgroundNode,
+ BridgeContext ctx) {
+ Value v = CSSUtilities.getComputedStyle
+ (backgroundElement, SVGCSSEngine.BACKGROUND_COLOR_INDEX);
+ float opacity = 1f;
+
+ return convertPaint(backgroundElement,
+ backgroundNode,
+ v,
+ opacity,
+ ctx);
+ }
+
+ /**
* Converts a Paint definition to a concrete <code>java.awt.Paint</code>
* instance according to the specified parameters.
*
@@ -584,9 +608,15 @@
* @param opacity The opacity value (0 <= o <= 1).
*/
public static Color convertColor(Value c, float opacity) {
+ if (c instanceof ComputedValue)
+ c = ((ComputedValue)c).getComputedValue();
int r = resolveColorComponent(c.getRed());
int g = resolveColorComponent(c.getGreen());
int b = resolveColorComponent(c.getBlue());
+ if (c instanceof RGBAColorValue) {
+ return new Color(r, g, b,
+ Math.round(resolveAlphaComponent(((RGBAColorValue)c).getAlpha()) * 255f));
+ } else
return new Color(r, g, b, Math.round(opacity * 255f));
}
@@ -758,6 +788,27 @@
}
/**
+ * Returns the value of the alpha component as a float in range [0.0, 1.0].
+ * @param v the value that defines the alpha component
+ */
+ public static float resolveAlphaComponent(Value v) {
+ float f;
+ switch(v.getPrimitiveType()) {
+ case CSSPrimitiveValue.CSS_PERCENTAGE:
+ f = v.getFloatValue();
+ f = (f > 100f) ? 100f : (f < 0f) ? 0f : f;
+ return f / 100f;
+ case CSSPrimitiveValue.CSS_NUMBER:
+ f = v.getFloatValue();
+ f = (f > 1f) ? 1f : (f < 0f) ? 0f : f;
+ return f;
+ default:
+ throw new IllegalArgumentException
+ ("Alpha component argument is not an appropriate CSS value");
+ }
+ }
+
+ /**
* Returns the opacity represented by the specified CSSValue.
* @param v the value that represents the opacity
* @return the opacity between 0 and 1
diff --git a/batik-bridge/src/main/java/org/apache/batik/bridge/SVGTextElementBridge.java b/batik-bridge/src/main/java/org/apache/batik/bridge/SVGTextElementBridge.java
index 5a9dfec..dff1eed 100644
--- a/batik-bridge/src/main/java/org/apache/batik/bridge/SVGTextElementBridge.java
+++ b/batik-bridge/src/main/java/org/apache/batik/bridge/SVGTextElementBridge.java
@@ -20,6 +20,7 @@
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;
@@ -70,6 +71,7 @@
import org.apache.batik.gvt.text.TextPath;
import org.apache.batik.util.XMLConstants;
+
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.css.CSSPrimitiveValue;
@@ -82,6 +84,9 @@
import org.w3c.dom.svg.SVGTextContentElement;
import org.w3c.dom.svg.SVGTextPositioningElement;
+
+import org.apache.batik.css.engine.value.StringValue;
+
/**
* Bridge class for the <text> element.
*
@@ -94,6 +99,8 @@
protected static final Integer ZERO = 0;
+ public static final Color TRANSPARENT = new Color(0, 0, 0, 0);
+
public static final
AttributedCharacterIterator.Attribute TEXT_COMPOUND_DELIMITER =
GVTAttributedCharacterIterator.TextAttribute.TEXT_COMPOUND_DELIMITER;
@@ -129,6 +136,14 @@
AttributedCharacterIterator.Attribute BASELINE_SHIFT
= GVTAttributedCharacterIterator.TextAttribute.BASELINE_SHIFT;
+ public static final
+ AttributedCharacterIterator.Attribute LINE_HEIGHT
+ = GVTAttributedCharacterIterator.TextAttribute.LINE_HEIGHT;
+
+ public static final
+ AttributedCharacterIterator.Attribute BACKGROUND_OUTLINE
+ = GVTAttributedCharacterIterator.TextAttribute.BACKGROUND_OUTLINE;
+
protected AttributedString laidoutText;
// This is used to track the TextPainterInfo for each element
@@ -627,11 +642,13 @@
TextNode tn = (TextNode)node;
elemTPI.clear();
- AttributedString as = buildAttributedString(ctx, e);
+ Map[] returnTextAttributes = new Map[1];
+ AttributedString as = buildAttributedString(ctx, e, returnTextAttributes);
if (as == null) {
tn.setAttributedCharacterIterator(null);
return;
}
+ Map textAttributes = returnTextAttributes[0];
addGlyphPositionAttributes(as, e, ctx);
if (ctx.isDynamic()) {
@@ -639,7 +656,7 @@
}
// Install the ACI in the text node.
- tn.setAttributedCharacterIterator(as.getIterator());
+ tn.setAttributedCharacterIterator(as.getIterator(), textAttributes);
// Now get the real paint into - this needs to
// wait until the text node is laidout so we can get
@@ -653,7 +670,7 @@
if (usingComplexSVGFont) {
// Force Complex SVG fonts to be recreated, if we have them.
- tn.setAttributedCharacterIterator(as.getIterator());
+ tn.setAttributedCharacterIterator(as.getIterator(), textAttributes);
}
if (ctx.isDynamic()) {
@@ -747,6 +764,12 @@
*/
protected void handleCSSPropertyChanged(int property) {
switch(property) { // fall-through is intended
+ case SVGCSSEngine.BACKGROUND_COLOR_INDEX:
+ case SVGCSSEngine.BACKGROUND_MODE_INDEX:
+ case SVGCSSEngine.BACKGROUND_OUTLINE_BOTTOM_INDEX:
+ case SVGCSSEngine.BACKGROUND_OUTLINE_LEFT_INDEX:
+ case SVGCSSEngine.BACKGROUND_OUTLINE_RIGHT_INDEX:
+ case SVGCSSEngine.BACKGROUND_OUTLINE_TOP_INDEX:
case SVGCSSEngine.FILL_INDEX:
case SVGCSSEngine.FILL_OPACITY_INDEX:
case SVGCSSEngine.STROKE_INDEX:
@@ -816,7 +839,8 @@
if (usingComplexSVGFont)
// Force Complex SVG fonts to be recreated
textNode.setAttributedCharacterIterator
- (textNode.getAttributedCharacterIterator());
+ (textNode.getAttributedCharacterIterator(),
+ textNode.getTextAttributes());
}
int getElementStartIndex(Element element) {
@@ -845,12 +869,15 @@
*/
protected AttributedString buildAttributedString(BridgeContext ctx,
Element element) {
-
- AttributedStringBuffer asb = new AttributedStringBuffer();
- fillAttributedStringBuffer(ctx, element, true, null, null, null, asb);
- return asb.toAttributedString();
+ return this.buildAttributedString(ctx, element, null);
}
+ protected AttributedString buildAttributedString(BridgeContext ctx,
+ Element element, Map[] returnTextAttributes) {
+ AttributedStringBuffer asb = new AttributedStringBuffer();
+ fillAttributedStringBuffer(ctx, element, true, null, null, null, asb, returnTextAttributes);
+ return asb.toAttributedString();
+ }
/**
* This is used to store the end of the last piece of text
@@ -870,6 +897,17 @@
Integer bidiLevel,
Map initialAttributes,
AttributedStringBuffer asb) {
+ this.fillAttributedStringBuffer(ctx, element, top, textPath, bidiLevel, initialAttributes, asb);
+ }
+
+ protected void fillAttributedStringBuffer(BridgeContext ctx,
+ Element element,
+ boolean top,
+ TextPath textPath,
+ Integer bidiLevel,
+ Map initialAttributes,
+ AttributedStringBuffer asb,
+ Map[] returnTextAttributes) {
// 'requiredFeatures', 'requiredExtensions', 'systemLanguage' &
// 'display="none".
if ((!SVGUtilities.matchUserAgent(element, ctx.getUserAgent())) ||
@@ -893,8 +931,13 @@
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
+ if (returnTextAttributes != null)
+ returnTextAttributes[0] = map;
+ // batik bidi processing
Object o = map.get(TextAttribute.BIDI_EMBEDDING);
Integer subBidiLevel = bidiLevel;
if (o != null) {
@@ -933,7 +976,7 @@
textPath,
subBidiLevel,
initialAttributes,
- asb);
+ asb, null);
if (asb.count != before) {
initialAttributes = null;
}
@@ -950,7 +993,7 @@
newTextPath,
subBidiLevel,
initialAttributes,
- asb);
+ asb, null);
if (asb.count != before) {
initialAttributes = null;
}
@@ -997,7 +1040,7 @@
textPath,
subBidiLevel,
initialAttributes,
- asb);
+ asb, null);
if (asb.count != before) {
initialAttributes = null;
}
@@ -1532,6 +1575,11 @@
// holds hard ref to DOM.
result.put(GVT_FONT_FAMILIES, fontFamilyList);
+ // Line height
+ result.put(LINE_HEIGHT,
+ TextUtilities.convertLineHeight(element,
+ SVGCSSEngine.LINE_HEIGHT_INDEX, fontSize));
+
if (!ctx.isDynamic()) {
// Only leave this in the map for dynamic documents.
// Otherwise it will cause the whole DOM to stay when
@@ -1585,6 +1633,11 @@
result.put(PAINT_INFO, pi);
elemTPI.put(element, pi);
+ // Background outline
+ float[] backgroundOutline = TextUtilities.convertBackgroundOutline(element);
+ result.put(BACKGROUND_OUTLINE, backgroundOutline);
+
+ // Text path
if (textPath != null) {
result.put(TEXTPATH, textPath);
}
@@ -1885,7 +1938,9 @@
(sm.isNullCascaded(SVGCSSEngine.FILL_INDEX)) &&
(sm.isNullCascaded(SVGCSSEngine.STROKE_INDEX)) &&
(sm.isNullCascaded(SVGCSSEngine.STROKE_WIDTH_INDEX)) &&
- (sm.isNullCascaded(SVGCSSEngine.OPACITY_INDEX))) {
+ (sm.isNullCascaded(SVGCSSEngine.OPACITY_INDEX)) &&
+ (sm.isNullCascaded(SVGCSSEngine.BACKGROUND_COLOR_INDEX)) &&
+ (sm.isNullCascaded(SVGCSSEngine.BACKGROUND_MODE_INDEX))) {
// If not, keep the same decorations.
return pi;
}
@@ -1906,6 +1961,13 @@
pi.composite = AlphaComposite.SrcOver;
pi.visible = CSSUtilities.convertVisibility(element);
+ StyleMap sm = ((CSSStylableElement)element).getComputedStyleMap(null);
+ Paint backgroundPaint = PaintServer.convertBackgroundPaint(element, node, ctx);
+ if (!sm.isNullCascaded(SVGCSSEngine.BACKGROUND_COLOR_INDEX))
+ pi.backgroundPaint = backgroundPaint;
+ StringValue backgroundMode = TextUtilities.convertBackgroundMode(element);
+ if (!sm.isNullCascaded(SVGCSSEngine.BACKGROUND_MODE_INDEX))
+ pi.backgroundMode = backgroundMode.getStringValue();
pi.fillPaint = PaintServer.convertFillPaint (element, node, ctx);
pi.strokePaint = PaintServer.convertStrokePaint(element, node, ctx);
pi.strokeStroke = PaintServer.convertStroke (element);
diff --git a/batik-bridge/src/main/java/org/apache/batik/bridge/StrokingTextPainter.java b/batik-bridge/src/main/java/org/apache/batik/bridge/StrokingTextPainter.java
index 0979e8c..03224b7 100644
--- a/batik-bridge/src/main/java/org/apache/batik/bridge/StrokingTextPainter.java
+++ b/batik-bridge/src/main/java/org/apache/batik/bridge/StrokingTextPainter.java
@@ -16,9 +16,9 @@
limitations under the License.
*/
-
package org.apache.batik.bridge;
+import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.RenderingHints;
@@ -29,6 +29,7 @@
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;
@@ -36,11 +37,13 @@
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
+import java.util.Map;
import java.util.Set;
import org.apache.batik.gvt.font.GVTFont;
import org.apache.batik.gvt.font.GVTFontFamily;
import org.apache.batik.gvt.font.GVTGlyphMetrics;
+import org.apache.batik.gvt.font.GVTGlyphVector;
import org.apache.batik.gvt.font.GVTLineMetrics;
import org.apache.batik.gvt.text.AttributedCharacterSpanIterator;
import org.apache.batik.gvt.text.BidiAttributedCharacterIterator;
@@ -48,7 +51,6 @@
import org.apache.batik.gvt.text.TextPaintInfo;
import org.apache.batik.gvt.text.TextPath;
-
/**
* More sophisticated implementation of TextPainter which
* renders the attributed character iterator of a <code>TextNode</code>.
@@ -124,13 +126,20 @@
public static final GVTAttributedCharacterIterator.TextAttribute ALT_GLYPH_HANDLER =
GVTAttributedCharacterIterator.TextAttribute.ALT_GLYPH_HANDLER;
+ public static final
+ AttributedCharacterIterator.Attribute LINE_HEIGHT
+ = GVTAttributedCharacterIterator.TextAttribute.LINE_HEIGHT;
+
+ public static final
+ AttributedCharacterIterator.Attribute BACKGROUND_OUTLINE
+ = GVTAttributedCharacterIterator.TextAttribute.BACKGROUND_OUTLINE;
+
static Set extendedAtts = new HashSet();
static {
extendedAtts.add(FLOW_PARAGRAPH);
extendedAtts.add(TEXT_COMPOUND_ID);
extendedAtts.add(GVT_FONT);
- // extendedAtts.add(BIDI_LEVEL);
}
/**
@@ -159,13 +168,17 @@
List textRuns = getTextRuns(node, aci);
- // draw the underline and overline first, then the actual text
- // and finally the strikethrough
+ // 1. draw text node background
+ paintBackground(node, textRuns, g2d);
+ // 2. draw text run backgrounds
+ paintBackgrounds(node, textRuns, g2d);
+ // 3. draw text run underline and overline
paintDecorations(textRuns, g2d, TextSpanLayout.DECORATION_UNDERLINE);
paintDecorations(textRuns, g2d, TextSpanLayout.DECORATION_OVERLINE);
+ // 4. draw text run glyphs
paintTextRuns(textRuns, g2d);
- paintDecorations
- (textRuns, g2d, TextSpanLayout.DECORATION_STRIKETHROUGH);
+ // 5. draw text run strike through
+ paintDecorations(textRuns, g2d, TextSpanLayout.DECORATION_STRIKETHROUGH);
}
protected void printAttrs(AttributedCharacterIterator aci) {
@@ -851,6 +864,158 @@
}
/**
+ * Paint text node background.
+ */
+ protected void paintBackground(TextNode node, List textRuns, Graphics2D g2d) {
+ Map textAttributes = node.getTextAttributes();
+ if (textAttributes != null) {
+ TextPaintInfo tpi = (TextPaintInfo) textAttributes.get(PAINT_INFO);
+ if (tpi != null) {
+ if (tpi.visible) {
+ Paint paint = tpi.backgroundPaint;
+ String 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);
+ adjustForOutline(bounds, (float[]) textAttributes.get(BACKGROUND_OUTLINE));
+ g2d.fill(bounds);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private Rectangle2D computeBackgroundBounds(TextNode node, List textRuns, String mode) {
+ if (mode == TextPaintInfo.BBOX) {
+ return computeBBoxBounds(node.getPrimitiveBounds());
+ } else if (mode == TextPaintInfo.LINE_HEIGHT) {
+ TextRun run = (TextRun) textRuns.get(0);
+ TextSpanLayout layout = run.getLayout();
+ GVTLineMetrics lineMetrics = layout.getLineMetrics();
+ double ascent = lineMetrics.getAscent();
+ double descent = lineMetrics.getDescent();
+ double emHeight = ascent + descent;
+ GVTGlyphVector gv = layout.getGlyphVector();
+ Point2D firstPosition = gv.getGlyphPosition(0);
+ Map textAttributes = node.getTextAttributes();
+ double fontSize = (textAttributes != null) ? ((Float) textAttributes.get(TextAttribute.SIZE)).doubleValue() : 0d;
+ double lineHeight = (textAttributes != null) ? ((Float) textAttributes.get(LINE_HEIGHT)).doubleValue() : fontSize * 1.1f;
+ return computeLineHeightBounds(firstPosition, ascent, emHeight, lineHeight, node.getPrimitiveBounds().getWidth());
+ } else {
+ return new Rectangle2D.Double();
+ }
+ }
+
+ /**
+ * Paint text run backgrounds.
+ */
+ 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;
+ String 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 bounds = p.getBounds2D();
+ if (!bounds.isEmpty()) {
+ g2d.setPaint(paint);
+ adjustForOutline(bounds, (float[]) runaci.getAttribute(BACKGROUND_OUTLINE));
+ g2d.fill(bounds);
+ }
+ }
+ }
+ eDrawn.add(e);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private Rectangle2D computeBackgroundBounds(TextRun run, String mode) {
+ if (mode == TextPaintInfo.BBOX) {
+ return computeBBoxBounds(run.getLayout().getBounds2D());
+ } else if (mode == TextPaintInfo.LINE_HEIGHT) {
+ TextSpanLayout layout = run.getLayout();
+ GVTLineMetrics lineMetrics = layout.getLineMetrics();
+ double ascent = lineMetrics.getAscent();
+ double descent = lineMetrics.getDescent();
+ double emHeight = ascent + descent;
+ GVTGlyphVector gv = layout.getGlyphVector();
+ Rectangle2D bbox = layout.getBounds2D();
+ Point2D firstPosition = new Point2D.Double(bbox.getX(), gv.getGlyphPosition(0).getY());
+ AttributedCharacterIterator aci = run.getACI();
+ double fontSize = (aci != null) ? ((Float) aci.getAttribute(TextAttribute.SIZE)).doubleValue() : 0d;
+ double lineHeight = (aci != null) ? ((Float) aci.getAttribute(LINE_HEIGHT)).doubleValue() : fontSize * 1.1f;
+ return computeLineHeightBounds(firstPosition, ascent, emHeight, lineHeight, bbox.getWidth());
+ } else {
+ return new Rectangle2D.Double();
+ }
+ }
+
+ 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);
+ }
+
+ private void adjustForOutline(Rectangle2D b, float[] outline) {
+ if (outline != null) {
+ double x = b.getX();
+ double y = b.getY();
+ double w = b.getWidth();
+ double h = b.getHeight();
+ x -= outline[3];
+ y -= outline[0];
+ w += outline[1] + outline[3];
+ h += outline[0] + outline[2];
+ b.setFrame(x, y, w, h);
+ }
+ }
+
+ /**
* Paints decorations of the specified type.
*/
protected void paintDecorations(List textRuns,
diff --git a/batik-bridge/src/main/java/org/apache/batik/bridge/TextNode.java b/batik-bridge/src/main/java/org/apache/batik/bridge/TextNode.java
index d6938ca..0270319 100644
--- a/batik-bridge/src/main/java/org/apache/batik/bridge/TextNode.java
+++ b/batik-bridge/src/main/java/org/apache/batik/bridge/TextNode.java
@@ -27,6 +27,7 @@
import java.text.AttributedCharacterIterator;
import java.text.CharacterIterator;
import java.util.List;
+import java.util.Map;
import org.apache.batik.gvt.AbstractGraphicsNode;
import org.apache.batik.gvt.Selectable;
@@ -63,6 +64,11 @@
protected String text;
/**
+ * Attibutes that apply to text node as a whole (not to individual text runs).
+ */
+ protected Map textAttributes;
+
+ /**
* The begin mark.
*/
protected Mark beginMark = null;
@@ -165,6 +171,13 @@
}
/**
+ * Returns the top level text attributes of text node.
+ */
+ public Map getTextAttributes() {
+ return textAttributes;
+ }
+
+ /**
* Sets the location of this text node.
*
* @param newLocation the new location of this text node
@@ -193,19 +206,25 @@
fireGraphicsNodeChangeCompleted();
}
-
/**
* Sets the attributed character iterator of this text node.
*
* @param newAci the new attributed character iterator
+ * @param textAttributes top-level text node attributes map
*/
public void setAttributedCharacterIterator
(AttributedCharacterIterator newAci) {
+ this.setAttributedCharacterIterator(newAci, null);
+ }
+
+ public void setAttributedCharacterIterator
+ (AttributedCharacterIterator newAci, Map textAttributes) {
fireGraphicsNodeChangeStarted();
invalidateGeometryCache();
this.aci = newAci;
- text = null;
- textRuns = null;
+ this.text = null;
+ this.textAttributes = textAttributes;
+ this.textRuns = null;
fireGraphicsNodeChangeCompleted();
}
@@ -538,6 +557,11 @@
}
}
}
+
+ public enum BackgroundMode {
+ BBOX,
+ LINE_HEIGHT;
+ };
}
diff --git a/batik-bridge/src/main/java/org/apache/batik/bridge/TextUtilities.java b/batik-bridge/src/main/java/org/apache/batik/bridge/TextUtilities.java
index bb05ec3..952d374 100644
--- a/batik-bridge/src/main/java/org/apache/batik/bridge/TextUtilities.java
+++ b/batik-bridge/src/main/java/org/apache/batik/bridge/TextUtilities.java
@@ -22,13 +22,21 @@
import java.util.ArrayList;
import java.util.StringTokenizer;
+
+
import org.apache.batik.css.engine.SVGCSSEngine;
+import org.apache.batik.css.engine.value.ComputedValue;
import org.apache.batik.css.engine.value.Value;
+import org.apache.batik.css.engine.value.ValueConstants;
+import org.apache.batik.css.engine.value.svg12.LineHeightValue;
+import org.apache.batik.css.engine.value.svg12.SVG12ValueConstants;
import org.apache.batik.util.CSSConstants;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.css.CSSPrimitiveValue;
+import org.apache.batik.gvt.text.TextPaintInfo;
+import org.apache.batik.css.engine.value.StringValue;
/**
* A collection of utility method for text.
*
@@ -145,6 +153,30 @@
}
/**
+ * Converts the line-height CSS value to a float value.
+ * @param e the element
+ */
+ public static Float convertLineHeight(Element e, int lineHeightIndex, float fontSize) {
+ Value v = CSSUtilities.getComputedStyle(e, lineHeightIndex);
+ if ((v == ValueConstants.INHERIT_VALUE) ||
+ (v == SVG12ValueConstants.NORMAL_VALUE)) {
+ return fontSize*1.1f;
+ }
+ float lineHeight = fontSize;
+ if (v instanceof ComputedValue)
+ v = ((ComputedValue)v).getComputedValue();
+ if (v instanceof LineHeightValue) {
+ lineHeight = v.getFloatValue();
+ if (((LineHeightValue)v).getFontSizeRelative())
+ lineHeight *= fontSize;
+ } else if (v.getPrimitiveType() == CSSPrimitiveValue.CSS_IDENT) {
+ if (v.getStringValue().equals(CSS_NORMAL_VALUE))
+ lineHeight = fontSize * 1.1f;
+ }
+ return Float.valueOf(lineHeight);
+ }
+
+ /**
* Converts the font-style CSS value to a float value.
* @param e the element
*/
@@ -262,6 +294,43 @@
}
/**
+ * Converts the background-mode CSS value to a TextNode.BackgroundMode.
+ * @param e the element
+ */
+ public static StringValue convertBackgroundMode(Element e) {
+ Value v = CSSUtilities.getComputedStyle
+ (e, SVGCSSEngine.BACKGROUND_MODE_INDEX);
+ switch (v.getStringValue().charAt(0)) {
+ case 'b':
+ return new StringValue(CSSPrimitiveValue.CSS_IDENT,TextPaintInfo.BBOX);
+ case 'l':
+ default:
+ return new StringValue(CSSPrimitiveValue.CSS_IDENT,TextPaintInfo.LINE_HEIGHT);
+ }
+ }
+
+ /**
+ * Converts the background-outline CSS value to a floats[] instance.
+ * @param e the element
+ */
+ public static float[] convertBackgroundOutline(Element e) {
+ Value v;
+ v = CSSUtilities.getComputedStyle(e, SVGCSSEngine.BACKGROUND_OUTLINE_TOP_INDEX);
+ float top = v.getFloatValue();
+
+ v = CSSUtilities.getComputedStyle(e, SVGCSSEngine.BACKGROUND_OUTLINE_RIGHT_INDEX);
+ float right = v.getFloatValue();
+
+ v = CSSUtilities.getComputedStyle(e, SVGCSSEngine.BACKGROUND_OUTLINE_BOTTOM_INDEX);
+ float bottom = v.getFloatValue();
+
+ v = CSSUtilities.getComputedStyle(e, SVGCSSEngine.BACKGROUND_OUTLINE_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
diff --git a/batik-css/src/main/java/org/apache/batik/css/engine/SVG12CSSEngine.java b/batik-css/src/main/java/org/apache/batik/css/engine/SVG12CSSEngine.java
index cf9ad99..590061a 100644
--- a/batik-css/src/main/java/org/apache/batik/css/engine/SVG12CSSEngine.java
+++ b/batik-css/src/main/java/org/apache/batik/css/engine/SVG12CSSEngine.java
@@ -22,7 +22,6 @@
import org.apache.batik.css.engine.value.ValueManager;
import org.apache.batik.css.engine.value.svg.SVGColorManager;
import org.apache.batik.css.engine.value.svg.OpacityManager;
-import org.apache.batik.css.engine.value.svg12.LineHeightManager;
import org.apache.batik.css.engine.value.svg12.MarginLengthManager;
import org.apache.batik.css.engine.value.svg12.MarginShorthandManager;
import org.apache.batik.css.engine.value.svg12.TextAlignManager;
@@ -55,7 +54,6 @@
SVG_VALUE_MANAGERS,
SVG_SHORTHAND_MANAGERS,
ctx);
- lineHeightIndex = LINE_HEIGHT_INDEX;
}
/**
@@ -77,14 +75,12 @@
mergeArrays(SVG_VALUE_MANAGERS, vms),
mergeArrays(SVG_SHORTHAND_MANAGERS, sms),
ctx);
- lineHeightIndex = LINE_HEIGHT_INDEX;
}
/**
* The value managers for SVG.
*/
public static final ValueManager[] SVG_VALUE_MANAGERS = {
- new LineHeightManager (),
new MarginLengthManager(SVG12CSSConstants.CSS_INDENT_PROPERTY),
new MarginLengthManager(SVG12CSSConstants.CSS_MARGIN_BOTTOM_PROPERTY),
new MarginLengthManager(SVG12CSSConstants.CSS_MARGIN_LEFT_PROPERTY),
@@ -106,8 +102,7 @@
//
// The property indexes.
//
- public static final int LINE_HEIGHT_INDEX = SVGCSSEngine.FINAL_INDEX+1;
- public static final int INDENT_INDEX = LINE_HEIGHT_INDEX+1;
+ public static final int INDENT_INDEX = SVGCSSEngine.FINAL_INDEX+1;
public static final int MARGIN_BOTTOM_INDEX = INDENT_INDEX+1;
public static final int MARGIN_LEFT_INDEX = MARGIN_BOTTOM_INDEX+1;
public static final int MARGIN_RIGHT_INDEX = MARGIN_LEFT_INDEX+1;
diff --git a/batik-css/src/main/java/org/apache/batik/css/engine/SVGCSSEngine.java b/batik-css/src/main/java/org/apache/batik/css/engine/SVGCSSEngine.java
index 7ee8995..0e54353 100644
--- a/batik-css/src/main/java/org/apache/batik/css/engine/SVGCSSEngine.java
+++ b/batik-css/src/main/java/org/apache/batik/css/engine/SVGCSSEngine.java
@@ -21,6 +21,9 @@
import org.apache.batik.css.engine.value.ShorthandManager;
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.BackgroundOutlineShorthandManager;
+import org.apache.batik.css.engine.value.css2.BackgroundOutlineLengthManager;
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;
@@ -33,6 +36,7 @@
import org.apache.batik.css.engine.value.css2.FontStyleManager;
import org.apache.batik.css.engine.value.css2.FontVariantManager;
import org.apache.batik.css.engine.value.css2.FontWeightManager;
+import org.apache.batik.css.engine.value.css2.LineHeightManager;
import org.apache.batik.css.engine.value.css2.OverflowManager;
import org.apache.batik.css.engine.value.css2.SrcManager;
import org.apache.batik.css.engine.value.css2.TextDecorationManager;
@@ -109,8 +113,6 @@
true,
null,
ctx);
- // SVG defines line-height to be font-size.
- lineHeightIndex = fontSizeIndex;
}
/**
@@ -139,8 +141,6 @@
true,
null,
ctx);
- // SVG defines line-height to be font-size.
- lineHeightIndex = fontSizeIndex;
}
protected SVGCSSEngine(Document doc,
@@ -160,8 +160,6 @@
mergeArrays(SVG_VALUE_MANAGERS, vms),
mergeArrays(SVG_SHORTHAND_MANAGERS, sms),
pe, sns, sln, cns, cln, hints, hintsNS, ctx);
- // SVG defines line-height to be font-size.
- lineHeightIndex = fontSizeIndex;
}
@@ -193,6 +191,12 @@
*/
public static final ValueManager[] SVG_VALUE_MANAGERS = {
new AlignmentBaselineManager(),
+ new SVGColorManager(CSSConstants.CSS_BACKGROUND_COLOR_PROPERTY, ValueConstants.TRANSPARENT_VALUE),
+ new BackgroundModeManager(),
+ new BackgroundOutlineLengthManager(CSSConstants.CSS_BACKGROUND_OUTLINE_BOTTOM_PROPERTY),
+ new BackgroundOutlineLengthManager(CSSConstants.CSS_BACKGROUND_OUTLINE_LEFT_PROPERTY),
+ new BackgroundOutlineLengthManager(CSSConstants.CSS_BACKGROUND_OUTLINE_RIGHT_PROPERTY),
+ new BackgroundOutlineLengthManager(CSSConstants.CSS_BACKGROUND_OUTLINE_TOP_PROPERTY),
new BaselineShiftManager(),
new ClipManager(),
new ClipPathManager(),
@@ -233,6 +237,7 @@
new SpacingManager(CSSConstants.CSS_LETTER_SPACING_PROPERTY),
new SVGColorManager(CSSConstants.CSS_LIGHTING_COLOR_PROPERTY,
ValueConstants.WHITE_RGB_VALUE),
+ new LineHeightManager(),
new MarkerManager(CSSConstants.CSS_MARKER_END_PROPERTY),
new MarkerManager(CSSConstants.CSS_MARKER_MID_PROPERTY),
@@ -271,6 +276,7 @@
* The shorthand managers for SVG.
*/
public static final ShorthandManager[] SVG_SHORTHAND_MANAGERS = {
+ new BackgroundOutlineShorthandManager(),
new FontShorthandManager(),
new MarkerShorthandManager(),
};
@@ -279,8 +285,14 @@
// The property indexes.
//
public static final int ALIGNMENT_BASELINE_INDEX = 0;
+ public static final int BACKGROUND_COLOR_INDEX = ALIGNMENT_BASELINE_INDEX + 1;
+ public static final int BACKGROUND_MODE_INDEX = BACKGROUND_COLOR_INDEX + 1;
+ public static final int BACKGROUND_OUTLINE_BOTTOM_INDEX = BACKGROUND_MODE_INDEX + 1;
+ public static final int BACKGROUND_OUTLINE_LEFT_INDEX = BACKGROUND_OUTLINE_BOTTOM_INDEX + 1;
+ public static final int BACKGROUND_OUTLINE_RIGHT_INDEX = BACKGROUND_OUTLINE_LEFT_INDEX + 1;
+ public static final int BACKGROUND_OUTLINE_TOP_INDEX = BACKGROUND_OUTLINE_RIGHT_INDEX + 1;
public static final int BASELINE_SHIFT_INDEX =
- ALIGNMENT_BASELINE_INDEX + 1;
+ BACKGROUND_OUTLINE_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;
@@ -329,7 +341,8 @@
public static final int KERNING_INDEX = IMAGE_RENDERING_INDEX + 1;
public static final int LETTER_SPACING_INDEX = KERNING_INDEX + 1;
public static final int LIGHTING_COLOR_INDEX = LETTER_SPACING_INDEX + 1;
- public static final int MARKER_END_INDEX = LIGHTING_COLOR_INDEX + 1;
+ public static final int LINE_HEIGHT_INDEX = LIGHTING_COLOR_INDEX + 1;
+ public static final int MARKER_END_INDEX = LINE_HEIGHT_INDEX + 1;
public static final int MARKER_MID_INDEX = MARKER_END_INDEX + 1;
diff --git a/batik-css/src/main/java/org/apache/batik/css/engine/value/AbstractColorManager.java b/batik-css/src/main/java/org/apache/batik/css/engine/value/AbstractColorManager.java
index 488fd26..2cf3e82 100644
--- a/batik-css/src/main/java/org/apache/batik/css/engine/value/AbstractColorManager.java
+++ b/batik-css/src/main/java/org/apache/batik/css/engine/value/AbstractColorManager.java
@@ -68,6 +68,8 @@
ValueConstants.SILVER_VALUE);
values.put(CSSConstants.CSS_TEAL_VALUE,
ValueConstants.TEAL_VALUE);
+ values.put(CSSConstants.CSS_TRANSPARENT_VALUE,
+ ValueConstants.TRANSPARENT_VALUE);
values.put(CSSConstants.CSS_WHITE_VALUE,
ValueConstants.WHITE_VALUE);
values.put(CSSConstants.CSS_YELLOW_VALUE,
@@ -166,6 +168,8 @@
ValueConstants.BLUE_RGB_VALUE);
computedValues.put(CSSConstants.CSS_TEAL_VALUE,
ValueConstants.TEAL_RGB_VALUE);
+ computedValues.put(CSSConstants.CSS_TRANSPARENT_VALUE,
+ ValueConstants.TRANSPARENT_RGB_VALUE);
computedValues.put(CSSConstants.CSS_AQUA_VALUE,
ValueConstants.AQUA_RGB_VALUE);
}
diff --git a/batik-css/src/main/java/org/apache/batik/css/engine/value/AbstractValue.java b/batik-css/src/main/java/org/apache/batik/css/engine/value/AbstractValue.java
index 2829747..488bdfa 100644
--- a/batik-css/src/main/java/org/apache/batik/css/engine/value/AbstractValue.java
+++ b/batik-css/src/main/java/org/apache/batik/css/engine/value/AbstractValue.java
@@ -79,6 +79,13 @@
}
/**
+ * Implements {@link Value#getAlpha()}.
+ */
+ public Value getAlpha() throws DOMException {
+ throw createDOMException();
+ }
+
+ /**
* Implements {@link Value#getLength()}.
*/
public int getLength() throws DOMException {
diff --git a/batik-css/src/main/java/org/apache/batik/css/engine/value/ComputedValue.java b/batik-css/src/main/java/org/apache/batik/css/engine/value/ComputedValue.java
index fc9b300..d0b5578 100644
--- a/batik-css/src/main/java/org/apache/batik/css/engine/value/ComputedValue.java
+++ b/batik-css/src/main/java/org/apache/batik/css/engine/value/ComputedValue.java
@@ -124,6 +124,13 @@
}
/**
+ * Implements {@link Value#getGreen()}.
+ */
+ public Value getAlpha() throws DOMException {
+ return computedValue.getAlpha();
+ }
+
+ /**
* Implements {@link Value#getLength()}.
*/
public int getLength() throws DOMException {
diff --git a/batik-css/src/main/java/org/apache/batik/css/engine/value/RGBAColorValue.java b/batik-css/src/main/java/org/apache/batik/css/engine/value/RGBAColorValue.java
new file mode 100644
index 0000000..d93a73a
--- /dev/null
+++ b/batik-css/src/main/java/org/apache/batik/css/engine/value/RGBAColorValue.java
@@ -0,0 +1,61 @@
+/*
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+package org.apache.batik.css.engine.value;
+
+import org.w3c.dom.DOMException;
+
+/**
+ * This class represents RGBA colors.
+ *
+ * @author <a href="mailto:gadams@apache.org">Glenn Adams</a>
+ * @version $Id$
+ */
+public class RGBAColorValue extends RGBColorValue {
+
+ /**
+ * The alpha component.
+ */
+ protected Value alpha;
+
+ /**
+ * Creates a new RGBAColorValue.
+ */
+ public RGBAColorValue(Value r, Value g, Value b, Value a) {
+ super(r, g, b);
+ alpha = a;
+ }
+
+ /**
+ * A string representation of the current value.
+ */
+ public String getCssText() {
+ return "rgba(" +
+ red.getCssText() + ", " +
+ green.getCssText() + ", " +
+ blue.getCssText() + ", " +
+ alpha.getCssText() + ')';
+ }
+
+ /**
+ * Implements {@link Value#getAlpha()}.
+ */
+ public Value getAlpha() throws DOMException {
+ return alpha;
+ }
+}
diff --git a/batik-css/src/main/java/org/apache/batik/css/engine/value/Value.java b/batik-css/src/main/java/org/apache/batik/css/engine/value/Value.java
index 114f94f..fed7f54 100644
--- a/batik-css/src/main/java/org/apache/batik/css/engine/value/Value.java
+++ b/batik-css/src/main/java/org/apache/batik/css/engine/value/Value.java
@@ -84,6 +84,14 @@
Value getBlue() throws DOMException;
/**
+ * The alpha value of the RGBA color.
+ * @exception DOMException
+ * INVALID_ACCESS_ERR: Raised if the value doesn't contain a RGB
+ * color value.
+ */
+ Value getAlpha() throws DOMException;
+
+ /**
* The number of <code>CSSValues</code> in the list. The range of valid
* values of the indices is <code>0</code> to <code>length-1</code>
* inclusive.
diff --git a/batik-css/src/main/java/org/apache/batik/css/engine/value/ValueConstants.java b/batik-css/src/main/java/org/apache/batik/css/engine/value/ValueConstants.java
index aeaeb1d..cdc75fa 100644
--- a/batik-css/src/main/java/org/apache/batik/css/engine/value/ValueConstants.java
+++ b/batik-css/src/main/java/org/apache/batik/css/engine/value/ValueConstants.java
@@ -772,6 +772,13 @@
CSSConstants.CSS_TEAL_VALUE);
/**
+ * The 'transparent' color name.
+ */
+ Value TRANSPARENT_VALUE =
+ new StringValue(CSSPrimitiveValue.CSS_IDENT,
+ CSSConstants.CSS_TRANSPARENT_VALUE);
+
+ /**
* The 'white' color name.
*/
Value WHITE_VALUE =
@@ -1073,6 +1080,12 @@
new RGBColorValue(NUMBER_0, NUMBER_128, NUMBER_128);
/**
+ * The 'transparent' RGB color.
+ */
+ Value TRANSPARENT_RGB_VALUE =
+ new RGBAColorValue(NUMBER_0, NUMBER_0, NUMBER_0, NUMBER_0);
+
+ /**
* The 'aqua' RGB color.
*/
Value AQUA_RGB_VALUE =
diff --git a/batik-css/src/main/java/org/apache/batik/css/engine/value/css2/BackgroundModeManager.java b/batik-css/src/main/java/org/apache/batik/css/engine/value/css2/BackgroundModeManager.java
new file mode 100644
index 0000000..c95c500
--- /dev/null
+++ b/batik-css/src/main/java/org/apache/batik/css/engine/value/css2/BackgroundModeManager.java
@@ -0,0 +1,97 @@
+/*
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+package org.apache.batik.css.engine.value.css2;
+
+import org.apache.batik.css.engine.value.IdentifierManager;
+import org.apache.batik.css.engine.value.StringMap;
+import org.apache.batik.css.engine.value.Value;
+import org.apache.batik.css.engine.value.ValueManager;
+import org.apache.batik.css.engine.value.svg.SVGValueConstants;
+import org.apache.batik.util.CSSConstants;
+import org.apache.batik.util.SVGTypes;
+
+/**
+ * This class provides a manager for the 'background-mode' property values.
+ *
+ * @author <a href="mailto:gadams@apache.org">Glenn Adams</a>
+ * @version $Id$
+ */
+public class BackgroundModeManager extends IdentifierManager {
+
+ /**
+ * The identifier values.
+ */
+ protected static final StringMap values = new StringMap();
+ static {
+ values.put(CSSConstants.CSS_BBOX_VALUE, SVGValueConstants.BBOX_VALUE);
+ values.put(CSSConstants.CSS_LINE_HEIGHT_VALUE, SVGValueConstants.LINE_HEIGHT_VALUE);
+ }
+
+ /**
+ * Implements {@link
+ * org.apache.batik.css.engine.value.ValueManager#isInheritedProperty()}.
+ */
+ public boolean isInheritedProperty() {
+ return true;
+ }
+
+ /**
+ * Implements {@link ValueManager#isAnimatableProperty()}.
+ */
+ public boolean isAnimatableProperty() {
+ return false;
+ }
+
+ /**
+ * Implements {@link ValueManager#isAdditiveProperty()}.
+ */
+ public boolean isAdditiveProperty() {
+ return false;
+ }
+
+ /**
+ * Implements {@link ValueManager#getPropertyType()}.
+ */
+ public int getPropertyType() {
+ return SVGTypes.TYPE_IDENT;
+ }
+
+ /**
+ * Implements {@link
+ * org.apache.batik.css.engine.value.ValueManager#getPropertyName()}.
+ */
+ public String getPropertyName() {
+ return CSSConstants.CSS_BACKGROUND_MODE_PROPERTY;
+ }
+
+ /**
+ * Implements {@link
+ * org.apache.batik.css.engine.value.ValueManager#getDefaultValue()}.
+ */
+ public Value getDefaultValue() {
+ return SVGValueConstants.LINE_HEIGHT_VALUE;
+ }
+
+ /**
+ * Implements {@link IdentifierManager#getIdentifiers()}.
+ */
+ public StringMap getIdentifiers() {
+ return values;
+ }
+}
diff --git a/batik-css/src/main/java/org/apache/batik/css/engine/value/css2/BackgroundOutlineLengthManager.java b/batik-css/src/main/java/org/apache/batik/css/engine/value/css2/BackgroundOutlineLengthManager.java
new file mode 100644
index 0000000..e450b3b
--- /dev/null
+++ b/batik-css/src/main/java/org/apache/batik/css/engine/value/css2/BackgroundOutlineLengthManager.java
@@ -0,0 +1,107 @@
+/*
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+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.util.SVGTypes;
+
+import org.w3c.css.sac.LexicalUnit;
+import org.w3c.dom.DOMException;
+
+/**
+ * This class provides a factory for the 'background-outline-*' properties values.
+ *
+ * @author <a href="mailto:gadams@apache.org">Glenn Adams</a>
+ * @version $Id$
+ */
+public class BackgroundOutlineLengthManager extends LengthManager {
+
+ protected String prop;
+
+ public BackgroundOutlineLengthManager(String prop) {
+ this.prop = prop;
+ }
+
+ /**
+ * Implements {@link ValueManager#isInheritedProperty()}.
+ */
+ public boolean isInheritedProperty() {
+ return false;
+ }
+
+ /**
+ * Implements {@link ValueManager#isAnimatableProperty()}.
+ */
+ public boolean isAnimatableProperty() {
+ return true;
+ }
+
+ /**
+ * Implements {@link ValueManager#isAdditiveProperty()}.
+ */
+ public boolean isAdditiveProperty() {
+ return true;
+ }
+
+ /**
+ * Implements {@link ValueManager#getPropertyType()}.
+ */
+ public int getPropertyType() {
+ return SVGTypes.TYPE_LENGTH_OR_INHERIT;
+ }
+
+ /**
+ * Implements {@link ValueManager#getPropertyName()}.
+ */
+ public String getPropertyName() {
+ return prop;
+ }
+
+ /**
+ * Implements {@link ValueManager#getDefaultValue()}.
+ */
+ public Value getDefaultValue() {
+ return ValueConstants.NUMBER_0;
+ }
+
+ /**
+ * Implements {@link ValueManager#createValue(LexicalUnit,CSSEngine)}.
+ */
+ public Value createValue(LexicalUnit lu, CSSEngine engine)
+ throws DOMException {
+ if (lu.getLexicalUnitType() == LexicalUnit.SAC_INHERIT) {
+ return ValueConstants.INHERIT_VALUE;
+ }
+ return super.createValue(lu, engine);
+ }
+
+
+ /**
+ * Indicates the orientation of the property associated with
+ * this manager.
+ */
+ protected int getOrientation() {
+ // background outlines are always wrt to block width, event for top/bottom.
+ return HORIZONTAL_ORIENTATION;
+ }
+}
diff --git a/batik-css/src/main/java/org/apache/batik/css/engine/value/css2/BackgroundOutlineShorthandManager.java b/batik-css/src/main/java/org/apache/batik/css/engine/value/css2/BackgroundOutlineShorthandManager.java
new file mode 100644
index 0000000..35c07b4
--- /dev/null
+++ b/batik-css/src/main/java/org/apache/batik/css/engine/value/css2/BackgroundOutlineShorthandManager.java
@@ -0,0 +1,95 @@
+/*
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+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.CSSConstants;
+import org.w3c.css.sac.LexicalUnit;
+import org.w3c.dom.DOMException;
+
+/**
+ * This class represents an object which provide support for the
+ * 'background-outline' shorthand property.
+ *
+ * @author <a href="mailto:gadams@apache.org">Glenn Adams</a>
+ * @version $Id$
+ */
+public class BackgroundOutlineShorthandManager
+ extends AbstractValueFactory
+ implements ShorthandManager {
+
+ public BackgroundOutlineShorthandManager() { }
+
+ /**
+ * Implements {@link ValueManager#getPropertyName()}.
+ */
+ public String getPropertyName() {
+ return CSSConstants.CSS_BACKGROUND_OUTLINE_PROPERTY;
+ }
+
+ /**
+ * Implements {@link ShorthandManager#isAnimatableProperty()}.
+ */
+ public boolean isAnimatableProperty() {
+ return true;
+ }
+
+ /**
+ * Implements {@link ShorthandManager#isAdditiveProperty()}.
+ */
+ public boolean isAdditiveProperty() {
+ return false;
+ }
+
+ /**
+ * Implements {@link ShorthandManager#setValues(CSSEngine,ShorthandManager.PropertyHandler,LexicalUnit,boolean)}.
+ */
+ public void setValues(CSSEngine eng,
+ ShorthandManager.PropertyHandler ph,
+ LexicalUnit lu,
+ boolean imp)
+ throws DOMException {
+ if (lu.getLexicalUnitType() == LexicalUnit.SAC_INHERIT)
+ return;
+
+ LexicalUnit []lus = new LexicalUnit[4];
+ int cnt=0;
+ while (lu != null) {
+ if (cnt == 4)
+ throw createInvalidLexicalUnitDOMException
+ (lu.getLexicalUnitType());
+ lus[cnt++] = lu;
+ lu = lu.getNextLexicalUnit();
+ }
+ switch (cnt) {
+ case 1: lus[3] = lus[2] = lus[1] = lus[0]; break;
+ case 2: lus[2] = lus[0]; lus[3] = lus[1]; break;
+ case 3: lus[3] = lus[1]; break;
+ default:
+ }
+
+ ph.property(CSSConstants.CSS_BACKGROUND_OUTLINE_TOP_PROPERTY, lus[0], imp);
+ ph.property(CSSConstants.CSS_BACKGROUND_OUTLINE_RIGHT_PROPERTY, lus[1], imp);
+ ph.property(CSSConstants.CSS_BACKGROUND_OUTLINE_BOTTOM_PROPERTY, lus[2], imp);
+ ph.property(CSSConstants.CSS_BACKGROUND_OUTLINE_LEFT_PROPERTY, lus[3], imp);
+ }
+}
diff --git a/batik-css/src/main/java/org/apache/batik/css/engine/value/svg12/LineHeightManager.java b/batik-css/src/main/java/org/apache/batik/css/engine/value/css2/LineHeightManager.java
similarity index 91%
rename from batik-css/src/main/java/org/apache/batik/css/engine/value/svg12/LineHeightManager.java
rename to batik-css/src/main/java/org/apache/batik/css/engine/value/css2/LineHeightManager.java
index 60e8b49..e767977 100644
--- a/batik-css/src/main/java/org/apache/batik/css/engine/value/svg12/LineHeightManager.java
+++ b/batik-css/src/main/java/org/apache/batik/css/engine/value/css2/LineHeightManager.java
@@ -16,8 +16,7 @@
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.CSSStylableElement;
@@ -25,8 +24,9 @@
import org.apache.batik.css.engine.value.LengthManager;
import org.apache.batik.css.engine.value.FloatValue;
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.util.SVG12CSSConstants;
+import org.apache.batik.util.CSSConstants;
import org.apache.batik.util.SVGTypes;
import org.w3c.css.sac.LexicalUnit;
@@ -76,14 +76,14 @@
* Implements {@link ValueManager#getPropertyName()}.
*/
public String getPropertyName() {
- return SVG12CSSConstants.CSS_LINE_HEIGHT_PROPERTY;
+ return CSSConstants.CSS_LINE_HEIGHT_PROPERTY;
}
/**
* Implements {@link ValueManager#getDefaultValue()}.
*/
public Value getDefaultValue() {
- return SVG12ValueConstants.NORMAL_VALUE;
+ return ValueConstants.NORMAL_VALUE;
}
/**
@@ -94,11 +94,11 @@
switch (lu.getLexicalUnitType()) {
case LexicalUnit.SAC_INHERIT:
- return SVG12ValueConstants.INHERIT_VALUE;
+ return ValueConstants.INHERIT_VALUE;
case LexicalUnit.SAC_IDENT: {
String s = lu.getStringValue().toLowerCase();
- if (SVG12CSSConstants.CSS_NORMAL_VALUE.equals(s))
- return SVG12ValueConstants.NORMAL_VALUE;
+ if (CSSConstants.CSS_NORMAL_VALUE.equals(s))
+ return ValueConstants.NORMAL_VALUE;
throw createInvalidIdentifierDOMException(lu.getStringValue());
}
default:
diff --git a/batik-css/src/main/java/org/apache/batik/css/engine/value/css2/LineHeightValue.java b/batik-css/src/main/java/org/apache/batik/css/engine/value/css2/LineHeightValue.java
new file mode 100644
index 0000000..3ec1379
--- /dev/null
+++ b/batik-css/src/main/java/org/apache/batik/css/engine/value/css2/LineHeightValue.java
@@ -0,0 +1,52 @@
+/*
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+ */
+package org.apache.batik.css.engine.value.css2;
+
+import org.apache.batik.css.engine.value.FloatValue;
+
+/**
+ * This class represents line-height values. These are basically
+ * FloatValues except that it may be 'font-size' relative.
+ *
+ * @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
+ * @version $Id$
+ */
+public class LineHeightValue extends FloatValue {
+
+ /**
+ * True if the line-height is relative to the font-size
+ */
+ protected boolean fontSizeRelative;
+
+ /**
+ * Creates a new value.
+ */
+ public LineHeightValue(short unitType, float floatValue,
+ boolean fontSizeRelative) {
+ super(unitType, floatValue);
+ this.fontSizeRelative = fontSizeRelative;
+ }
+
+ /**
+ * The type of the value.
+ */
+ public boolean getFontSizeRelative() {
+ return fontSizeRelative;
+ }
+}
diff --git a/batik-css/src/main/java/org/apache/batik/css/engine/value/svg/ColorManager.java b/batik-css/src/main/java/org/apache/batik/css/engine/value/svg/ColorManager.java
index f02dbd1..f89c2f9 100644
--- a/batik-css/src/main/java/org/apache/batik/css/engine/value/svg/ColorManager.java
+++ b/batik-css/src/main/java/org/apache/batik/css/engine/value/svg/ColorManager.java
@@ -342,6 +342,8 @@
SVGValueConstants.BLUE_RGB_VALUE);
computedValues.put(CSSConstants.CSS_TEAL_VALUE,
SVGValueConstants.TEAL_RGB_VALUE);
+ computedValues.put(CSSConstants.CSS_TRANSPARENT_VALUE,
+ SVGValueConstants.TRANSPARENT_RGB_VALUE);
computedValues.put(CSSConstants.CSS_AQUA_VALUE,
SVGValueConstants.AQUA_RGB_VALUE);
diff --git a/batik-css/src/main/java/org/apache/batik/css/engine/value/svg/SVGValueConstants.java b/batik-css/src/main/java/org/apache/batik/css/engine/value/svg/SVGValueConstants.java
index 89ed791..57e3f55 100644
--- a/batik-css/src/main/java/org/apache/batik/css/engine/value/svg/SVGValueConstants.java
+++ b/batik-css/src/main/java/org/apache/batik/css/engine/value/svg/SVGValueConstants.java
@@ -719,6 +719,13 @@
CSSConstants.CSS_BASELINE_VALUE);
/**
+ * The 'bbox' keyword.
+ */
+ Value BBOX_VALUE =
+ new StringValue(CSSPrimitiveValue.CSS_IDENT,
+ CSSConstants.CSS_BBOX_VALUE);
+
+ /**
* The 'before-edge' keyword.
*/
Value BEFORE_EDGE_VALUE =
@@ -810,6 +817,13 @@
CSSConstants.CSS_LINEARRGB_VALUE);
/**
+ * The 'line-height' keyword (used with background-mode property).
+ */
+ Value LINE_HEIGHT_VALUE =
+ new StringValue(CSSPrimitiveValue.CSS_IDENT,
+ CSSConstants.CSS_LINE_HEIGHT_VALUE);
+
+ /**
* The 'lr' keyword.
*/
Value LR_VALUE =
diff --git a/batik-css/src/main/java/org/apache/batik/css/engine/value/svg12/LineHeightValue.java b/batik-css/src/main/java/org/apache/batik/css/engine/value/svg12/LineHeightValue.java
index 80a4493..c20bebf 100644
--- a/batik-css/src/main/java/org/apache/batik/css/engine/value/svg12/LineHeightValue.java
+++ b/batik-css/src/main/java/org/apache/batik/css/engine/value/svg12/LineHeightValue.java
@@ -18,8 +18,6 @@
*/
package org.apache.batik.css.engine.value.svg12;
-import org.apache.batik.css.engine.value.FloatValue;
-
/**
* This class represents line-height values. These are basically
* FloatValues except that it may be 'font-size' relative.
@@ -27,26 +25,8 @@
* @author <a href="mailto:stephane@hillion.org">Stephane Hillion</a>
* @version $Id$
*/
-public class LineHeightValue extends FloatValue {
-
- /**
- * True if the line-height is relative to the font-size
- */
- protected boolean fontSizeRelative;
-
- /**
- * Creates a new value.
- */
- public LineHeightValue(short unitType, float floatValue,
- boolean fontSizeRelative) {
- super(unitType, floatValue);
- this.fontSizeRelative = fontSizeRelative;
- }
-
- /**
- * The type of the value.
- */
- public boolean getFontSizeRelative() {
- return fontSizeRelative;
+public class LineHeightValue extends org.apache.batik.css.engine.value.css2.LineHeightValue {
+ public LineHeightValue(short unitType, float floatValue, boolean fontSizeRelative) {
+ super(unitType, floatValue, fontSizeRelative);
}
}
diff --git a/batik-gvt/src/main/java/org/apache/batik/gvt/text/GVTAttributedCharacterIterator.java b/batik-gvt/src/main/java/org/apache/batik/gvt/text/GVTAttributedCharacterIterator.java
index d6792c6..adc1c6e 100644
--- a/batik-gvt/src/main/java/org/apache/batik/gvt/text/GVTAttributedCharacterIterator.java
+++ b/batik-gvt/src/main/java/org/apache/batik/gvt/text/GVTAttributedCharacterIterator.java
@@ -351,6 +351,9 @@
public static final TextAttribute LANGUAGE =
new TextAttribute("LANGUAGE");
+ public static final TextAttribute BACKGROUND_OUTLINE =
+ new TextAttribute("BACKGROUND_OUTLINE");
+
// VALUES
/** Value for WRITING_MODE indicating left-to-right */
diff --git a/batik-gvt/src/main/java/org/apache/batik/gvt/text/TextPaintInfo.java b/batik-gvt/src/main/java/org/apache/batik/gvt/text/TextPaintInfo.java
index 54ab170..555bc56 100644
--- a/batik-gvt/src/main/java/org/apache/batik/gvt/text/TextPaintInfo.java
+++ b/batik-gvt/src/main/java/org/apache/batik/gvt/text/TextPaintInfo.java
@@ -22,6 +22,8 @@
import java.awt.Paint;
import java.awt.Stroke;
+import org.apache.batik.util.CSSConstants;
+
/**
* One line Class Desc
*
@@ -32,6 +34,8 @@
*/
public class TextPaintInfo {
public boolean visible;
+ public Paint backgroundPaint;
+ public String backgroundMode;
public Paint fillPaint;
public Paint strokePaint;
public Stroke strokeStroke;
@@ -51,6 +55,9 @@
public int startChar, endChar;
+ public static final String BBOX = CSSConstants.CSS_BBOX_VALUE;
+ public static final String LINE_HEIGHT = CSSConstants.CSS_LINE_HEIGHT_VALUE;
+
public TextPaintInfo() { }
public TextPaintInfo(TextPaintInfo pi) {
@@ -59,6 +66,8 @@
public void set(TextPaintInfo pi) {
if (pi == null) {
+ this.backgroundPaint = null;
+ this.backgroundMode = null;
this.fillPaint = null;
this.strokePaint = null;
this.strokeStroke = null;
@@ -78,6 +87,8 @@
this.visible = false;
} else {
+ this.backgroundPaint = pi.backgroundPaint;
+ this.backgroundMode = pi.backgroundMode;
this.fillPaint = pi.fillPaint;
this.strokePaint = pi.strokePaint;
this.strokeStroke = pi.strokeStroke;
@@ -105,6 +116,12 @@
return false;
} else if (tpi2 == null) return false;
+ if ((tpi1.backgroundPaint == null) != (tpi2.backgroundPaint == null))
+ return false;
+
+ if ((tpi1.backgroundMode == null) != (tpi2.backgroundMode == null))
+ return false;
+
if ((tpi1.fillPaint == null) != (tpi2.fillPaint == null))
return false;
diff --git a/batik-svggen/src/main/java/org/apache/batik/svggen/SVGStylingAttributes.java b/batik-svggen/src/main/java/org/apache/batik/svggen/SVGStylingAttributes.java
index 4ec1e06..a8fc078 100644
--- a/batik-svggen/src/main/java/org/apache/batik/svggen/SVGStylingAttributes.java
+++ b/batik-svggen/src/main/java/org/apache/batik/svggen/SVGStylingAttributes.java
@@ -32,6 +32,12 @@
static Set attrSet = new HashSet();
static {
+ attrSet.add(SVG_BACKGROUND_COLOR_ATTRIBUTE);
+ attrSet.add(SVG_BACKGROUND_MODE_ATTRIBUTE);
+ attrSet.add(SVG_BACKGROUND_OUTLINE_BOTTOM_ATTRIBUTE);
+ attrSet.add(SVG_BACKGROUND_OUTLINE_LEFT_ATTRIBUTE);
+ attrSet.add(SVG_BACKGROUND_OUTLINE_RIGHT_ATTRIBUTE);
+ attrSet.add(SVG_BACKGROUND_OUTLINE_TOP_ATTRIBUTE);
attrSet.add(SVG_CLIP_PATH_ATTRIBUTE);
attrSet.add(SVG_COLOR_INTERPOLATION_ATTRIBUTE);
attrSet.add(SVG_COLOR_RENDERING_ATTRIBUTE);
diff --git a/batik-util/src/main/java/org/apache/batik/util/CSSConstants.java b/batik-util/src/main/java/org/apache/batik/util/CSSConstants.java
index f66e693..df2c933 100644
--- a/batik-util/src/main/java/org/apache/batik/util/CSSConstants.java
+++ b/batik-util/src/main/java/org/apache/batik/util/CSSConstants.java
@@ -36,6 +36,13 @@
// The CSS property names.
//
String CSS_ALIGNMENT_BASELINE_PROPERTY = "alignment-baseline";
+ String CSS_BACKGROUND_COLOR_PROPERTY = "background-color";
+ String CSS_BACKGROUND_MODE_PROPERTY = "background-mode";
+ String CSS_BACKGROUND_OUTLINE_PROPERTY = "background-outline";
+ String CSS_BACKGROUND_OUTLINE_BOTTOM_PROPERTY = "background-outline-bottom";
+ String CSS_BACKGROUND_OUTLINE_LEFT_PROPERTY = "background-outline-left";
+ String CSS_BACKGROUND_OUTLINE_RIGHT_PROPERTY = "background-outline-right";
+ String CSS_BACKGROUND_OUTLINE_TOP_PROPERTY = "background-outline-top";
String CSS_BASELINE_SHIFT_PROPERTY = "baseline-shift";
String CSS_CLIP_PROPERTY = "clip";
String CSS_CLIP_PATH_PROPERTY = "clip-path";
@@ -118,6 +125,7 @@
String CSS_AZURE_VALUE = "azure";
String CSS_BACKGROUND_VALUE = "background";
String CSS_BASELINE_VALUE = "baseline";
+ String CSS_BBOX_VALUE = "bbox";
String CSS_BEFORE_EDGE_VALUE = "before-edge";
String CSS_BEIGE_VALUE = "beige";
String CSS_BEVEL_VALUE = "bevel";
@@ -252,6 +260,7 @@
String CSS_LIGHTYELLOW_VALUE = "lightyellow";
String CSS_LIMEGREEN_VALUE = "limegreen";
String CSS_LIME_VALUE = "lime";
+ String CSS_LINE_HEIGHT_VALUE = "line-height";
String CSS_LINEARRGB_VALUE = "linearrgb";
String CSS_LINEN_VALUE = "linen";
String CSS_LINE_THROUGH_VALUE = "line-through";
@@ -377,6 +386,7 @@
String CSS_TB_RL_VALUE = "tb-rl";
String CSS_TB_VALUE = "tb";
String CSS_TEAL_VALUE = "teal";
+ String CSS_TRANSPARENT_VALUE = "transparent";
String CSS_TEXT_AFTER_EDGE_VALUE = "text-after-edge";
String CSS_TEXT_BEFORE_EDGE_VALUE = "text-before-edge";
String CSS_TEXT_BOTTOM_VALUE = "text-bottom";
diff --git a/batik-util/src/main/java/org/apache/batik/util/SVG12CSSConstants.java b/batik-util/src/main/java/org/apache/batik/util/SVG12CSSConstants.java
index 19b57d4..6331d8d 100644
--- a/batik-util/src/main/java/org/apache/batik/util/SVG12CSSConstants.java
+++ b/batik-util/src/main/java/org/apache/batik/util/SVG12CSSConstants.java
@@ -56,7 +56,5 @@
String CSS_END_VALUE = "end";
/** Value for text-align to both edges of region */
String CSS_FULL_VALUE = "full";
- /** Value for line-height for 'normal' line height */
- String CSS_NORMAL_VALUE = "normal";
}
diff --git a/batik-util/src/main/java/org/apache/batik/util/SVGConstants.java b/batik-util/src/main/java/org/apache/batik/util/SVGConstants.java
index d28c9df..823aa16 100644
--- a/batik-util/src/main/java/org/apache/batik/util/SVGConstants.java
+++ b/batik-util/src/main/java/org/apache/batik/util/SVGConstants.java
@@ -440,6 +440,13 @@
String SVG_ALPHABETIC_ATTRIBUTE = "alphabetic";
String SVG_ATTRIBUTE_NAME_ATTRIBUTE = "attributeName";
String SVG_ATTRIBUTE_TYPE_ATTRIBUTE = "attributeType";
+ String SVG_BACKGROUND_COLOR_ATTRIBUTE = CSS_BACKGROUND_COLOR_PROPERTY;
+ String SVG_BACKGROUND_MODE_ATTRIBUTE = CSS_BACKGROUND_MODE_PROPERTY;
+ String SVG_BACKGROUND_OUTLINE_ATTRIBUTE = CSS_BACKGROUND_OUTLINE_PROPERTY;
+ String SVG_BACKGROUND_OUTLINE_BOTTOM_ATTRIBUTE = CSS_BACKGROUND_OUTLINE_BOTTOM_PROPERTY;
+ String SVG_BACKGROUND_OUTLINE_LEFT_ATTRIBUTE = CSS_BACKGROUND_OUTLINE_LEFT_PROPERTY;
+ String SVG_BACKGROUND_OUTLINE_RIGHT_ATTRIBUTE = CSS_BACKGROUND_OUTLINE_RIGHT_PROPERTY;
+ String SVG_BACKGROUND_OUTLINE_TOP_ATTRIBUTE = CSS_BACKGROUND_OUTLINE_TOP_PROPERTY;
String SVG_BASE_FREQUENCY_ATTRIBUTE = "baseFrequency";
String SVG_BASE_PROFILE_ATTRIBUTE = "baseProfile";
String SVG_BEGIN_ATTRIBUTE = "begin";