diff --git a/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGTextPathElementBridge.java b/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGTextPathElementBridge.java
index 56c244611..26f2e2f3a 100644
--- a/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGTextPathElementBridge.java
+++ b/echosvg-bridge/src/main/java/io/sf/carte/echosvg/bridge/SVGTextPathElementBridge.java
@@ -68,42 +68,58 @@ public void handleElement(BridgeContext ctx, Element e) {
* @return The new TextPath.
*/
public TextPath createTextPath(BridgeContext ctx, Element textPathElement) {
+ Element pathElement;
+ // Check whether the textPath has a 'path' attribute
+ String path = textPathElement.getAttributeNS(null, SVG_PATH_ATTRIBUTE).trim();
+
+ if (path.isEmpty()) {
+ // get the referenced element
+ String uri = XLinkSupport.getXLinkHref(textPathElement);
+ pathElement = ctx.getReferencedElement(textPathElement, uri);
+
+ if (pathElement == null || !SVG_NAMESPACE_URI.equals(pathElement.getNamespaceURI())
+ || !pathElement.getLocalName().equals(SVG_PATH_TAG)) {
+ // couldn't find the referenced element
+ // or the referenced element was not a path
+ throw new BridgeException(ctx, textPathElement, ERR_URI_BAD_TARGET,
+ new Object[] { uri });
+ }
- // get the referenced element
- String uri = XLinkSupport.getXLinkHref(textPathElement);
- Element pathElement = ctx.getReferencedElement(textPathElement, uri);
-
- if ((pathElement == null) || (!SVG_NAMESPACE_URI.equals(pathElement.getNamespaceURI()))
- || (!pathElement.getLocalName().equals(SVG_PATH_TAG))) {
- // couldn't find the referenced element
- // or the referenced element was not a path
- throw new BridgeException(ctx, textPathElement, ERR_URI_BAD_TARGET, new Object[] { uri });
+ // construct a shape for the referenced path element
+ path = pathElement.getAttributeNS(null, SVG_D_ATTRIBUTE);
+ if (path.isEmpty()) {
+ throw new BridgeException(ctx, pathElement, ERR_ATTRIBUTE_MISSING,
+ new Object[] { SVG_D_ATTRIBUTE });
+ }
+ } else {
+ pathElement = textPathElement;
}
- // construct a shape for the referenced path element
- String s = pathElement.getAttributeNS(null, SVG_D_ATTRIBUTE);
Shape pathShape = null;
- if (s.length() != 0) {
- AWTPathProducer app = new AWTPathProducer();
- app.setWindingRule(CSSUtilities.convertFillRule(pathElement));
- try {
- PathParser pathParser = new PathParser(app);
- pathParser.parse(s);
- } catch (ParseException pEx) {
- throw new BridgeException(ctx, pathElement, pEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
- new Object[] { SVG_D_ATTRIBUTE });
- } finally {
- pathShape = app.getShape();
+ AWTPathProducer app = new AWTPathProducer();
+ app.setWindingRule(CSSUtilities.convertFillRule(pathElement));
+ try {
+ PathParser pathParser = new PathParser(app);
+ pathParser.parse(path);
+ } catch (ParseException pEx) {
+ final String attrName;
+ if (pathElement != textPathElement) {
+ attrName = SVG_D_ATTRIBUTE;
+ } else {
+ attrName = SVG_PATH_ATTRIBUTE;
}
- } else {
- throw new BridgeException(ctx, pathElement, ERR_ATTRIBUTE_MISSING, new Object[] { SVG_D_ATTRIBUTE });
+ throw new BridgeException(ctx, pathElement, pEx, ERR_ATTRIBUTE_VALUE_MALFORMED,
+ new Object[] { attrName });
+ } finally {
+ pathShape = app.getShape();
}
// if the reference path element has a transform apply the transform
// to the path shape
- s = pathElement.getAttributeNS(null, SVG_TRANSFORM_ATTRIBUTE);
- if (s.length() != 0) {
- AffineTransform tr = SVGUtilities.convertTransform(pathElement, SVG_TRANSFORM_ATTRIBUTE, s, ctx);
+ String s = pathElement.getAttributeNS(null, SVG_TRANSFORM_ATTRIBUTE);
+ if (!s.isEmpty()) {
+ AffineTransform tr = SVGUtilities.convertTransform(pathElement, SVG_TRANSFORM_ATTRIBUTE,
+ s, ctx);
pathShape = tr.createTransformedShape(pathShape);
}
@@ -112,7 +128,7 @@ public TextPath createTextPath(BridgeContext ctx, Element textPathElement) {
// set the start offset if specified
s = textPathElement.getAttributeNS(null, SVG_START_OFFSET_ATTRIBUTE);
- if (s.length() > 0) {
+ if (!s.isEmpty()) {
float startOffset = 0;
int percentIndex = s.indexOf('%');
if (percentIndex != -1) {
diff --git a/echosvg-test/src/test/java/io/sf/carte/echosvg/test/svg/SamplesSpecRenderingTest.java b/echosvg-test/src/test/java/io/sf/carte/echosvg/test/svg/SamplesSpecRenderingTest.java
index 27d05f945..404fbb64f 100644
--- a/echosvg-test/src/test/java/io/sf/carte/echosvg/test/svg/SamplesSpecRenderingTest.java
+++ b/echosvg-test/src/test/java/io/sf/carte/echosvg/test/svg/SamplesSpecRenderingTest.java
@@ -914,7 +914,7 @@ public void testTextLength() throws TranscoderException, IOException {
@Test
public void testTextOnPath() throws TranscoderException, IOException {
- test("samples/tests/spec/text/textOnPath.svg");
+ testNV("samples/tests/spec/text/textOnPath.svg");
}
@Test
@@ -932,6 +932,26 @@ public void testTextOnPathSpaces() throws TranscoderException, IOException {
test("samples/tests/spec/text/textOnPathSpaces.svg");
}
+ @Test
+ public void testTextOnPathPathAttr() throws TranscoderException, IOException {
+ testNV("samples/tests/spec/text/textOnPathPathAttr.svg");
+ }
+
+ @Test
+ public void testTextOnPathPathAttr2() throws TranscoderException, IOException {
+ testNV("samples/tests/spec/text/textOnPathPathAttr2.svg");
+ }
+
+ @Test
+ public void testTextOnPathPathAttr3() throws TranscoderException, IOException {
+ testNV("samples/tests/spec/text/textOnPathPathAttr3.svg");
+ }
+
+ @Test
+ public void testTextOnPathPathAttrSpaces() throws TranscoderException, IOException {
+ testNV("samples/tests/spec/text/textOnPathPathAttrSpaces.svg");
+ }
+
@Test
public void testTextPCDATA() throws TranscoderException, IOException {
test("samples/tests/spec/text/textPCDATA.svg");
@@ -962,6 +982,11 @@ public void testVerticalTextOnPath() throws TranscoderException, IOException {
test("samples/tests/spec/text/verticalTextOnPath.svg");
}
+ @Test
+ public void testVerticalTextOnPathPathAttr() throws TranscoderException, IOException {
+ testNV("samples/tests/spec/text/verticalTextOnPathPathAttr.svg");
+ }
+
@Test
public void testTextPosition() throws TranscoderException, IOException {
test("samples/tests/spec/text/textPosition.svg");
diff --git a/echosvg-test/src/test/java/io/sf/carte/echosvg/test/svg/StyleBypassRenderingTest.java b/echosvg-test/src/test/java/io/sf/carte/echosvg/test/svg/StyleBypassRenderingTest.java
index e98533d55..b8f95c672 100644
--- a/echosvg-test/src/test/java/io/sf/carte/echosvg/test/svg/StyleBypassRenderingTest.java
+++ b/echosvg-test/src/test/java/io/sf/carte/echosvg/test/svg/StyleBypassRenderingTest.java
@@ -945,7 +945,7 @@ public void testTextLength() throws TranscoderException, IOException {
@Test
public void testTextOnPath() throws TranscoderException, IOException {
- test("samples/tests/spec/text/textOnPath.svg");
+ testNV("samples/tests/spec/text/textOnPath.svg");
}
@Test
diff --git a/samples/tests/spec/text/textOnPath.svg b/samples/tests/spec/text/textOnPath.svg
index 5939a8745..4fb22c2c2 100644
--- a/samples/tests/spec/text/textOnPath.svg
+++ b/samples/tests/spec/text/textOnPath.svg
@@ -1,6 +1,4 @@
-
+
+
+
+
+
+
+
+
+
diff --git a/samples/tests/spec/text/textOnPathPathAttr2.svg b/samples/tests/spec/text/textOnPathPathAttr2.svg
new file mode 100644
index 000000000..6bd4face9
--- /dev/null
+++ b/samples/tests/spec/text/textOnPathPathAttr2.svg
@@ -0,0 +1,90 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/tests/spec/text/textOnPathPathAttr3.svg b/samples/tests/spec/text/textOnPathPathAttr3.svg
new file mode 100644
index 000000000..0dcc940c8
--- /dev/null
+++ b/samples/tests/spec/text/textOnPathPathAttr3.svg
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/tests/spec/text/textOnPathPathAttrSpaces.svg b/samples/tests/spec/text/textOnPathPathAttrSpaces.svg
new file mode 100644
index 000000000..2267fb616
--- /dev/null
+++ b/samples/tests/spec/text/textOnPathPathAttrSpaces.svg
@@ -0,0 +1,159 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/tests/spec/text/verticalTextOnPathPathAttr.svg b/samples/tests/spec/text/verticalTextOnPathPathAttr.svg
new file mode 100644
index 000000000..52c70e127
--- /dev/null
+++ b/samples/tests/spec/text/verticalTextOnPathPathAttr.svg
@@ -0,0 +1,171 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test-references/samples/tests/spec/text/textOnPathPathAttr.png b/test-references/samples/tests/spec/text/textOnPathPathAttr.png
new file mode 100644
index 000000000..e3cf8afc3
Binary files /dev/null and b/test-references/samples/tests/spec/text/textOnPathPathAttr.png differ
diff --git a/test-references/samples/tests/spec/text/textOnPathPathAttr2.png b/test-references/samples/tests/spec/text/textOnPathPathAttr2.png
new file mode 100644
index 000000000..203415b46
Binary files /dev/null and b/test-references/samples/tests/spec/text/textOnPathPathAttr2.png differ
diff --git a/test-references/samples/tests/spec/text/textOnPathPathAttr3.png b/test-references/samples/tests/spec/text/textOnPathPathAttr3.png
new file mode 100644
index 000000000..3572609ed
Binary files /dev/null and b/test-references/samples/tests/spec/text/textOnPathPathAttr3.png differ
diff --git a/test-references/samples/tests/spec/text/textOnPathPathAttrSpaces.png b/test-references/samples/tests/spec/text/textOnPathPathAttrSpaces.png
new file mode 100644
index 000000000..6e9f31124
Binary files /dev/null and b/test-references/samples/tests/spec/text/textOnPathPathAttrSpaces.png differ
diff --git a/test-references/samples/tests/spec/text/verticalTextOnPathPathAttr.png b/test-references/samples/tests/spec/text/verticalTextOnPathPathAttr.png
new file mode 100644
index 000000000..5289e8e53
Binary files /dev/null and b/test-references/samples/tests/spec/text/verticalTextOnPathPathAttr.png differ