소스 검색

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
tags/fop-0_90-alpha1
Luca Furini 18 년 전
부모
커밋
5cdaf10f11

+ 1
- 1
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

+ 62
- 0
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;
}
}

+ 42
- 8
src/java/org/apache/fop/area/inline/TextArea.java 파일 보기

@@ -18,16 +18,13 @@

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
*/
@@ -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();
}

/**

+ 2
- 1
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

+ 62
- 0
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;
}
}

+ 1
- 1
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);

+ 1
- 1
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;

+ 2
- 2
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

+ 3
- 1
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());

+ 31
- 4
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();
}

/**

+ 62
- 11
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);
}
/**

+ 27
- 2
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);
}

/**

Loading…
취소
저장