diff options
author | Luca Furini <lfurini@apache.org> | 2005-10-25 15:14:10 +0000 |
---|---|---|
committer | Luca Furini <lfurini@apache.org> | 2005-10-25 15:14:10 +0000 |
commit | 5cdaf10f11c193c2a2b833d2ea37a914764c665a (patch) | |
tree | cc275f275b5f3eb1085cf619deb8ddde9b43a0d7 /src | |
parent | 1cb5e8113f4eafa673ab1adbf63510ac1833cb87 (diff) | |
download | xmlgraphics-fop-5cdaf10f11c193c2a2b833d2ea37a914764c665a.tar.gz xmlgraphics-fop-5cdaf10f11c193c2a2b833d2ea37a914764c665a.zip |
Fix for bug 36238 (at least in the PDFRenderer)
The text is split into WordAreas and SpaceAreas: the latters (when the font is multibyte) are not affected by the Tw operator, so they are shifted in the inline progression dimension instead.
The behaviour of the other renderers should be the same as before this change.
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@328381 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'src')
12 files changed, 296 insertions, 32 deletions
diff --git a/src/java/org/apache/fop/area/inline/AbstractTextArea.java b/src/java/org/apache/fop/area/inline/AbstractTextArea.java index a50500979..200b3e568 100644 --- a/src/java/org/apache/fop/area/inline/AbstractTextArea.java +++ b/src/java/org/apache/fop/area/inline/AbstractTextArea.java @@ -21,7 +21,7 @@ package org.apache.fop.area.inline; /** * Abstract base class for both TextArea and Character. */ -public abstract class AbstractTextArea extends InlineArea { +public abstract class AbstractTextArea extends InlineParent { /** * this class stores information about spaces and potential adjustments diff --git a/src/java/org/apache/fop/area/inline/SpaceArea.java b/src/java/org/apache/fop/area/inline/SpaceArea.java new file mode 100644 index 000000000..1b5a1ae6e --- /dev/null +++ b/src/java/org/apache/fop/area/inline/SpaceArea.java @@ -0,0 +1,62 @@ +/*
+ * Copyright 2004-2005 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.
+ */
+
+/* $Id$ */
+package org.apache.fop.area.inline;
+
+/**
+ * A space
+ */
+public class SpaceArea extends InlineArea {
+
+ /**
+ * The space for this space area
+ */
+ protected String space;
+
+ /**
+ * The correction offset for the next area
+ */
+ protected int offset = 0;
+
+ /**
+ * Create a text inline area
+ * @param s the space character
+ */
+ public SpaceArea(char s) {
+ space = new String() + s;
+ }
+
+ /**
+ * @return Returns the space.
+ */
+ public String getSpace() {
+ return new String(space);
+ }
+
+ /**
+ * @return Returns the offset.
+ */
+ public int getOffset() {
+ return offset;
+ }
+ /**
+ * @param o The offset to set.
+ */
+ public void setOffset(int o) {
+ offset = o;
+ }
+}
diff --git a/src/java/org/apache/fop/area/inline/TextArea.java b/src/java/org/apache/fop/area/inline/TextArea.java index 5f58f989b..d57171e8a 100644 --- a/src/java/org/apache/fop/area/inline/TextArea.java +++ b/src/java/org/apache/fop/area/inline/TextArea.java @@ -18,17 +18,14 @@ package org.apache.fop.area.inline; +import org.apache.fop.util.CharUtilities; + /** * A text inline area. */ public class TextArea extends AbstractTextArea { /** - * The text for this inline area - */ - protected String text; - - /** * Create a text inline area */ public TextArea() { @@ -50,8 +47,34 @@ public class TextArea extends AbstractTextArea { * * @param t the text string */ - public void setTextArea(String t) { - text = t; + public void setText(String t) { + // split the text and create WordAreas and SpaceAreas + char charArray[] = t.toCharArray(); + int wordStartIndex = -1; + for (int i = 0; i < charArray.length; i ++) { + if (CharUtilities.isAnySpace(charArray[i])) { + // a space character + // create a SpaceArea child + SpaceArea space = new SpaceArea(charArray[i]); + this.addChildArea(space); + space.setParentArea(this); + } else { + // a non-space character + if (wordStartIndex == -1) { + // first character of the text, or after a space + wordStartIndex = i; + } + if (i == charArray.length - 1 + || CharUtilities.isAnySpace(charArray[i + 1])) { + // last character before the end of the text or a space: + // create a WordArea child + WordArea word = new WordArea(t.substring(wordStartIndex, i + 1)); + this.addChildArea(word); + word.setParentArea(this); + wordStartIndex = -1; + } + } + } } /** @@ -60,7 +83,18 @@ public class TextArea extends AbstractTextArea { * @return the text string */ public String getTextArea() { - return text; + StringBuffer text = new StringBuffer(); + InlineArea child; + // assemble the text + for (int i = 0; i < inlines.size(); i ++) { + child = (InlineArea) inlines.get(i); + if (child instanceof WordArea) { + text.append(((WordArea) child).getWord()); + } else { + text.append(((SpaceArea) child).getSpace()); + } + } + return text.toString(); } /** diff --git a/src/java/org/apache/fop/area/inline/UnresolvedPageNumber.java b/src/java/org/apache/fop/area/inline/UnresolvedPageNumber.java index 3d2d44689..0b429b665 100644 --- a/src/java/org/apache/fop/area/inline/UnresolvedPageNumber.java +++ b/src/java/org/apache/fop/area/inline/UnresolvedPageNumber.java @@ -33,6 +33,7 @@ public class UnresolvedPageNumber extends TextArea implements Resolvable { private boolean resolved = false; private String pageIDRef; private Font font; + private String text; /** * Create a new unresolvable page number. @@ -69,7 +70,7 @@ public class UnresolvedPageNumber extends TextArea implements Resolvable { if (pageIDRef.equals(id) && pages != null) { resolved = true; PageViewport page = (PageViewport)pages.get(0); - setTextArea(page.getPageNumberString()); + setText(page.getPageNumberString()); // update ipd updateIPD(getStringWidth(text)); // set the Font object to null, as we don't need it any more diff --git a/src/java/org/apache/fop/area/inline/WordArea.java b/src/java/org/apache/fop/area/inline/WordArea.java new file mode 100644 index 000000000..c766e0e62 --- /dev/null +++ b/src/java/org/apache/fop/area/inline/WordArea.java @@ -0,0 +1,62 @@ +/*
+ * Copyright 2004-2005 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.
+ */
+
+/* $Id$ */
+package org.apache.fop.area.inline;
+
+/**
+ * A string of characters without spaces
+ */
+public class WordArea extends InlineArea {
+
+ /**
+ * The text for this word area
+ */
+ protected String word;
+
+ /**
+ * The correction offset for the next area
+ */
+ protected int offset = 0;
+
+ /**
+ * Create a text inline area
+ * @param w the word string
+ */
+ public WordArea(String w) {
+ word = w;
+ }
+
+ /**
+ * @return Returns the word.
+ */
+ public String getWord() {
+ return word;
+ }
+
+ /**
+ * @return Returns the offset.
+ */
+ public int getOffset() {
+ return offset;
+ }
+ /**
+ * @param o The offset to set.
+ */
+ public void setOffset(int o) {
+ offset = o;
+ }
+}
diff --git a/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java index 162397217..502d3ed6f 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/LeaderLayoutManager.java @@ -129,7 +129,7 @@ public class LeaderLayoutManager extends LeafNodeLayoutManager { char dot = '.'; // userAgent.getLeaderDotCharacter(); int width = font.getCharWidth(dot); - t.setTextArea("" + dot); + t.setText("" + dot); t.setIPD(width); t.setBPD(width); t.setBaselineOffset(width); diff --git a/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java index 083d7838f..9badf6986 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/PageNumberCitationLayoutManager.java @@ -110,7 +110,7 @@ public class PageNumberCitationLayoutManager extends LeafNodeLayoutManager { TextArea text = new TextArea(); inline = text; int width = getStringWidth(str); - text.setTextArea(str); + text.setText(str); inline.setIPD(width); resolved = true; diff --git a/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java index d6cc739f2..2cabaa8a3 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/PageNumberLayoutManager.java @@ -75,7 +75,7 @@ public class PageNumberLayoutManager extends LeafNodeLayoutManager { TextArea text = new TextArea(); String str = getCurrentPV().getPageNumberString(); int width = getStringWidth(str); - text.setTextArea(str); + text.setText(str); text.setIPD(width); text.setBPD(font.getAscender() - font.getDescender()); text.setBaselineOffset(font.getAscender()); @@ -114,7 +114,7 @@ public class PageNumberLayoutManager extends LeafNodeLayoutManager { private void updateContent(TextArea area) { // get the page number of the page actually being built - area.setTextArea(getCurrentPV().getPageNumberString()); + area.setText(getCurrentPV().getPageNumberString()); // update the ipd of the area area.updateIPD(getStringWidth(area.getTextArea())); // update the width stored in the AreaInfo object diff --git a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java index 2ab8fd1a8..1755dd4fd 100644 --- a/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java +++ b/src/java/org/apache/fop/layoutmgr/inline/TextLayoutManager.java @@ -393,6 +393,8 @@ public class TextLayoutManager extends LeafNodeLayoutManager { * @param adjust the total ipd adjustment with respect to the optimal width * @param context the layout context * @param spaceDiff unused + * @param firstIndex the index of the first AreaInfo used for the TextArea + * @param lastIndex the index of the last AreaInfo used for the TextArea * @return the new text area */ protected TextArea createTextArea(String str, MinOptMax width, int adjust, @@ -417,7 +419,7 @@ public class TextLayoutManager extends LeafNodeLayoutManager { textArea.setOffset(alignmentContext.getOffset()); } - textArea.setTextArea(str); + textArea.setText(str); textArea.addTrait(Trait.FONT_NAME, font.getFontName()); textArea.addTrait(Trait.FONT_SIZE, new Integer(font.getFontSize())); textArea.addTrait(Trait.COLOR, foText.getColor()); diff --git a/src/java/org/apache/fop/render/AbstractRenderer.java b/src/java/org/apache/fop/render/AbstractRenderer.java index ab2fc8588..0335c2089 100644 --- a/src/java/org/apache/fop/render/AbstractRenderer.java +++ b/src/java/org/apache/fop/render/AbstractRenderer.java @@ -59,6 +59,8 @@ import org.apache.fop.area.inline.Space; import org.apache.fop.area.inline.Viewport; import org.apache.fop.area.inline.TextArea; import org.apache.fop.area.inline.Character; +import org.apache.fop.area.inline.WordArea; +import org.apache.fop.area.inline.SpaceArea; import org.apache.fop.apps.FOUserAgent; import org.apache.fop.fo.Constants; import org.apache.fop.fonts.FontInfo; @@ -587,14 +589,18 @@ public abstract class AbstractRenderer protected void renderInlineArea(InlineArea inlineArea) { if (inlineArea instanceof TextArea) { renderText((TextArea) inlineArea); + } else if (inlineArea instanceof Character) { + renderCharacter((Character) inlineArea); + } else if (inlineArea instanceof WordArea) { + renderWord((WordArea) inlineArea); + } else if (inlineArea instanceof SpaceArea) { + renderSpace((SpaceArea) inlineArea); } else if (inlineArea instanceof InlineParent) { renderInlineParent((InlineParent) inlineArea); } else if (inlineArea instanceof InlineBlockParent) { renderInlineBlockParent((InlineBlockParent) inlineArea); } else if (inlineArea instanceof Space) { renderInlineSpace((Space) inlineArea); - } else if (inlineArea instanceof Character) { - renderCharacter((Character) inlineArea); } else if (inlineArea instanceof Viewport) { renderViewport((Viewport) inlineArea); } else if (inlineArea instanceof Leader) { @@ -602,7 +608,6 @@ public abstract class AbstractRenderer } } - /** * Render the given Character. * @param ch the character to render @@ -636,7 +641,29 @@ public abstract class AbstractRenderer * @param text the text to render */ protected void renderText(TextArea text) { - currentIPPosition += text.getAllocIPD(); + int saveIP = currentIPPosition; + int saveBP = currentBPPosition; + Iterator iter = text.getChildAreas().iterator(); + while (iter.hasNext()) { + renderInlineArea((InlineArea) iter.next()); + } + currentIPPosition = saveIP + text.getAllocIPD(); + } + + /** + * Render the given WordArea. + * @param word the word to render + */ + protected void renderWord(WordArea word) { + currentIPPosition += word.getAllocIPD(); + } + + /** + * Render the given SpaceArea. + * @param space the space to render + */ + protected void renderSpace(SpaceArea space) { + currentIPPosition += space.getAllocIPD(); } /** diff --git a/src/java/org/apache/fop/render/pdf/PDFRenderer.java b/src/java/org/apache/fop/render/pdf/PDFRenderer.java index 70beb20fb..69a96f432 100644 --- a/src/java/org/apache/fop/render/pdf/PDFRenderer.java +++ b/src/java/org/apache/fop/render/pdf/PDFRenderer.java @@ -52,6 +52,8 @@ import org.apache.fop.area.inline.ForeignObject; import org.apache.fop.area.inline.Image; import org.apache.fop.area.inline.Leader; import org.apache.fop.area.inline.InlineParent; +import org.apache.fop.area.inline.WordArea; +import org.apache.fop.area.inline.SpaceArea; import org.apache.fop.datatypes.ColorType; import org.apache.fop.fonts.Typeface; import org.apache.fop.fonts.Font; @@ -1095,11 +1097,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { // This assumes that *all* CIDFonts use a /ToUnicode mapping Typeface tf = (Typeface) fontInfo.getFonts().get(name); boolean useMultiByte = tf.isMultiByte(); - - // String startText = useMultiByte ? "<FEFF" : "("; - String startText = useMultiByte ? "<" : "("; - String endText = useMultiByte ? "> " : ") "; - + updateFont(name, size, pdf); ColorType ct = (ColorType) text.getTrait(Trait.COLOR); updateColor(ct, true, pdf); @@ -1125,7 +1123,7 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { pdf.append("1 0 0 -1 " + (rx / 1000f) + " " + (bl / 1000f) + " Tm " + (text.getTextLetterSpaceAdjust() / 1000f) + " Tc " - + (text.getTextWordSpaceAdjust() / 1000f) + " Tw [" + startText); + + (text.getTextWordSpaceAdjust() / 1000f) + " Tw ["); prevWordY = bl; textOpen = true; } else { @@ -1133,24 +1131,77 @@ public class PDFRenderer extends AbstractPathOrientedRenderer { pdf.append("1 0 0 -1 " + (rx / 1000f) + " " + (bl / 1000f) + " Tm " + (text.getTextLetterSpaceAdjust() / 1000f) + " Tc " - + (text.getTextWordSpaceAdjust() / 1000f) + " Tw [" + startText); + + (text.getTextWordSpaceAdjust() / 1000f) + " Tw ["); textOpen = true; } prevWordWidth = text.getIPD(); prevWordX = rx; - String s = text.getTextArea(); + currentStream.add(pdf.toString()); + renderTextDecoration(tf, size, text, bl, rx); + + super.renderText(text); + } + + /** + * @see org.apache.fop.render.AbstractRenderer#renderWord(WordArea) + */ + public void renderWord(WordArea word) { + String name = (String) word.getParentArea().getTrait(Trait.FONT_NAME); + int size = ((Integer) word.getParentArea().getTrait(Trait.FONT_SIZE)).intValue(); + Typeface tf = (Typeface) fontInfo.getFonts().get(name); + boolean useMultiByte = tf.isMultiByte(); + + String startText = useMultiByte ? "<" : "("; + String endText = useMultiByte ? "> " : ") "; + + StringBuffer pdf = new StringBuffer(); + + pdf.append(startText); + + String s = word.getWord(); + FontMetrics metrics = fontInfo.getMetricsFor(name); Font fs = new Font(name, metrics, size); escapeText(s, fs, useMultiByte, pdf); pdf.append(endText); - + currentStream.add(pdf.toString()); - renderTextDecoration(tf, size, text, bl, rx); + super.renderWord(word); + } + + /** + * @see org.apache.fop.render.AbstractRenderer#renderSpace(SpaceArea) + */ + public void renderSpace(SpaceArea space) { + String name = (String) space.getParentArea().getTrait(Trait.FONT_NAME); + int size = ((Integer) space.getParentArea().getTrait(Trait.FONT_SIZE)).intValue(); + Typeface tf = (Typeface) fontInfo.getFonts().get(name); + boolean useMultiByte = tf.isMultiByte(); + + String startText = useMultiByte ? "<" : "("; + String endText = useMultiByte ? "> " : ") "; - super.renderText(text); + StringBuffer pdf = new StringBuffer(); + + pdf.append(startText); + + String s = space.getSpace(); + + FontMetrics metrics = fontInfo.getMetricsFor(name); + Font fs = new Font(name, metrics, size); + escapeText(s, fs, useMultiByte, pdf); + pdf.append(endText); + + if (useMultiByte) { + pdf.append(-(((TextArea) space.getParentArea()).getTextWordSpaceAdjust() / (size / 1000)) + " "); + } + + currentStream.add(pdf.toString()); + + super.renderSpace(space); } /** diff --git a/src/java/org/apache/fop/render/xml/XMLRenderer.java b/src/java/org/apache/fop/render/xml/XMLRenderer.java index 71d47df40..da3260d54 100644 --- a/src/java/org/apache/fop/render/xml/XMLRenderer.java +++ b/src/java/org/apache/fop/render/xml/XMLRenderer.java @@ -66,6 +66,8 @@ import org.apache.fop.area.inline.Leader; import org.apache.fop.area.inline.Space; import org.apache.fop.area.inline.Viewport; import org.apache.fop.area.inline.TextArea; +import org.apache.fop.area.inline.SpaceArea; +import org.apache.fop.area.inline.WordArea; /** * Renderer that renders areas to XML for debugging purposes. @@ -613,9 +615,32 @@ public class XMLRenderer extends PrintRenderer { addAreaAttributes(text); addTraitAttributes(text); startElement("text", atts); - characters(text.getTextArea()); - endElement("text"); super.renderText(text); + endElement("text"); + } + + /** + * @see org.apache.fop.render.AbstractRenderer#renderWord(WordArea) + */ + protected void renderWord(WordArea word) { + atts.clear(); + addAttribute("offset", word.getOffset()); + startElement("word", atts); + characters(word.getWord()); + endElement("word"); + super.renderWord(word); + } + + /** + * @see org.apache.fop.render.AbstractRenderer#renderSpace(SpaceArea) + */ + protected void renderSpace(SpaceArea space) { + atts.clear(); + addAttribute("offset", space.getOffset()); + startElement("space", atts); + characters(space.getSpace()); + endElement("space"); + super.renderSpace(space); } /** |