bella 01/07/30 23:20:10
Modified: sources/org/apache/batik/bridge SVGTextElementBridge.java
TextUtilities.java
Log:
text rotate attribute now handled properly
Revision Changes Path
1.29 +111 -72
xml-batik/sources/org/apache/batik/bridge/SVGTextElementBridge.java
Index: SVGTextElementBridge.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/bridge/SVGTextElementBridge.java,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -r1.28 -r1.29
--- SVGTextElementBridge.java 2001/07/05 06:56:09 1.28
+++ SVGTextElementBridge.java 2001/07/31 06:20:10 1.29
@@ -47,6 +47,7 @@
import org.w3c.dom.Element;
import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
import org.w3c.dom.css.CSSPrimitiveValue;
import org.w3c.dom.css.CSSStyleDeclaration;
import org.w3c.dom.css.CSSValue;
@@ -56,7 +57,7 @@
* Bridge class for the <text> element.
*
* @author <a href="[EMAIL PROTECTED]>Bill Haneman</a>
- * @version $Id: SVGTextElementBridge.java,v 1.28 2001/07/05 06:56:09 bella Exp $
+ * @version $Id: SVGTextElementBridge.java,v 1.29 2001/07/31 06:20:10 bella Exp $
*/
public class SVGTextElementBridge extends AbstractSVGBridge
implements GraphicsNodeBridge, ErrorConstants {
@@ -150,6 +151,8 @@
GraphicsNode node) {
e.normalize();
AttributedString as = buildAttributedString(ctx, e, node);
+ addGlyphPositionAttributes(as, e, ctx);
+
((TextNode)node).setAttributedCharacterIterator(as.getIterator());
// 'filter'
@@ -341,11 +344,6 @@
as = createAttributedString(s, map, indexMap, preserve,
stripFirst, last && top);
if (as != null) {
- // NOTE: we get position attributes from the
- // surrounding text or tspan node, not the tref
- // link target
- addGlyphPositionAttributes
- (as, true, indexMap, ctx, nodeElement);
stripLast = !preserve &&
(as.getIterator().first() == ' ');
if (stripLast) {
@@ -372,10 +370,6 @@
as = createAttributedString
(s, m, indexMap, preserve, stripFirst, last && top);
if (as != null) {
- if (first) {
- addGlyphPositionAttributes
- (as, !top, indexMap, ctx, element);
- }
stripLast =
!preserve && (as.getIterator().first() == ' ');
if (stripLast && !result.isEmpty()) {
@@ -499,102 +493,147 @@
return as;
}
+ // returns true if node1 is an ancestor of node2
+ private boolean nodeAncestorOf(Node node1, Node node2) {
+ Node parent = node2.getParentNode();
+ while (parent != null && parent != node1) {
+ parent = parent.getParentNode();
+ }
+ if (parent == node1) {
+ return true;
+ }
+ return false;
+ }
+
+
/**
* Adds glyph position attributes to an AttributedString.
*/
protected void addGlyphPositionAttributes(AttributedString as,
- boolean isChild,
- int[] indexMap,
- BridgeContext ctx,
- Element element) {
-
- UnitProcessor.Context uctx
- = UnitProcessor.createContext(ctx, element);
+ Element element,
+ BridgeContext ctx) {
- int asLength = as.getIterator().getEndIndex();
- // AttributedStrings always start at index 0, we hope!
+ // get all of the glyph position attribute values
+ String xAtt = element.getAttributeNS(null, SVG_X_ATTRIBUTE);
+ String yAtt = element.getAttributeNS(null, SVG_Y_ATTRIBUTE);
+ String dxAtt = element.getAttributeNS(null, SVG_DX_ATTRIBUTE);
+ String dyAtt = element.getAttributeNS(null, SVG_DY_ATTRIBUTE);
+ String rotateAtt = element.getAttributeNS(null, SVG_ROTATE_ATTRIBUTE);
+
+ UnitProcessor.Context uctx = UnitProcessor.createContext(ctx, element);
+ AttributedCharacterIterator aci = as.getIterator();
+
+ // calculate which chars in the string belong to this element
+ int firstChar = 0;
+ for (int i = 0; i < aci.getEndIndex(); i++) {
+ aci.setIndex(i);
+ Element delimeter = (Element)aci.getAttribute(
+ GVTAttributedCharacterIterator.TextAttribute.TEXT_COMPOUND_DELIMITER);
+ if (delimeter == element || nodeAncestorOf(element, delimeter)) {
+ firstChar = i;
+ break;
+ }
+ }
+ int lastChar = aci.getEndIndex()-1;
+ for (int i = aci.getEndIndex()-1; i >= 0; i--) {
+ aci.setIndex(i);
+ Element delimeter = (Element)aci.getAttribute(
+
GVTAttributedCharacterIterator.TextAttribute.TEXT_COMPOUND_DELIMITER);
+ if (delimeter == element || nodeAncestorOf(element, delimeter)) {
+ lastChar = i;
+ break;
+ }
+ }
- // glyph and sub-element positions
- String s = element.getAttributeNS(null, SVG_X_ATTRIBUTE);
- if (s.length() != 0) {
+ // process the x attribute
+ if (xAtt.length() != 0) {
float x[] = TextUtilities.svgHorizontalCoordinateArrayToUserSpace
- (element, SVG_X_ATTRIBUTE, s, ctx);
-
- as.addAttribute(GVTAttributedCharacterIterator.TextAttribute.X,
- new Float(Float.NaN), 0, asLength);
+ (element, SVG_X_ATTRIBUTE, xAtt, ctx);
- if ((x.length > 1) || (isChild)) {
-
as.addAttribute(GVTAttributedCharacterIterator.TextAttribute.EXPLICIT_LAYOUT,
Boolean.TRUE, 0, asLength);
- }
-
- for (int i=0; i<asLength; ++i) {
- if (i < x.length) {
- as.addAttribute(GVTAttributedCharacterIterator.TextAttribute.X,
new Float(x[i]), i, i+1);
+ for (int i = 0; i < x.length; i++) {
+ if (firstChar+i <= lastChar) {
+ as.addAttribute
+ (GVTAttributedCharacterIterator.TextAttribute.X,
+ new Float(x[i]), firstChar+i, firstChar+i+1);
}
}
}
- // parse the y attribute, (default is 0)
- s = element.getAttributeNS(null, SVG_Y_ATTRIBUTE);
-
- if (s.length() != 0) {
+ // process the y attribute
+ if (yAtt.length() != 0) {
float y[] = TextUtilities.svgVerticalCoordinateArrayToUserSpace
- (element, SVG_Y_ATTRIBUTE, s, ctx);
+ (element, SVG_Y_ATTRIBUTE, yAtt, ctx);
- as.addAttribute(GVTAttributedCharacterIterator.TextAttribute.Y,
- new Float(Float.NaN), 0, asLength);
-
- if ((y.length > 1) || (isChild)) {
- as.addAttribute
- (GVTAttributedCharacterIterator.TextAttribute.EXPLICIT_LAYOUT,
Boolean.TRUE, 0, asLength);
- }
-
- for (int i=0; i<asLength; ++i) {
- if (i < y.length) {
+ for (int i = 0; i < y.length; i++) {
+ if (firstChar+i <= lastChar) {
as.addAttribute
(GVTAttributedCharacterIterator.TextAttribute.Y,
- new Float(y[i]), i, i+1);
+ new Float(y[i]), firstChar+i, firstChar+i+1);
}
}
}
- s = element.getAttributeNS(null, SVG_DX_ATTRIBUTE);
- if (s.length() != 0) {
- float x[] = TextUtilities.svgHorizontalCoordinateArrayToUserSpace
- (element, SVG_DX_ATTRIBUTE, s, ctx);
+ // process dx attribute
+ if (dxAtt.length() != 0) {
+ float dx[] = TextUtilities.svgHorizontalCoordinateArrayToUserSpace
+ (element, SVG_DX_ATTRIBUTE, dxAtt, ctx);
- as.addAttribute
- (GVTAttributedCharacterIterator.TextAttribute.DX,
- new Float(Float.NaN), 0, asLength);
-
- for (int i=0; i<asLength; ++i) {
- if (i < x.length) {
+ for (int i = 0; i < dx.length; i++) {
+ if (firstChar+i <= lastChar) {
as.addAttribute
(GVTAttributedCharacterIterator.TextAttribute.DX,
- new Float(x[i]), i, i+1);
+ new Float(dx[i]), firstChar+i, firstChar+i+1);
}
}
}
- // parse the y attribute, (default is 0)
- s = element.getAttributeNS(null, SVG_DY_ATTRIBUTE);
- if (s.length() != 0) {
- float y[] = TextUtilities.svgVerticalCoordinateArrayToUserSpace
- (element, SVG_DY_ATTRIBUTE, s, ctx);
+ // process dy attribute
+ if (dyAtt.length() != 0) {
+ float dy[] = TextUtilities.svgVerticalCoordinateArrayToUserSpace
+ (element, SVG_DY_ATTRIBUTE, dyAtt, ctx);
- as.addAttribute
- (GVTAttributedCharacterIterator.TextAttribute.DY,
- new Float(Float.NaN), 0, asLength);
-
- for (int i=0; i<asLength; ++i) {
- if (i < y.length) {
+ for (int i = 0; i < dy.length; i++) {
+ if (firstChar+i <= lastChar) {
as.addAttribute
(GVTAttributedCharacterIterator.TextAttribute.DY,
- new Float(y[i]), i, i+1);
+ new Float(dy[i]), firstChar+i, firstChar+i+1);
+ }
+ }
+ }
+
+ // process rotate attribute
+ if (rotateAtt.length() != 0) {
+ float rotate[] = TextUtilities.svgRotateArrayToFloats
+ (element, SVG_ROTATE_ATTRIBUTE, rotateAtt, ctx);
+
+ if (rotate.length == 1) { // not a list
+ // each char will have the same rotate value
+ as.addAttribute
+ (GVTAttributedCharacterIterator.TextAttribute.ROTATION,
+ new Float(rotate[0]), firstChar, lastChar+1);
+
+ } else { // its a list
+ // set each rotate value from the list
+ for (int i = 0; i < rotate.length; i++) {
+ if (firstChar+i <= lastChar) {
+ as.addAttribute
+ (GVTAttributedCharacterIterator.TextAttribute.ROTATION,
+ new Float(rotate[i]), firstChar+i, firstChar+i+1);
+ }
}
}
}
+
+ // do the same for each child element
+ NodeList children = element.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if (child.getNodeType() == Node.ELEMENT_NODE) {
+ addGlyphPositionAttributes(as, (Element)child, ctx);
+ }
+ }
}
+
/**
* Returns the map to pass to the current characters.
1.4 +29 -3 xml-batik/sources/org/apache/batik/bridge/TextUtilities.java
Index: TextUtilities.java
===================================================================
RCS file: /home/cvs/xml-batik/sources/org/apache/batik/bridge/TextUtilities.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- TextUtilities.java 2001/03/18 18:18:18 1.3
+++ TextUtilities.java 2001/07/31 06:20:10 1.4
@@ -22,9 +22,9 @@
* A collection of utility method for text.
*
* @author <a href="[EMAIL PROTECTED]>Bill Haneman</a>
- * @version $Id: TextUtilities.java,v 1.3 2001/03/18 18:18:18 vhardy Exp $
+ * @version $Id: TextUtilities.java,v 1.4 2001/07/31 06:20:10 bella Exp $
*/
-public abstract class TextUtilities implements CSSConstants {
+public abstract class TextUtilities implements CSSConstants, ErrorConstants {
/**
* Returns the float array that represents a set of horizontal
@@ -81,7 +81,7 @@
values.add
(new Float(UnitProcessor.svgVerticalCoordinateToUserSpace
(st.nextToken(), attrName, uctx)));
- c++;
+ c++;
}
float[] floats = new float[c];
for (int i=0; i<c; ++i) {
@@ -89,6 +89,32 @@
}
return floats;
}
+
+
+ public static float[] svgRotateArrayToFloats(Element element,
+ String attrName,
+ String valueStr,
+ BridgeContext ctx) {
+
+ StringTokenizer st = new StringTokenizer(valueStr, ", ", false);
+ float[] floats = new float[st.countTokens()];
+ int c = 0;
+ String s;
+ while (st.hasMoreTokens()) {
+ try {
+ s = st.nextToken();
+ floats[c] = (float)Math.toRadians(SVGUtilities.convertSVGNumber(s));
+ c++;
+ } catch (NumberFormatException ex) {
+ throw new BridgeException
+ (element, ERR_ATTRIBUTE_VALUE_MALFORMED,
+ new Object [] {attrName, valueStr});
+ }
+ }
+ return floats;
+ }
+
+
/**
* Converts the font-size CSS value to a float value.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]