package org.apache.fop.layoutmgr;
+import java.util.LinkedList;
import java.util.List;
+import org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager;
+import org.apache.fop.layoutmgr.inline.KnuthInlineBox;
+
/**
*
if (!canAppendSequence(sequence)) {
return false;
}
+ // does the first element of the first paragraph add to an existing word?
+ KnuthElement lastOldElement, firstNewElement;
+ lastOldElement = getLast();
+ firstNewElement = sequence.getElement(0);
+ if (firstNewElement.isBox() && !firstNewElement.isAuxiliary()
+ && lastOldElement.isBox() && lastOldElement.getW() != 0) {
+ addALetterSpace();
+ }
addAll(sequence);
return true;
}
return this;
}
+ public void addALetterSpace() {
+ KnuthBox prevBox = (KnuthBox) removeLast();
+ LinkedList oldList = new LinkedList();
+ // if there are two consecutive KnuthBoxes the
+ // first one does not represent a whole word,
+ // so it must be given one more letter space
+ if (!prevBox.isAuxiliary()) {
+ // if letter spacing is constant,
+ // only prevBox needs to be replaced;
+ oldList.add(prevBox);
+ } else {
+ // prevBox is the last element
+ // in the sub-sequence
+ // <box> <aux penalty> <aux glue> <aux box>
+ // the letter space is added to <aux glue>,
+ // while the other elements are not changed
+ oldList.add(prevBox);
+ oldList.addFirst((KnuthGlue) removeLast());
+ oldList.addFirst((KnuthPenalty) removeLast());
+ oldList.addFirst((KnuthBox) removeLast());
+ }
+ // adding a letter space could involve, according to the text
+ // represented by oldList, replacing a glue element or adding
+ // new elements
+ addAll(((InlineLevelLayoutManager)
+ prevBox.getLayoutManager())
+ .addALetterSpaceTo(oldList));
+ if (((KnuthInlineBox) prevBox).isAnchor()) {
+ // prevBox represents a footnote citation: copy footnote info
+ // from prevBox to the new box
+ KnuthInlineBox newBox = (KnuthInlineBox) getLast();
+ newBox.setFootnoteBodyLM(((KnuthInlineBox) prevBox).getFootnoteBodyLM());
+ }
+ }
+
}
}
}
- private void addALetterSpace() {
- KnuthBox prevBox = (KnuthBox) removeLast();
- LinkedList oldList = new LinkedList();
- // if there are two consecutive KnuthBoxes the
- // first one does not represent a whole word,
- // so it must be given one more letter space
- if (!prevBox.isAuxiliary()) {
- // if letter spacing is constant,
- // only prevBox needs to be replaced;
- oldList.add(prevBox);
- } else {
- // prevBox is the last element
- // in the sub-sequence
- // <box> <aux penalty> <aux glue> <aux box>
- // the letter space is added to <aux glue>,
- // while the other elements are not changed
- oldList.add(prevBox);
- oldList.addFirst((KnuthGlue) removeLast());
- oldList.addFirst((KnuthPenalty) removeLast());
- oldList.addFirst((KnuthBox) removeLast());
- }
- // adding a letter space could involve, according to the text
- // represented by oldList, replacing a glue element or adding
- // new elements
- addAll(((InlineLevelLayoutManager)
- prevBox.getLayoutManager())
- .addALetterSpaceTo(oldList));
- if (((KnuthInlineBox) prevBox).isAnchor()) {
- // prevBox represents a footnote citation: copy footnote info
- // from prevBox to the new box
- KnuthInlineBox newBox = (KnuthInlineBox) getLast();
- newBox.setFootnoteBodyLM(((KnuthInlineBox) prevBox).getFootnoteBodyLM());
- }
- }
}
private class LineBreakingAlgorithm extends BreakingAlgorithm {
--- /dev/null
+<?xml version="1.0" encoding="iso-8859-1"?>
+
+<testcase>
+ <info>
+ <p>
+ This test checks whether letterspacing is applied between across
+ fo:inline elements in the same word.
+ </p>
+ </info>
+ <fo>
+ <fo:root
+ xmlns:fo="http://www.w3.org/1999/XSL/Format"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <fo:layout-master-set>
+ <fo:simple-page-master master-name="simpleA4"
+ page-height="5cm" page-width="15cm"
+ margin-top="2cm" margin-bottom="2cm"
+ margin-left="2cm" margin-right="2cm">
+ <fo:region-body/>
+ </fo:simple-page-master>
+ </fo:layout-master-set>
+
+ <fo:page-sequence master-reference="simpleA4">
+ <fo:flow flow-name="xsl-region-body">
+ <fo:block language="en" country="US">
+ <fo:inline letter-spacing="2pt"><fo:inline>nor</fo:inline><fo:inline>mal</fo:inline></fo:inline>
+ </fo:block>
+ </fo:flow>
+ </fo:page-sequence>
+ </fo:root>
+ </fo>
+ <checks>
+ <eval expected="46672"
+xpath="//flow/block[1]/lineArea[1]/inlineparent[1]/@ipd" desc="IPD of
+containing inline area"/>
+ <eval expected="23340"
+xpath="//flow/block[1]/lineArea[1]/inlineparent[1]/inlineparent[1]/@ipd"
+desc="IPD of first contained inline area"/>
+ <eval expected="23340"
+xpath="//flow/block[1]/lineArea[1]/inlineparent[1]/inlineparent[1]/text/@ipd"
+desc="IPD of corresponding text area"/>
+ </checks>
+</testcase>