deweese 2005/01/03 02:48:07
Modified: samples anne.svg
samples/tests/spec/text textAnchor.svg textAnchor2.svg
textAnchor3.svg
samples/tests/spec12/text flowText.svg flowText2.svg
flowText3.svg flowText4.svg flowText5.svg
sources/org/apache/batik/bridge DocumentLoader.java
SVGTextElementBridge.java
sources/org/apache/batik/bridge/svg12
SVGFlowRootElementBridge.java
sources/org/apache/batik/extension/svg
BatikFlowTextElementBridge.java
sources/org/apache/batik/gvt/flow FlowGlyphLayout.java
test-references/samples/tests/spec/linking anchor.png
anchorInsideText.png pointerEvents.png
pointerEvents2.png
test-references/samples/tests/spec/structure
symbolViewBoxClip.png symbolViewBoxOverflow.png
toolTips.png
test-references/samples/tests/spec/text smallFonts.png
test-references/samples/tests/spec12/text flowText2.png
test-resources/org/apache/batik/test samplesRendering.xml
Added: samples/tests/spec/text xmlSpace.svg
test-references/samples/tests/spec/text xmlSpace.png
Log:
1) The document loader caching was a memory leak because it always
used hard references. It now uses soft references.
2) Reworked the xml:space support so it behaves a bit more
rationally. The code is also simplier. Still have no idea
what the specification really wants!
PR: 32872
Revision Changes Path
1.11 +4 -2 xml-batik/samples/anne.svg
Index: anne.svg
===================================================================
RCS file: /home/cvs/xml-batik/samples/anne.svg,v
retrieving revision 1.10
retrieving revision 1.11
diff -u -r1.10 -r1.11
--- anne.svg 18 Aug 2004 07:11:34 -0000 1.10
+++ anne.svg 3 Jan 2005 10:48:05 -0000 1.11
@@ -26,7 +26,9 @@
<!-- @version $Id$
-->
<!--
========================================================================= -->
-<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink" width="450" height="500" viewBox="0
0 450 500">
+<svg width="450" height="500" viewBox="0 0 450 500"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink" >
<!-- ============================================================= -->
<!-- Test content -->
<!-- ============================================================= -->
1.4 +4 -2 xml-batik/samples/tests/spec/text/textAnchor.svg
Index: textAnchor.svg
===================================================================
RCS file: /home/cvs/xml-batik/samples/tests/spec/text/textAnchor.svg,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- textAnchor.svg 18 Aug 2004 07:12:21 -0000 1.3
+++ textAnchor.svg 3 Jan 2005 10:48:05 -0000 1.4
@@ -27,7 +27,9 @@
<!-- ======================================================================
-->
<?xml-stylesheet type="text/css" href="../../resources/style/test.css" ?>
-<svg width="450" height="500" viewBox="0 0 450 500" >
+<svg width="450" height="500" viewBox="0 0 450 500"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink" >
<text class="title" x="50%" y="40">text-anchor on <tspan></text>
1.5 +4 -2 xml-batik/samples/tests/spec/text/textAnchor2.svg
Index: textAnchor2.svg
===================================================================
RCS file: /home/cvs/xml-batik/samples/tests/spec/text/textAnchor2.svg,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- textAnchor2.svg 18 Aug 2004 07:12:21 -0000 1.4
+++ textAnchor2.svg 3 Jan 2005 10:48:05 -0000 1.5
@@ -27,7 +27,9 @@
<!-- ======================================================================
-->
<?xml-stylesheet type="text/css" href="../../resources/style/test.css" ?>
-<svg width="450" height="500" viewBox="0 0 450 500" >
+<svg width="450" height="500" viewBox="0 0 450 500"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink" >
<text class="title" x="50%" y="30">text-anchor on a single
<tspan></text>
1.4 +4 -2 xml-batik/samples/tests/spec/text/textAnchor3.svg
Index: textAnchor3.svg
===================================================================
RCS file: /home/cvs/xml-batik/samples/tests/spec/text/textAnchor3.svg,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- textAnchor3.svg 18 Aug 2004 07:12:21 -0000 1.3
+++ textAnchor3.svg 3 Jan 2005 10:48:05 -0000 1.4
@@ -27,7 +27,9 @@
<!-- ======================================================================
-->
<?xml-stylesheet type="text/css" href="../../resources/style/test.css" ?>
-<svg width="450" height="500" viewBox="0 0 450 500" >
+<svg width="450" height="500" viewBox="0 0 450 500"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink" >
<text class="title" x="50%" y="30">text-anchor on a single
<tspan></text>
1.1 xml-batik/samples/tests/spec/text/xmlSpace.svg
Index: xmlSpace.svg
===================================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<!--
Copyright 2004 The Apache Software Foundation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
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.
-->
<!-- ======================================================================
-->
<!-- Tests "proper" handling of xml:space
-->
<!--
-->
<!-- @author [EMAIL PROTECTED] -->
<!-- @version $Id: xmlSpace.svg,v 1.1 2005/01/03 10:48:05 deweese Exp $ -->
<!-- ======================================================================
-->
<?xml-stylesheet type="text/css" href="../../resources/style/test.css" ?>
<svg width="450" height="500" viewBox="0 0 450 500"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:foo="http://graphics.apache.org/batik/foo">
<text class="title" x="50%" y="40">Test of xml:space handling</text>
<font horiz-adv-x="600" id="stroke">
<font-face
font-family="BlockSpace"
font-weight="normal"
units-per-em="1000"
ascent="1000"
descent="250"
alphabetic="0"/>
<missing-glyph horiz-adv-x="600" d="M0 0 V800 H500 V0 z"/>
<glyph unicode=" " glyph-name=" " horiz-adv-x="600"
d="M20 0 V800 H520 V0 z M 50 30 H490 V770 H50 z"/>
</font>
<style type="text/css"><![CDATA[
.cap { font: normal normal 8 monospaced;
stroke: none; stroke-width: 0;
fill: black } ]]>
</style>
<g font="20 BlockSpace">
<text x="10" y=" 75"> X X </text>
<text class="cap" x="120" y="75">no xml:space attr</text>
<text x="10" y="100" xml:space="default"> X X </text>
<text class="cap" x="120" y="100">xml:space="default"</text>
<text x="10" y="150" xml:space="preserve"> X X <tspan fill="red"
xml:space="default"/></text>
<text class="cap" x="120" y="140">Empty tspan at end
<tspan x="120" dy="1.2em">xml:space="default"</tspan></text>
<text x="10" y="175" xml:space="preserve"> X X<tspan fill="red"
xml:space="default"> </tspan></text>
<text class="cap" x="120" y="165">tspan end 2spc
<tspan x="120" dy="1.2em">xml:space="default"</tspan></text>
<text x="10" y="200" xml:space="preserve"> X X <tspan fill="red"
xml:space="default"> </tspan></text>
<text class="cap" x="120" y="190">tspan end
<tspan x="120" dy="1.2em">xml:space="default"</tspan></text>
<text x="10" y="225" xml:space="preserve"><tspan fill="red"
xml:space="default"> </tspan> X X </text>
<text class="cap" x="120" y="215">tspan start
<tspan x="120" dy="1.2em">xml:space="default"</tspan></text>
<text x="10" y="250" xml:space="preserve"> <tspan fill="red"
xml:space="default"> </tspan>X X </text>
<text class="cap" x="120" y="240">tspan near start
<tspan x="120" dy="1.2em">xml:space="default"</tspan></text>
<text x="10" y="275" xml:space="preserve"> X<tspan fill="red"
xml:space="default"> </tspan> X </text>
<text class="cap" x="120" y="265">tspan middle front
<tspan x="120" dy="1.2em">xml:space="default"</tspan></text>
<text x="10" y="300" xml:space="preserve"> X <tspan fill="red"
xml:space="default"> </tspan>X </text>
<text class="cap" x="120" y="290">tspan middle end
<tspan x="120" dy="1.2em">xml:space="default"</tspan></text>
<text x="10" y="325" xml:space="preserve"> <foo:xxx/> X X </text>
<text class="cap" x="120" y="315">unknown element
<tspan x="120" dy="1.2em">start</tspan></text>
<text x="10" y="350" xml:space="preserve"> X <foo:xxx/> X </text>
<text class="cap" x="120" y="340">unknown element
<tspan x="120" dy="1.2em">middle</tspan></text>
<text x="10" y="375" xml:space="preserve"> X X <foo:xxx/> </text>
<text class="cap" x="120" y="365">unknown element
<tspan x="120" dy="1.2em">end</tspan></text>
<!-- -->
<text x="235" y="100" xml:space="preserve"> X X </text>
<text class="cap" x="345" y="100">xml:space="preserve"</text>
<text x="235" y="150" xml:space="default"> X X <tspan fill="red"
xml:space="preserve"/></text>
<text class="cap" x="345" y="140">Empty tspan at end
<tspan x="345"
dy="1.2em">xml:space="preserve"</tspan></text>
<text x="235" y="175" xml:space="default"> X X<tspan fill="red"
xml:space="preserve"> </tspan></text>
<text class="cap" x="345" y="165">tspan end 2spc
<tspan x="345"
dy="1.2em">xml:space="preserve"</tspan></text>
<text x="235" y="200" xml:space="default"> X X <tspan fill="red"
xml:space="preserve"> </tspan></text>
<text class="cap" x="345" y="190">tspan end
<tspan x="345"
dy="1.2em">xml:space="preserve"</tspan></text>
<text x="235" y="225" xml:space="default"><tspan fill="red"
xml:space="preserve"> </tspan> X X </text>
<text class="cap" x="345" y="215">tspan start
<tspan x="345"
dy="1.2em">xml:space="preserve"</tspan></text>
<text x="235" y="250" xml:space="default"> <tspan fill="red"
xml:space="preserve"> </tspan>X X </text>
<text class="cap" x="345" y="240">tspan near start
<tspan x="345"
dy="1.2em">xml:space="preserve"</tspan></text>
<text x="235" y="275" xml:space="default"> X<tspan fill="red"
xml:space="preserve"> </tspan> X </text>
<text class="cap" x="345" y="265">tspan middle front
<tspan x="345"
dy="1.2em">xml:space="preserve"</tspan></text>
<text x="235" y="300" xml:space="default"> X <tspan fill="red"
xml:space="preserve"> </tspan>X </text>
<text class="cap" x="345" y="290">tspan middle end
<tspan x="345"
dy="1.2em">xml:space="preserve"</tspan></text>
<text x="235" y="325" xml:space="default"> <foo:xxx/> X X </text>
<text class="cap" x="345" y="315">unknown element
<tspan x="345" dy="1.2em">start</tspan></text>
<text x="235" y="350" xml:space="default"> X <foo:xxx/> X </text>
<text class="cap" x="345" y="340">unknown element
<tspan x="345" dy="1.2em">middle</tspan></text>
<text x="236" y="375" xml:space="default"> X X <foo:xxx/> </text>
<text class="cap" x="345" y="365">unknown element
<tspan x="345" dy="1.2em">end</tspan></text>
</g>
</svg>
1.3 +2 -2 xml-batik/samples/tests/spec12/text/flowText.svg
Index: flowText.svg
===================================================================
RCS file: /home/cvs/xml-batik/samples/tests/spec12/text/flowText.svg,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- flowText.svg 30 Nov 2004 03:23:58 -0000 1.2
+++ flowText.svg 3 Jan 2005 10:48:05 -0000 1.3
@@ -46,7 +46,7 @@
<line x1="243" y1="70" x2="243" y2="490" stroke="grey" fill="none"/>
<line x1="423" y1="70" x2="423" y2="490" stroke="grey" fill="none"/>
- <flowRoot font-size="20" xml:space="preserve">
+ <flowRoot font-size="20">
<flowRegion>
<rect x="17" y="80" width="200" height="400"/>
<rect x="233" y="80" width="200" height="400"/>
1.2 +2 -2 xml-batik/samples/tests/spec12/text/flowText2.svg
Index: flowText2.svg
===================================================================
RCS file: /home/cvs/xml-batik/samples/tests/spec12/text/flowText2.svg,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- flowText2.svg 18 Nov 2004 01:46:52 -0000 1.1
+++ flowText2.svg 3 Jan 2005 10:48:05 -0000 1.2
@@ -53,7 +53,7 @@
<line x1="243" y1="70" x2="243" y2="490" stroke="grey" fill="none"/>
<line x1="423" y1="70" x2="423" y2="490" stroke="grey" fill="none"/>
- <flowRoot font-size="20" xml:space="preserve">
+ <flowRoot font-size="20">
<flowRegion>
<path d="M 67,80 l-50,400 h200 l-50,-400 z"/>
<!-- <rect x="17" y="80" width="200" height="400"/> -->
1.2 +2 -2 xml-batik/samples/tests/spec12/text/flowText3.svg
Index: flowText3.svg
===================================================================
RCS file: /home/cvs/xml-batik/samples/tests/spec12/text/flowText3.svg,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- flowText3.svg 18 Nov 2004 01:46:52 -0000 1.1
+++ flowText3.svg 3 Jan 2005 10:48:05 -0000 1.2
@@ -48,7 +48,7 @@
<line x1="243" y1="70" x2="243" y2="490" stroke="grey" fill="none"/>
<line x1="423" y1="70" x2="423" y2="490" stroke="grey" fill="none"/>
- <flowRoot font-size="20" xml:space="preserve">
+ <flowRoot font-size="20">
<flowRegion>
<path d="M 17,80 v400 h200 v-400 z
M 220,80 v400 h10 v-400 z
1.2 +3 -3 xml-batik/samples/tests/spec12/text/flowText4.svg
Index: flowText4.svg
===================================================================
RCS file: /home/cvs/xml-batik/samples/tests/spec12/text/flowText4.svg,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- flowText4.svg 18 Nov 2004 01:46:52 -0000 1.1
+++ flowText4.svg 3 Jan 2005 10:48:05 -0000 1.2
@@ -43,7 +43,7 @@
font-size="500" font-weight="bold"
text-anchor="middle"
>B</text>
- <flowRoot font-size="10" xml:space="preserve">
+ <flowRoot font-size="10">
<flowRegion>
<text x="225" y="450" font-size="500" font-weight="bold"
text-anchor="middle">B</text>
<!-- <rect x="17" y="80" width="200" height="400"/>
@@ -52,7 +52,7 @@
<flowDiv>
<flowPara indent="20" margin-top="3" margin-bottom="5" >This is an
<flowSpan font-size="40" fill="crimson">ex­ample</flowSpan> of a very
long string that is split ‍across multi­ple lines via text
wrap­ping.</flowPara>
- <flowPara text-align="middle" margin-top="5" margin-left="10"
margin-right="10" margin-bottom="5"><flowLine>Now check if text wrapping
handles a number of tricky</flowLine> situations:
a­very­long­runon­word­that­spans­multiple­lines­<flowSpan
font-weight="bold">with­<flowSpan
fill="crimson">embedded­</flowSpan>span</flowSpan>­elements &
<flowSpan fill="green" dy="-.3em" font-size="80%">super</flowSpan><flowSpan
dy=".3em"> or </flowSpan><flowSpan fill="darkgreen" dy=".3em"
font-size="80%">sub</flowSpan><flowSpan dy="-.3em">
scripts.</flowSpan></flowPara>
+ <flowPara text-align="middle" margin-top="5" margin-left="10"
margin-right="10" margin-bottom="5"><flowLine>Now check if text wrapping
handles a number of tricky </flowLine>situations:
a­very­long­runon­word­that­spans­multiple­lines­<flowSpan
font-weight="bold">with­<flowSpan
fill="crimson">embedded­</flowSpan>span</flowSpan>­elements &
<flowSpan fill="green" dy="-.3em" font-size="80%">super</flowSpan><flowSpan
dy=".3em"> or </flowSpan><flowSpan fill="darkgreen" dy=".3em"
font-size="80%">sub</flowSpan><flowSpan dy="-.3em">
scripts.</flowSpan></flowPara>
<flowPara margin-top="5" text-align="end">Now we are just <flowSpan
font-size="30" fill="blue">about</flowSpan> to go to the next flow rect
<flowSpan font-size="10">(note if the 'about' were included on the last line of
the previous flow rect the line would not have fit and the whole line would
have moved here).</flowSpan></flowPara>
<flowPara margin="10" text-align="full"> I'll keep going
because I want to make sure that it properly stops when it hits the end of all
of the the flow regions defined. Also the last line includes text in a larger
font size so it will not fit. Thus the end of this sentence will be cut off
because the line size gets <flowSpan font-size="35">tall</flowSpan>er</flowPara>
</flowDiv>
1.2 +3 -3 xml-batik/samples/tests/spec12/text/flowText5.svg
Index: flowText5.svg
===================================================================
RCS file: /home/cvs/xml-batik/samples/tests/spec12/text/flowText5.svg,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- flowText5.svg 18 Nov 2004 01:46:52 -0000 1.1
+++ flowText5.svg 3 Jan 2005 10:48:05 -0000 1.2
@@ -42,7 +42,7 @@
<use width="400" height="400"
xlink:href="../../../batikLogo.svg#Batik_Squiggle" opacity="0.5"/>
<g transform="rotate(-45, 200, 200)">
- <flowRoot font-size="15.75" xml:space="preserve">
+ <flowRoot font-size="15.75">
<flowRegion>
<use transform="rotate(45, 200, 200)" width="400" height="400"
xlink:href="../../../batikLogo.svg#Batik_Squiggle" />
</flowRegion>
@@ -72,7 +72,7 @@
<use xlink:href="../../../batikLogo.svg#Batik_Squiggle_Green"/>
</g>
<g transform="rotate(-45, 200, 200)">
- <flowRoot font-size="16.5" xml:space="preserve">
+ <flowRoot font-size="16.5">
<flowRegion>
<use transform="rotate(45, 200, 200), scale(.73,.73)"
xlink:href="../../../batikLogo.svg#Batik_Squiggle_Blue"/>
1.23 +33 -13
xml-batik/sources/org/apache/batik/bridge/DocumentLoader.java
Index: DocumentLoader.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/bridge/DocumentLoader.java,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- DocumentLoader.java 18 Aug 2004 07:12:31 -0000 1.22
+++ DocumentLoader.java 3 Jan 2005 10:48:05 -0000 1.23
@@ -24,6 +24,8 @@
import org.apache.batik.dom.svg.SAXSVGDocumentFactory;
import org.apache.batik.dom.svg.SVGDocumentFactory;
import org.apache.batik.dom.util.DocumentDescriptor;
+import org.apache.batik.util.CleanerThread;
+
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.svg.SVGDocument;
@@ -80,9 +82,12 @@
if (n != -1) {
uri = uri.substring(0, n);
}
- DocumentState state = (DocumentState)cacheMap.get(uri);
+ DocumentState state;
+ synchronized (cacheMap) {
+ state = (DocumentState)cacheMap.get(uri);
+ }
if (state != null)
- return state.document;
+ return state.getDocument();
return null;
}
@@ -101,9 +106,11 @@
DocumentDescriptor desc = documentFactory.getDocumentDescriptor();
DocumentState state = new DocumentState(uri, document, desc);
- cacheMap.put(uri, state);
+ synchronized (cacheMap) {
+ cacheMap.put(uri, state);
+ }
- return state.document;
+ return state.getDocument();
}
/**
@@ -122,9 +129,11 @@
DocumentDescriptor desc = documentFactory.getDocumentDescriptor();
DocumentState state = new DocumentState(uri, document, desc);
- cacheMap.put(uri, state);
+ synchronized (cacheMap) {
+ cacheMap.put(uri, state);
+ }
- return state.document;
+ return state.getDocument();
}
/**
@@ -139,7 +148,9 @@
*/
public void dispose() {
// new Exception("purge the cache").printStackTrace();
- cacheMap.clear();
+ synchronized (cacheMap) {
+ cacheMap.clear();
+ }
}
/**
@@ -152,7 +163,10 @@
*/
public int getLineNumber(Element e) {
String uri = ((SVGDocument)e.getOwnerDocument()).getURL();
- DocumentState state = (DocumentState)cacheMap.get(uri);
+ DocumentState state;
+ synchronized (cacheMap) {
+ state = (DocumentState)cacheMap.get(uri);
+ }
if (state == null) {
return -1;
} else {
@@ -163,20 +177,25 @@
/**
* A simple class that contains a Document and its number of nodes.
*/
- private static class DocumentState {
+ private class DocumentState extends CleanerThread.SoftReferenceCleared {
private String uri;
- private Document document;
private DocumentDescriptor desc;
public DocumentState(String uri,
Document document,
DocumentDescriptor desc) {
+ super(document);
this.uri = uri;
- this.document = document;
this.desc = desc;
}
+ public void cleared() {
+ synchronized (cacheMap) {
+ cacheMap.remove(uri);
+ }
+ }
+
public DocumentDescriptor getDocumentDescriptor() {
return desc;
}
@@ -186,7 +205,8 @@
}
public Document getDocument() {
- return document;
+ return (Document)get();
}
}
+
}
1.102 +103 -82
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.101
retrieving revision 1.102
diff -u -r1.101 -r1.102
--- SVGTextElementBridge.java 2 Dec 2004 01:24:36 -0000 1.101
+++ SVGTextElementBridge.java 3 Jan 2005 10:48:05 -0000 1.102
@@ -771,6 +771,15 @@
return asb.toAttributedString();
}
+
+ /**
+ * This is used to store the end of the last piece of text
+ * content from an element with xml:space="preserve". When
+ * we are stripping trailing spaces we need to make sure
+ * we don't strip anything before this point.
+ */
+ protected int endLimit;
+
/**
* Fills the given AttributedStringBuffer.
*/
@@ -780,7 +789,8 @@
TextPath textPath,
Integer bidiLevel,
AttributedStringBuffer asb) {
- // 'requiredFeatures', 'requiredExtensions' and 'systemLanguage'
+ // 'requiredFeatures', 'requiredExtensions', 'systemLanguage' &
+ // 'display="none".
if ((!SVGUtilities.matchUserAgent(element, ctx.getUserAgent())) ||
(!CSSUtilities.convertDisplay(element))) {
return;
@@ -788,12 +798,14 @@
String s = XMLSupport.getXMLSpace(element);
boolean preserve = s.equals(SVG_PRESERVE_VALUE);
- boolean first = true;
- boolean last;
- boolean stripFirst = !preserve;
- boolean stripLast = !preserve;
+ boolean prevEndsWithSpace;
Element nodeElement = element;
+ if (top)
+ endLimit = 0;
+ if (preserve)
+ endLimit = asb.length();
+
Map map = getAttributeMap(ctx, element, textPath, bidiLevel);
Object o = map.get(TextAttribute.BIDI_EMBEDDING);
Integer subBidiLevel = bidiLevel;
@@ -804,12 +816,15 @@
n != null;
n = n.getNextSibling()) {
- last = n.getNextSibling() == null;
-
- int lastChar = asb.getLastChar();
- stripFirst = !preserve && first &&
- (top || lastChar == ' ' || lastChar == -1);
-
+ if (preserve) {
+ prevEndsWithSpace = false;
+ } else {
+ if (asb.length() == 0)
+ prevEndsWithSpace = true;
+ else
+ prevEndsWithSpace = (asb.getLastChar() == ' ');
+ }
+
switch (n.getNodeType()) {
case Node.ELEMENT_NODE:
if (!SVG_NAMESPACE_URI.equals(n.getNamespaceURI()))
@@ -844,14 +859,10 @@
String uriStr = XLinkSupport.getXLinkHref((Element)n);
Element ref = ctx.getReferencedElement((Element)n,
uriStr);
s = TextUtilities.getElementContent(ref);
- s = normalizeString(s, preserve, stripFirst, last &&
top);
+ s = normalizeString(s, preserve, prevEndsWithSpace);
if (s != null) {
- stripLast = !preserve && s.charAt(0) == ' ';
- if (stripLast && !asb.isEmpty()) {
- asb.stripLast();
- }
Map m = getAttributeMap(ctx, nodeElement,
- textPath, bidiLevel);
+ textPath, bidiLevel);
asb.append(s, m);
}
} else if (ln.equals(SVG_A_TAG)) {
@@ -872,15 +883,16 @@
case Node.TEXT_NODE:
case Node.CDATA_SECTION_NODE:
s = n.getNodeValue();
- s = normalizeString(s, preserve, stripFirst, last && top);
- if (s != null) {
- stripLast = !preserve && s.charAt(0) == ' ';
- if (stripLast && !asb.isEmpty())
- asb.stripLast();
- asb.append(s, map);
- }
+ s = normalizeString(s, preserve, prevEndsWithSpace);
+ asb.append(s, map);
+ if (preserve)
+ endLimit = asb.length();
}
- first = false;
+ }
+
+ if (top) {
+ while ((endLimit < asb.length()) && (asb.getLastChar() == ' '))
+ asb.stripLast();
}
}
@@ -889,9 +901,8 @@
*/
protected String normalizeString(String s,
boolean preserve,
- boolean stripfirst,
- boolean striplast) {
- StringBuffer sb = new StringBuffer();
+ boolean stripfirst) {
+ StringBuffer sb = new StringBuffer(s.length());
if (preserve) {
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
@@ -905,57 +916,45 @@
sb.append(c);
}
}
- } else {
- boolean space = false;
- int idx = 0;
- if (stripfirst) {
- loop: while (idx < s.length()) {
- switch (s.charAt(idx)) {
- default:
- break loop;
- case 10:
- case 13:
- case ' ':
- case '\t':
- idx++;
- }
- }
- }
- for (int i = idx; i < s.length(); i++) {
- char c = s.charAt(i);
- switch (c) {
+ return sb.toString();
+ }
+
+ int idx = 0;
+ if (stripfirst) {
+ loop: while (idx < s.length()) {
+ switch (s.charAt(idx)) {
+ default:
+ break loop;
case 10:
case 13:
- break;
case ' ':
case '\t':
- if (!space) {
- sb.append(' ');
- space = true;
- }
- break;
- default:
- sb.append(c);
- space = false;
+ idx++;
}
}
- if (striplast) {
- int len;
- while ((len = sb.length()) > 0) {
- if (sb.charAt(len - 1) == ' ') {
- sb.deleteCharAt(len - 1);
- } else {
- break;
- }
+ }
+
+ boolean space = false;
+ for (int i = idx; i < s.length(); i++) {
+ char c = s.charAt(i);
+ switch (c) {
+ case 10:
+ case 13:
+ break;
+ case ' ':
+ case '\t':
+ if (!space) {
+ sb.append(' ');
+ space = true;
}
+ break;
+ default:
+ sb.append(c);
+ space = false;
}
}
- if (sb.length() > 0) {
- return sb.toString();
- } else if (stripfirst && striplast) {
- return " ";
- }
- return null;
+
+ return sb.toString();
}
/**
@@ -1030,20 +1029,42 @@
}
/**
- * Strips the last string last character.
+ * Strips the last string character.
+ */
+ public void stripFirst() {
+ String s = (String)strings.get(0);
+ if (s.charAt(s.length() - 1) != ' ')
+ return;
+
+ length--;
+
+ if (s.length() == 1) {
+ attributes.remove(0);
+ strings.remove(0);
+ count--;
+ return;
+ }
+
+ strings.set(0, s.substring(1));
+ }
+
+ /**
+ * Strips the last string character.
*/
public void stripLast() {
- String s = (String)strings.remove(count - 1);
- if (s.charAt(s.length() - 1) == ' ') {
- if (s.length() == 1) {
- attributes.remove(--count);
- return;
- }
- strings.add(s.substring(0, s.length() - 1));
- length--;
- } else {
- strings.add(s);
+ String s = (String)strings.get(count - 1);
+ if (s.charAt(s.length() - 1) != ' ')
+ return;
+
+ length--;
+
+ if (s.length() == 1) {
+ attributes.remove(--count);
+ strings.remove(count);
+ return;
}
+
+ strings.set(count-1, s.substring(0, s.length() - 1));
}
/**
1.3 +62 -35
xml-batik/sources/org/apache/batik/bridge/svg12/SVGFlowRootElementBridge.java
Index: SVGFlowRootElementBridge.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/bridge/svg12/SVGFlowRootElementBridge.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- SVGFlowRootElementBridge.java 2 Dec 2004 01:24:37 -0000 1.2
+++ SVGFlowRootElementBridge.java 3 Jan 2005 10:48:05 -0000 1.3
@@ -281,10 +281,10 @@
int nextLN = ((Integer)lnIter.next()).intValue();
if (nextLN == prevLN) continue;
+ // System.out.println("Attr: [" + prevLN + "," + nextLN + "]");
ret.addAttribute(FLOW_LINE_BREAK,
new Object(),
prevLN, nextLN);
- // System.out.println("Attr: [" + prevLN + "," + nextLN + "]");
prevLN = nextLN;
}
@@ -359,6 +359,8 @@
}
}
+ protected int startLen;
+
/**
* Fills the given AttributedStringBuffer.
*/
@@ -368,18 +370,24 @@
Integer bidiLevel,
AttributedStringBuffer asb,
List lnLocs) {
- // 'requiredFeatures', 'requiredExtensions' and 'systemLanguage'
- if (!SVGUtilities.matchUserAgent(element, ctx.getUserAgent())) {
+ // 'requiredFeatures', 'requiredExtensions', 'systemLanguage' &
+ // 'display="none".
+ if ((!SVGUtilities.matchUserAgent(element, ctx.getUserAgent())) ||
+ (!CSSUtilities.convertDisplay(element))) {
return;
}
+
String s = XMLSupport.getXMLSpace(element);
boolean preserve = s.equals(SVG_PRESERVE_VALUE);
- boolean first = true;
- boolean last;
- boolean stripFirst = !preserve;
- boolean stripLast = !preserve;
+ boolean prevEndsWithSpace;
Element nodeElement = element;
+ if (top)
+ endLimit = startLen = asb.length();
+
+ if (preserve)
+ endLimit = startLen;
+
Map map = getAttributeMap(ctx, element, null, bidiLevel);
Object o = map.get(TextAttribute.BIDI_EMBEDDING);
Integer subBidiLevel = bidiLevel;
@@ -394,28 +402,33 @@
n != null;
n = n.getNextSibling()) {
- last = n.getNextSibling() == null;
-
- int lastChar = asb.getLastChar();
- stripFirst = (!preserve && first &&
- (lastChar == ' ' || lastChar == -1));
- // Strip spaces at start of para/regionBk
- if (top && first)
- stripFirst = true;
- // Strip spaces after lineBreak.
- if (asb.length() == lineBreak)
- stripFirst = true;
+ if (preserve) {
+ prevEndsWithSpace = false;
+ } else {
+ int len = asb.length();
+ if (len == startLen)
+ prevEndsWithSpace = true;
+ else {
+ prevEndsWithSpace = (asb.getLastChar() == ' ');
+ int idx = lnLocs.size()-1;
+ if (!prevEndsWithSpace && (idx >= 0)) {
+ Integer i = (Integer)lnLocs.get(idx);
+ if (i.intValue() == len)
+ prevEndsWithSpace = true;
+ }
+ }
+ }
switch (n.getNodeType()) {
case Node.ELEMENT_NODE:
// System.out.println("Element: " + n);
- if ((!getNamespaceURI().equals(n.getNamespaceURI())) &&
- (!SVG_NAMESPACE_URI.equals(n.getNamespaceURI()))) {
+ if (!SVG_NAMESPACE_URI.equals(n.getNamespaceURI()))
break;
- }
nodeElement = (Element)n;
+
String ln = n.getLocalName();
+
if (ln.equals(SVG12Constants.SVG_FLOW_LINE_TAG)) {
fillAttributedStringBuffer(ctx, nodeElement,
false, subBidiLevel,
@@ -456,32 +469,46 @@
String uriStr = XLinkSupport.getXLinkHref((Element)n);
Element ref = ctx.getReferencedElement((Element)n,
uriStr);
s = TextUtilities.getElementContent(ref);
- s = normalizeString(s, false, stripFirst, last && top);
+ s = normalizeString(s, preserve, prevEndsWithSpace);
if (s != null) {
- stripLast = !preserve && s.charAt(0) == ' ';
- if (stripLast && !asb.isEmpty()) {
- asb.stripLast();
- }
Map m = getAttributeMap(ctx, nodeElement, null,
bidiLevel);
asb.append(s, m);
}
- }
+ }
break;
case Node.TEXT_NODE:
case Node.CDATA_SECTION_NODE:
s = n.getNodeValue();
- s = normalizeString(s, false, stripFirst, last && top);
- if (s != null) {
- stripLast = !preserve && s.charAt(0) == ' ';
- if (stripLast && !asb.isEmpty()) {
- asb.stripLast();
+ s = normalizeString(s, preserve, prevEndsWithSpace);
+ asb.append(s, map);
+ if (preserve)
+ endLimit = asb.length();
+ }
+ }
+
+ if (top) {
+ while ((endLimit < asb.length()) && (asb.getLastChar() == ' ')) {
+ int idx = lnLocs.size()-1;
+ int len = asb.length();
+ if (idx >= 0) {
+ Integer i = (Integer)lnLocs.get(idx);
+ if (i.intValue() >= len) {
+ i = new Integer(len-1);
+ lnLocs.set(idx, i);
+ idx--;
+ while (idx >= 0) {
+ i = (Integer)lnLocs.get(idx);
+ if (i.intValue() < len-1)
+ break;
+ lnLocs.remove(idx);
+ idx--;
+ }
}
- asb.append(s, map);
}
+ asb.stripLast();
}
- first = false;
}
}
1.2 +34 -28
xml-batik/sources/org/apache/batik/extension/svg/BatikFlowTextElementBridge.java
Index: BatikFlowTextElementBridge.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/extension/svg/BatikFlowTextElementBridge.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- BatikFlowTextElementBridge.java 18 Nov 2004 01:46:58 -0000 1.1
+++ BatikFlowTextElementBridge.java 3 Jan 2005 10:48:05 -0000 1.2
@@ -31,6 +31,7 @@
import org.apache.batik.bridge.Bridge;
import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.BridgeException;
+import org.apache.batik.bridge.CSSUtilities;
import org.apache.batik.bridge.SVGAElementBridge;
import org.apache.batik.bridge.SVGTextElementBridge;
import org.apache.batik.bridge.SVGUtilities;
@@ -530,18 +531,23 @@
Integer bidiLevel,
AttributedStringBuffer asb,
List lnLocs) {
- // 'requiredFeatures', 'requiredExtensions' and 'systemLanguage'
- if (!SVGUtilities.matchUserAgent(element, ctx.getUserAgent())) {
+ // 'requiredFeatures', 'requiredExtensions', 'systemLanguage' &
+ // 'display="none".
+ if ((!SVGUtilities.matchUserAgent(element, ctx.getUserAgent())) ||
+ (!CSSUtilities.convertDisplay(element))) {
return;
}
+
String s = XMLSupport.getXMLSpace(element);
boolean preserve = s.equals(SVG_PRESERVE_VALUE);
- boolean first = true;
- boolean last;
- boolean stripFirst = !preserve;
- boolean stripLast = !preserve;
+ boolean prevEndsWithSpace;
Element nodeElement = element;
+ if (top)
+ endLimit = 0;
+ if (preserve)
+ endLimit = asb.length();
+
Map map = getAttributeMap(ctx, element, null, bidiLevel);
Object o = map.get(TextAttribute.BIDI_EMBEDDING);
Integer subBidiLevel = bidiLevel;
@@ -552,22 +558,26 @@
n != null;
n = n.getNextSibling()) {
- last = n.getNextSibling() == null;
-
- int lastChar = asb.getLastChar();
- stripFirst = !preserve && first &&
- (top || lastChar == ' ' || lastChar == -1);
+ if (preserve) {
+ prevEndsWithSpace = false;
+ } else {
+ if (asb.length() == 0)
+ prevEndsWithSpace = true;
+ else
+ prevEndsWithSpace = (asb.getLastChar() == ' ');
+ }
switch (n.getNodeType()) {
case Node.ELEMENT_NODE:
// System.out.println("Element: " + n);
if ((!getNamespaceURI().equals(n.getNamespaceURI())) &&
- (!SVG_NAMESPACE_URI.equals(n.getNamespaceURI()))) {
+ (!SVG_NAMESPACE_URI.equals(n.getNamespaceURI())))
break;
- }
nodeElement = (Element)n;
+
String ln = n.getLocalName();
+
if (ln.equals(BATIK_EXT_FLOW_LINE_TAG)) {
fillAttributedStringBuffer(ctx, nodeElement,
false, subBidiLevel,
@@ -607,12 +617,8 @@
String uriStr = XLinkSupport.getXLinkHref((Element)n);
Element ref = ctx.getReferencedElement((Element)n,
uriStr);
s = TextUtilities.getElementContent(ref);
- s = normalizeString(s, preserve, stripFirst, last &&
top);
+ s = normalizeString(s, preserve, prevEndsWithSpace);
if (s != null) {
- stripLast = !preserve && s.charAt(0) == ' ';
- if (stripLast && !asb.isEmpty()) {
- asb.stripLast();
- }
Map m = getAttributeMap(ctx, nodeElement, null,
bidiLevel);
asb.append(s, m);
@@ -623,16 +629,16 @@
case Node.TEXT_NODE:
case Node.CDATA_SECTION_NODE:
s = n.getNodeValue();
- s = normalizeString(s, preserve, stripFirst, last && top);
- if (s != null) {
- stripLast = !preserve && s.charAt(0) == ' ';
- if (stripLast && !asb.isEmpty()) {
- asb.stripLast();
- }
- asb.append(s, map);
- }
+ s = normalizeString(s, preserve, prevEndsWithSpace);
+ asb.append(s, map);
+ if (preserve)
+ endLimit = asb.length();
}
- first = false;
+ }
+
+ if (top) {
+ while ((endLimit < asb.length()) && (asb.getLastChar() == ' '))
+ asb.stripLast();
}
}
1.4 +2 -1
xml-batik/sources/org/apache/batik/gvt/flow/FlowGlyphLayout.java
Index: FlowGlyphLayout.java
===================================================================
RCS file:
/home/cvs/xml-batik/sources/org/apache/batik/gvt/flow/FlowGlyphLayout.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- FlowGlyphLayout.java 4 Dec 2004 18:40:45 -0000 1.3
+++ FlowGlyphLayout.java 3 Jan 2005 10:48:05 -0000 1.4
@@ -100,6 +100,7 @@
prevBotMargin = bi.getBottomMargin();
numWords += wordInfos[chunk].length;
}
+
Iterator frIter = flowRects.iterator();
RegionInfo currentRegion = null;
int currWord = 0;
1.7 +84 -81
xml-batik/test-references/samples/tests/spec/linking/anchor.png
<<Binary file>>
1.4 +78 -97
xml-batik/test-references/samples/tests/spec/linking/anchorInsideText.png
<<Binary file>>
1.6 +47 -40
xml-batik/test-references/samples/tests/spec/linking/pointerEvents.png
<<Binary file>>
1.6 +119 -103
xml-batik/test-references/samples/tests/spec/linking/pointerEvents2.png
<<Binary file>>
1.7 +103 -88
xml-batik/test-references/samples/tests/spec/structure/symbolViewBoxClip.png
<<Binary file>>
1.7 +190 -189
xml-batik/test-references/samples/tests/spec/structure/symbolViewBoxOverflow.png
<<Binary file>>
1.7 +102 -95
xml-batik/test-references/samples/tests/spec/structure/toolTips.png
<<Binary file>>
1.12 +138 -124
xml-batik/test-references/samples/tests/spec/text/smallFonts.png
<<Binary file>>
1.1
xml-batik/test-references/samples/tests/spec/text/xmlSpace.png
<<Binary file>>
1.2 +131 -131
xml-batik/test-references/samples/tests/spec12/text/flowText2.png
<<Binary file>>
1.124 +4 -1
xml-batik/test-resources/org/apache/batik/test/samplesRendering.xml
Index: samplesRendering.xml
===================================================================
RCS file:
/home/cvs/xml-batik/test-resources/org/apache/batik/test/samplesRendering.xml,v
retrieving revision 1.123
retrieving revision 1.124
diff -u -r1.123 -r1.124
--- samplesRendering.xml 4 Dec 2004 18:40:45 -0000 1.123
+++ samplesRendering.xml 3 Jan 2005 10:48:06 -0000 1.124
@@ -350,6 +350,9 @@
<test id="samples/tests/spec/text/textPosition.svg" />
<test id="samples/tests/spec/text/textPosition2.svg" />
<test
id="samples/tests/spec/text/textGlyphOrientationHorizontal.svg"/>
+ <test id="samples/tests/spec/text/xmlSpace.svg">
+ <property name="Validating" class="java.lang.Boolean"
value="false" />
+ </test>
</testGroup>
<testGroup id="tests.spec.scripting">
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]