}
}
- public class BlockSequence extends KnuthSequence {
+ public class BlockSequence extends BlockKnuthSequence {
+
+ /** Number of elements to ignore at the beginning of the list. */
+ public int ignoreAtStart = 0;
+ /** Number of elements to ignore at the end of the list. */
+ public int ignoreAtEnd = 0;
/**
* startOn represents where on the page/which page layout
return this.startOn;
}
+ /**
+ * Finalizes a Knuth sequence.
+ * @return a finalized sequence.
+ */
+ public KnuthSequence endSequence() {
+ return endSequence(null);
+ }
+
+ /**
+ * Finalizes a Knuth sequence.
+ * @param breakPosition a Position instance for the last penalty (may be null)
+ * @return a finalized sequence.
+ */
+ public KnuthSequence endSequence(Position breakPosition) {
+ // remove glue and penalty item at the end of the paragraph
+ while (this.size() > ignoreAtStart
+ && !((KnuthElement)this.get(this.size() - 1)).isBox()) {
+ this.remove(this.size() - 1);
+ }
+ if (this.size() > ignoreAtStart) {
+ // add the elements representing the space at the end of the last line
+ // and the forced break
+ this.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, null, false));
+ this.add(new KnuthGlue(0, 10000000, 0, null, false));
+ this.add(new KnuthPenalty(0, -KnuthElement.INFINITE, false, breakPosition, false));
+ ignoreAtEnd = 3;
+ return this;
+ } else {
+ this.clear();
+ return null;
+ }
+ }
+
public BlockSequence endBlockSequence(Position breakPosition) {
- KnuthSequence temp = super.endSequence(breakPosition);
+ KnuthSequence temp = endSequence(breakPosition);
if (temp != null) {
BlockSequence returnSequence = new BlockSequence(startOn);
returnSequence.addAll(temp);
* @param pos the Position
* @return the same Position but with a position index
*/
- protected Position notifyPos(Position pos) {
+ public Position notifyPos(Position pos) {
if (pos.getIndex() >= 0) {
throw new IllegalStateException("Position already got its index");
}
--- /dev/null
+/*
+ * Copyright 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.layoutmgr;
+
+import java.util.List;
+
+
+/**
+ * Represents a list of block level Knuth elements.
+ */
+public class BlockKnuthSequence extends KnuthSequence {
+
+ private boolean isClosed = false;
+
+ /**
+ * Creates a new and empty list.
+ */
+ public BlockKnuthSequence() {
+ super();
+ }
+
+ /**
+ * Creates a new list from an existing list.
+ * @param list The list from which to create the new list.
+ */
+ public BlockKnuthSequence(List list) {
+ super(list);
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.fop.layoutmgr.KnuthList#isInlineSequence()
+ */
+ public boolean isInlineSequence() {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.fop.layoutmgr.KnuthList#canAppendSequence(org.apache.fop.layoutmgr.KnuthSequence)
+ */
+ public boolean canAppendSequence(KnuthSequence sequence) {
+ return !sequence.isInlineSequence() && !isClosed;
+ }
+
+ /**
+ * this and sequence are supposed to belong to the same LayoutManager,
+ * which is stored in the positions of the elements in the sequences
+ * @param sequence The sequence following this
+ * @return whether this and the following sequence must be kept together
+ */
+ private boolean mustKeepWithNext(BlockKnuthSequence sequence) {
+/* // TODO read keep together correctly
+ // for now, return false
+ return BlockKnuthSequence.mustKeepTogether(this, sequence);
+*/ return false;
+ }
+
+ /**
+ * the two sequences are supposed to belong to the same LayoutManager,
+ * which is stored in the positions of the elements in the sequences
+ * @param sequence1 The leading sequence
+ * @param sequence2 The following sequence
+ * @return whether the two sequences must be kept together
+ */
+ public static boolean mustKeepTogether(BlockKnuthSequence sequence1,
+ BlockKnuthSequence sequence2) {
+ KnuthElement element1 = (KnuthElement) sequence1.get(sequence1.size() - 1);
+ LayoutManager lm1 = (LayoutManager) element1.getLayoutManager();
+ KnuthElement element2 = (KnuthElement) sequence2.get(0);
+ LayoutManager lm2 = (LayoutManager) element2.getLayoutManager();
+ if (!lm1.equals(lm2)) {
+ throw new IllegalStateException
+ ("The two sequences must belong to the same LayoutManager");
+ }
+ if (lm1 instanceof BlockLevelLayoutManager
+ && ((BlockLevelLayoutManager) lm1).mustKeepTogether()) {
+ return true;
+ }
+ Position pos1 = element1.getPosition();
+ if (pos1 != null) {
+ pos1 = pos1.getPosition();
+ if (pos1 != null) {
+ lm1 = pos1.getLM();
+ if (lm1 instanceof BlockLevelLayoutManager
+ && ((BlockLevelLayoutManager) lm1).mustKeepWithNext()) {
+ return true;
+ }
+ }
+ }
+ Position pos2 = element1.getPosition();
+ if (pos2 != null) {
+ pos2 = pos2.getPosition();
+ if (pos2 != null) {
+ lm2 = pos2.getLM();
+ if (lm2 instanceof BlockLevelLayoutManager
+ && ((BlockLevelLayoutManager) lm2).mustKeepWithPrevious()) {
+ return true;
+ }
+ }
+ }
+ return false;
+/* From BlockStackingLM.getChangedKnuthElements
+ // there is another block after this one
+ if (bSomethingAdded
+ && (this.mustKeepTogether()
+ || prevLM.mustKeepWithNext()
+ || currLM.mustKeepWithPrevious())) {
+ // add an infinite penalty to forbid a break between blocks
+ returnedList.add(new KnuthPenalty(0, KnuthElement.INFINITE, false,
+ new Position(this), false));
+ } else if (bSomethingAdded && !((KnuthElement) returnedList.getLast()).isGlue()) {
+ // add a null penalty to allow a break between blocks
+ returnedList.add(new KnuthPenalty(0, 0, false, new Position(this), false));
+ }
+*/ }
+
+ /* (non-Javadoc)
+ * @see org.apache.fop.layoutmgr.KnuthList#appendSequence(org.apache.fop.layoutmgr.KnuthSequence, org.apache.fop.layoutmgr.LayoutManager)
+ */
+ /**
+ * this and sequence are supposed to belong to the same LayoutManager,
+ * which is stored in the positions of the elements in the sequences
+ */
+ public boolean appendSequence(KnuthSequence sequence, LayoutManager lm) {
+ if (!canAppendSequence(sequence)) {
+ return false;
+ }
+/* // TODO disable because InlineLM.addAreas expects only NonLeafPostions; why?
+ if (!mustKeepWithNext((BlockKnuthSequence) sequence)) {
+ add(new KnuthPenalty(0, 0, false, new Position(lm), false));
+ }
+*/ addAll(sequence);
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.fop.layoutmgr.KnuthList#appendSequenceOrClose(org.apache.fop.layoutmgr.KnuthSequence, org.apache.fop.layoutmgr.LayoutManager)
+ */
+ public boolean appendSequenceOrClose(KnuthSequence sequence, LayoutManager lm) {
+ if (!appendSequence(sequence, lm)) {
+ endSequence();
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.fop.layoutmgr.KnuthSequence#endSequence()
+ */
+ public KnuthSequence endSequence() {
+ isClosed = true;
+ return this;
+ }
+
+}
--- /dev/null
+/*
+ * Copyright 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.layoutmgr;
+
+import java.util.List;
+
+
+/**
+ *
+ */
+public class InlineKnuthSequence extends KnuthSequence {
+
+ private boolean isClosed = false;
+
+ /**
+ * Creates a new and empty list.
+ */
+ public InlineKnuthSequence() {
+ super();
+ }
+
+ /**
+ * Creates a new list from an existing list.
+ * @param list The list from which to create the new list.
+ */
+ public InlineKnuthSequence(List list) {
+ super(list);
+ }
+
+ /**
+ * Is this an inline or a block sequence?
+ * @return false
+ */
+ public boolean isInlineSequence() {
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.fop.layoutmgr.KnuthSequence#canAppendSequence(org.apache.fop.layoutmgr.KnuthSequence)
+ */
+ public boolean canAppendSequence(KnuthSequence sequence) {
+ return sequence.isInlineSequence() && !isClosed;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.fop.layoutmgr.KnuthSequence#appendSequence(org.apache.fop.layoutmgr.KnuthSequence, org.apache.fop.layoutmgr.LayoutManager)
+ */
+ public boolean appendSequence(KnuthSequence sequence, LayoutManager lm) {
+ if (!canAppendSequence(sequence)) {
+ return false;
+ }
+ addAll(sequence);
+ return true;
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.fop.layoutmgr.KnuthSequence#appendSequenceOrClose(org.apache.fop.layoutmgr.KnuthSequence, org.apache.fop.layoutmgr.LayoutManager)
+ */
+ public boolean appendSequenceOrClose(KnuthSequence sequence, LayoutManager lm) {
+ if (!appendSequence(sequence, lm)) {
+ endSequence();
+ return false;
+ } else {
+ return true;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.apache.fop.layoutmgr.KnuthSequence#endSequence()
+ */
+ public KnuthSequence endSequence() {
+ if (!isClosed) {
+ add(new KnuthPenalty(0, -KnuthElement.INFINITE, false, null, false));
+ isClosed = true;
+ }
+ return this;
+ }
+
+}
package org.apache.fop.layoutmgr;
import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
/**
* Represents a list of Knuth elements.
*/
-public class KnuthSequence extends ArrayList {
- /** Number of elements to ignore at the beginning of the list. */
- public int ignoreAtStart = 0;
- /** Number of elements to ignore at the end of the list. */
- public int ignoreAtEnd = 0;
- // Is this an inline or a block sequence?
- private boolean isInlineSequence = false;
-
+/**
+ *
+ */
+public abstract class KnuthSequence extends ArrayList {
/**
* Creates a new and empty list.
*/
}
/**
- * Creates a new and empty list, and sets isInlineSequence.
+ * Creates a new list from an existing list.
+ * @param list The list from which to create the new list.
*/
- public KnuthSequence(boolean isInlineSequence) {
- super();
- this.isInlineSequence = isInlineSequence;
+ public KnuthSequence(List list) {
+ super(list);
}
/**
* Finalizes a Knuth sequence.
* @return a finalized sequence.
*/
- public KnuthSequence endSequence() {
- return endSequence(null);
- }
+ public abstract KnuthSequence endSequence();
+
+ /**
+ * Can sequence be appended to this sequence?
+ * @param sequence The sequence that may be appended.
+ * @return whether the sequence can be appended to this sequence.
+ */
+ public abstract boolean canAppendSequence(KnuthSequence sequence);
+
+ /**
+ * Append sequence to this sequence if it can be appended.
+ * TODO In principle the LayoutManager can also be retrieved from the elements in the sequence.
+ * @param sequence The sequence that is to be appended.
+ * @param lm The LayoutManager for the Position that may have to be created.
+ * @return whether the sequence was succesfully appended to this sequence.
+ */
+ public abstract boolean appendSequence(KnuthSequence sequence, LayoutManager lm);
/**
- * Finalizes a Knuth sequence.
- * @param breakPosition a Position instance for the last penalty (may be null)
- * @return a finalized sequence.
+ * Append sequence to this sequence if it can be appended.
+ * If that is not possible, close this sequence.
+ * TODO In principle the LayoutManager can also be retrieved from the elements in the sequence.
+ * @param sequence The sequence that is to be appended.
+ * @param lm The LayoutManager for the Position that may have to be created.
+ * @return whether the sequence was succesfully appended to this sequence.
*/
- public KnuthSequence endSequence(Position breakPosition) {
- // remove glue and penalty item at the end of the paragraph
- while (this.size() > ignoreAtStart
- && !((KnuthElement)this.get(this.size() - 1)).isBox()) {
- this.remove(this.size() - 1);
- }
- if (this.size() > ignoreAtStart) {
- // add the elements representing the space at the end of the last line
- // and the forced break
- this.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, null, false));
- this.add(new KnuthGlue(0, 10000000, 0, null, false));
- this.add(new KnuthPenalty(0, -KnuthElement.INFINITE, false, breakPosition, false));
- ignoreAtEnd = 3;
- return this;
- } else {
- this.clear();
- return null;
+ public abstract boolean appendSequenceOrClose(KnuthSequence sequence, LayoutManager lm);
+
+ /**
+ * Wrap the Positions of the elements of this sequence in a Position for LayoutManager lm.
+ * @param lm The LayoutManager for the Positions that will be created.
+ */
+ public void wrapPositions(LayoutManager lm) {
+ ListIterator listIter = listIterator();
+ KnuthElement element;
+ while (listIter.hasNext()) {
+ element = (KnuthElement) listIter.next();
+ element.setPosition
+ (lm.notifyPos(new NonLeafPosition(lm, element.getPosition())));
}
}
-
+
+ /**
+ * @return the last element of this sequence.
+ */
public KnuthElement getLast() {
int idx = size();
if (idx == 0) {
return (KnuthElement) get(idx - 1);
}
+ /**
+ * Remove the last element of this sequence.
+ * @return the removed element.
+ */
public KnuthElement removeLast() {
int idx = size();
if (idx == 0) {
return (KnuthElement) remove(idx - 1);
}
+ /**
+ * @param index The index of the element to be returned
+ * @return the element at index index.
+ */
public KnuthElement getElement(int index) {
return (KnuthElement) get(index);
}
* Is this an inline or a block sequence?
* @return true if this is an inline sequence
*/
- public boolean isInlineSequence() {
- return isInlineSequence;
- }
+ public abstract boolean isInlineSequence();
+
}
*/
FObj getFObj();
+ /**
+ * Adds a Position to the Position participating in the first|last determination by assigning
+ * it a unique position index.
+ * @param pos the Position
+ * @return the same Position but with a position index
+ */
+ Position notifyPos(Position pos);
}
import org.apache.fop.fo.flow.Character;
import org.apache.fop.fonts.Font;
+import org.apache.fop.layoutmgr.InlineKnuthSequence;
import org.apache.fop.layoutmgr.KnuthElement;
import org.apache.fop.layoutmgr.KnuthGlue;
import org.apache.fop.layoutmgr.KnuthPenalty;
public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
MinOptMax ipd;
curArea = get(context);
- KnuthSequence seq = new KnuthSequence(true);
+ KnuthSequence seq = new InlineKnuthSequence();
if (curArea == null) {
setFinished(true);
public boolean getGeneratesLineArea() {
return holder instanceof LineArea;
}
+
+ /* (non-Javadoc)
+ * @see org.apache.fop.layoutmgr.LayoutManager#notifyPos(org.apache.fop.layoutmgr.Position)
+ */
+ public Position notifyPos(Position pos) {
+ return pos;
+ }
}
import org.apache.fop.fo.flow.Footnote;
import org.apache.fop.layoutmgr.AbstractLayoutManager;
import org.apache.fop.layoutmgr.FootnoteBodyLayoutManager;
+import org.apache.fop.layoutmgr.InlineKnuthSequence;
import org.apache.fop.layoutmgr.KnuthElement;
import org.apache.fop.layoutmgr.KnuthSequence;
import org.apache.fop.layoutmgr.LayoutContext;
if (returnedList.size() == 0) {
//Inline part of the footnote is empty. Need to send back an auxiliary
//zero-width, zero-height inline box so the footnote gets painted.
- KnuthSequence seq = new KnuthSequence(true);
+ KnuthSequence seq = new InlineKnuthSequence();
//Need to use an aux. box, otherwise, the line height can't be forced to zero height.
forcedAnchor = new KnuthInlineBox(0, null, null, true);
seq.add(forcedAnchor);
import org.apache.fop.fo.properties.CommonMarginInline;
import org.apache.fop.fo.properties.SpaceProperty;
import org.apache.fop.fonts.Font;
+import org.apache.fop.layoutmgr.BlockKnuthSequence;
import org.apache.fop.layoutmgr.KnuthBox;
import org.apache.fop.layoutmgr.KnuthElement;
import org.apache.fop.layoutmgr.KnuthSequence;
/** @see org.apache.fop.layoutmgr.LayoutManager */
public LinkedList getNextKnuthElements(LayoutContext context, int alignment) {
- InlineLevelLayoutManager curILM;
- LayoutManager curLM, lastLM = null;
+ LayoutManager curLM;
// the list returned by child LM
LinkedList returnedList;
- KnuthElement returnedElement;
// the list which will be returned to the parent LM
LinkedList returnList = new LinkedList();
// just iterate once more to see if there is another child
continue;
}
+ if (returnedList.size() == 0) {
+ continue;
+ }
if (curLM instanceof InlineLevelLayoutManager) {
- // close the last block sequence
- if (lastSequence != null && !lastSequence.isInlineSequence()) {
- lastSequence = null;
- if (log.isTraceEnabled()) {
- trace.append(" ]");
- }
- }
// "wrap" the Position stored in each element of returnedList
ListIterator seqIter = returnedList.listIterator();
while (seqIter.hasNext()) {
KnuthSequence sequence = (KnuthSequence) seqIter.next();
- ListIterator listIter = sequence.listIterator();
- while (listIter.hasNext()) {
- returnedElement = (KnuthElement) listIter.next();
- returnedElement.setPosition
- (notifyPos(new NonLeafPosition(this,
- returnedElement.getPosition())));
- }
- if (!sequence.isInlineSequence()) {
- if (lastSequence != null && lastSequence.isInlineSequence()) {
- // log.error("Last inline sequence should be closed before"
- // + " a block sequence");
- lastSequence.add(new KnuthPenalty(0, -KnuthElement.INFINITE,
- false, null, false));
- lastSequence = null;
- if (log.isTraceEnabled()) {
- trace.append(" ]");
- }
- }
- returnList.add(sequence);
- if (log.isTraceEnabled()) {
- trace.append(" B");
- }
- } else {
- if (lastSequence == null) {
- lastSequence = new KnuthSequence(true);
- returnList.add(lastSequence);
- if (!borderAdded) {
- addKnuthElementsForBorderPaddingStart(lastSequence);
- borderAdded = true;
- }
- if (log.isTraceEnabled()) {
- trace.append(" [");
- }
- } else {
- if (log.isTraceEnabled()) {
- trace.append(" +");
- }
- }
- lastSequence.addAll(sequence);
- if (log.isTraceEnabled()) {
- trace.append(" I");
- }
- // finish last paragraph if it was closed with a linefeed
- KnuthElement lastElement = (KnuthElement) sequence.getLast();
- if (lastElement.isPenalty()
- && ((KnuthPenalty) lastElement).getP()
- == -KnuthPenalty.INFINITE) {
- // a penalty item whose value is -inf
- // represents a preserved linefeed,
- // wich forces a line break
- lastSequence = null;
- if (log.isTraceEnabled()) {
- trace.append(" ]");
- }
- }
- }
+ sequence.wrapPositions(this);
}
- } else { // A block LM
- // close the last inline sequence
- if (lastSequence != null && lastSequence.isInlineSequence()) {
- lastSequence.add(new KnuthPenalty(0, -KnuthElement.INFINITE,
- false, null, false));
- lastSequence = null;
- if (log.isTraceEnabled()) {
- trace.append(" ]");
- }
+ if (lastSequence != null && lastSequence.appendSequenceOrClose
+ ((KnuthSequence) returnedList.get(0), this)) {
+ returnedList.remove(0);
}
- if (curLM != lastLM) {
- // close the last block sequence
- if (lastSequence != null && !lastSequence.isInlineSequence()) {
- lastSequence = null;
- if (log.isTraceEnabled()) {
- trace.append(" ]");
- }
- }
- lastLM = curLM;
+ // add border and padding to the first complete sequence of this LM
+ if (!borderAdded && returnedList.size() != 0) {
+ addKnuthElementsForBorderPaddingStart((KnuthSequence) returnedList.get(0));
+ borderAdded = true;
}
- if (lastSequence == null) {
- lastSequence = new KnuthSequence(false);
- returnList.add(lastSequence);
- if (log.isTraceEnabled()) {
- trace.append(" [");
- }
+ returnList.addAll(returnedList);
+ } else { // A block LM
+ // TODO For now avoid having two different block LMs in a single sequence
+ if (curLM != lastChildLM && lastSequence != null) {
+ lastSequence.endSequence();
+ }
+ BlockKnuthSequence sequence = new BlockKnuthSequence(returnedList);
+ sequence.wrapPositions(this);
+ if (lastSequence == null || !lastSequence.appendSequenceOrClose(sequence, this)) {
+ // add border and padding to the first complete sequence of this LM
if (!borderAdded) {
- addKnuthElementsForBorderPaddingStart(lastSequence);
+ addKnuthElementsForBorderPaddingStart(sequence);
borderAdded = true;
}
- } else {
- if (log.isTraceEnabled()) {
- trace.append(" +");
- }
- }
- ListIterator iter = returnedList.listIterator();
- while (iter.hasNext()) {
- KnuthElement element = (KnuthElement) iter.next();
- element.setPosition
- (notifyPos(new NonLeafPosition(this,
- element.getPosition())));
- }
- lastSequence.addAll(returnedList);
- if (log.isTraceEnabled()) {
- trace.append(" L");
+ returnList.add(sequence);
}
}
+ lastSequence = (KnuthSequence) returnList.getLast();
lastChildLM = curLM;
}
-
+
if (lastSequence != null) {
addKnuthElementsForBorderPaddingEnd(lastSequence);
}
int ipStart = borderAndPadding.getBorderStartWidth(false)
+ borderAndPadding.getPaddingStart(false, this);
if (ipStart > 0) {
- returnList.add(new KnuthBox(ipStart, getAuxiliaryPosition(), true));
+ returnList.add(0,new KnuthBox(ipStart, getAuxiliaryPosition(), true));
}
}
}
import org.apache.fop.area.inline.TextArea;
import org.apache.fop.fo.flow.Leader;
import org.apache.fop.fonts.Font;
+import org.apache.fop.layoutmgr.InlineKnuthSequence;
import org.apache.fop.layoutmgr.KnuthElement;
import org.apache.fop.layoutmgr.KnuthGlue;
import org.apache.fop.layoutmgr.KnuthPenalty;
int alignment) {
MinOptMax ipd;
curArea = get(context);
- KnuthSequence seq = new KnuthSequence(true);
+ KnuthSequence seq = new InlineKnuthSequence();
if (curArea == null) {
setFinished(true);
import org.apache.fop.fo.FObj;
import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
import org.apache.fop.layoutmgr.AbstractLayoutManager;
+import org.apache.fop.layoutmgr.InlineKnuthSequence;
import org.apache.fop.layoutmgr.KnuthGlue;
import org.apache.fop.layoutmgr.KnuthPenalty;
import org.apache.fop.layoutmgr.KnuthSequence;
// node is a fo:ExternalGraphic, fo:InstreamForeignObject,
// fo:PageNumber or fo:PageNumberCitation
- KnuthSequence seq = new KnuthSequence(true);
+ KnuthSequence seq = new InlineKnuthSequence();
addKnuthElementsForBorderPaddingStart(seq);
import org.apache.fop.layoutmgr.BreakElement;
import org.apache.fop.layoutmgr.BreakingAlgorithm;
import org.apache.fop.layoutmgr.ElementListObserver;
+import org.apache.fop.layoutmgr.InlineKnuthSequence;
import org.apache.fop.layoutmgr.KnuthBlockBox;
import org.apache.fop.layoutmgr.KnuthBox;
import org.apache.fop.layoutmgr.KnuthElement;
}
// this class represents a paragraph
- private class Paragraph extends KnuthSequence {
+ private class Paragraph extends InlineKnuthSequence {
+ /** Number of elements to ignore at the beginning of the list. */
+ private int ignoreAtStart = 0;
+ /** Number of elements to ignore at the end of the list. */
+ private int ignoreAtEnd = 0;
+
// space at the end of the last line (in millipoints)
private MinOptMax lineFiller;
private int textAlignment;
public Paragraph(LineLayoutManager llm, int alignment, int alignmentLast,
int indent, int endIndent) {
- super(true);
+ super();
layoutManager = llm;
textAlignment = alignment;
textAlignmentLast = alignmentLast;
*/
private void collectInlineKnuthElements(LayoutContext context, MinOptMax availIPD) {
LayoutContext inlineLC = new LayoutContext(context);
-
+
InlineLevelLayoutManager curLM;
LinkedList returnedList = null;
iLineWidth = context.getStackLimit().opt;
-
+
// convert all the text in a sequence of paragraphs made
// of KnuthBox, KnuthGlue and KnuthPenalty objects
boolean bPrevWasKnuthBox = false;
-
+
StringBuffer trace = new StringBuffer("LineLM:");
-
+
Paragraph lastPar = null;
-
+
while ((curLM = (InlineLevelLayoutManager) getChildLM()) != null) {
- if ((returnedList
- = curLM.getNextKnuthElements(inlineLC,
- effectiveAlignment))
- != null) {
- if (returnedList.size() == 0) {
- continue;
+ returnedList = curLM.getNextKnuthElements(inlineLC, effectiveAlignment);
+ if (returnedList == null) {
+ // curLM returned null; this can happen
+ // if it has nothing more to layout,
+ // so just iterate once more to see
+ // if there are other children
+ continue;
+ }
+ if (returnedList.size() == 0) {
+ continue;
+ }
+
+ if (lastPar != null) {
+ KnuthSequence firstSeq = (KnuthSequence) returnedList.getFirst();
+
+ // finish last paragraph before a new block sequence
+ if (!firstSeq.isInlineSequence()) {
+ lastPar.endParagraph();
+ ElementListObserver.observe(lastPar, "line", null);
+ lastPar = null;
+ if (log.isTraceEnabled()) {
+ trace.append(" ]");
+ }
+ bPrevWasKnuthBox = false;
}
-
+
+ // does the first element of the first paragraph add to an existing word?
if (lastPar != null) {
- Object firstObj;
- KnuthSequence firstSeq = null;
- firstObj = returnedList.getFirst();
- if (firstObj instanceof KnuthSequence) {
- firstSeq = (KnuthSequence) firstObj;
+ KnuthElement thisElement;
+ thisElement = (KnuthElement) firstSeq.get(0);
+ if (thisElement.isBox() && !thisElement.isAuxiliary()
+ && bPrevWasKnuthBox) {
+ lastPar.addALetterSpace();
}
+ }
+ }
+
+ // loop over the KnuthSequences (and single KnuthElements) in returnedList
+ ListIterator iter = returnedList.listIterator();
+ while (iter.hasNext()) {
+ KnuthSequence sequence = (KnuthSequence) iter.next();
+ // the sequence contains inline Knuth elements
+ if (sequence.isInlineSequence()) {
+ // look at the last element
+ KnuthElement lastElement;
+ lastElement = (KnuthElement) sequence.getLast();
+ if (lastElement == null) {
+ throw new NullPointerException(
+ "Sequence was empty! lastElement is null");
+ }
+ bPrevWasKnuthBox = lastElement.isBox() && lastElement.getW() != 0;
- // finish last paragraph before a new block sequence
- if (firstSeq != null && !firstSeq.isInlineSequence()) {
+ // if last paragraph is open, add the new elements to the paragraph
+ // else this is the last paragraph
+ if (lastPar == null) {
+ lastPar = new Paragraph(this,
+ textAlignment, textAlignmentLast,
+ textIndent.getValue(this),
+ lastLineEndIndent.getValue(this));
+ lastPar.startParagraph(availIPD.opt);
+ if (log.isTraceEnabled()) {
+ trace.append(" [");
+ }
+ } else {
+ if (log.isTraceEnabled()) {
+ trace.append(" +");
+ }
+ }
+ lastPar.addAll(sequence);
+ if (log.isTraceEnabled()) {
+ trace.append(" I");
+ }
+
+ // finish last paragraph if it was closed with a linefeed
+ if (lastElement.isPenalty()
+ && ((KnuthPenalty) lastElement).getP()
+ == -KnuthPenalty.INFINITE) {
+ // a penalty item whose value is -inf
+ // represents a preserved linefeed,
+ // wich forces a line break
+ lastPar.removeLast();
+ if (lastPar.size() == 0) {
+ //only a forced linefeed on this line
+ //-> compensate with a zero width box
+ lastPar.add(new KnuthInlineBox(0, null, null, false));
+ }
lastPar.endParagraph();
ElementListObserver.observe(lastPar, "line", null);
lastPar = null;
}
bPrevWasKnuthBox = false;
}
-
- // does the first element of the first paragraph add to an existing word?
- if (lastPar != null) {
- KnuthElement thisElement;
- if (firstObj instanceof KnuthElement) {
- thisElement = (KnuthElement) firstObj;
- } else {
- thisElement = (KnuthElement) firstSeq.get(0);
- }
- if (thisElement.isBox() && !thisElement.isAuxiliary()
- && bPrevWasKnuthBox) {
- lastPar.addALetterSpace();
- }
+ } else { // the sequence is a block sequence
+ /*
+ // "wrap" the Position stored in each element of returnedList
+ ListIterator listIter = sequence.listIterator();
+ while (listIter.hasNext()) {
+ KnuthElement returnedElement = (KnuthElement) listIter.next();
+ returnedElement.setPosition
+ (new NonLeafPosition(this,
+ returnedElement.getPosition()));
+ }
+ */
+ knuthParagraphs.add(sequence);
+ if (log.isTraceEnabled()) {
+ trace.append(" B");
}
-
}
-
-
- // loop over the KnuthSequences (and single KnuthElements) in returnedList
- // (LeafNodeLM descendants may also skip wrapping elements in KnuthSequences
- // to cause fewer container structures)
- // TODO the mixture here adds a little to the complexity. Decide whether:
- // - to leave as is and save some container instances
- // - to use KnuthSequences exclusively (adjustments on leaf-type LMs necessary)
- // See also FootnoteLM.addAnchor() as well as right above this comment
- // for similar code. Or see http://svn.apache.org/viewcvs?rev=230779&view=rev
- ListIterator iter = returnedList.listIterator();
- while (iter.hasNext()) {
- Object obj = iter.next();
- KnuthElement singleElement = null;
- KnuthSequence sequence = null;
- if (obj instanceof KnuthElement) {
- singleElement = (KnuthElement)obj;
- } else {
- sequence = (KnuthSequence)obj;
- }
- // the sequence contains inline Knuth elements
- if (singleElement != null || sequence.isInlineSequence()) {
- // look at the last element
- KnuthElement lastElement;
- if (singleElement != null) {
- lastElement = singleElement;
- } else {
- lastElement = (KnuthElement) sequence.getLast();
- if (lastElement == null) {
- throw new NullPointerException(
- "Sequence was empty! lastElement is null");
- }
- }
- bPrevWasKnuthBox = lastElement.isBox() && lastElement.getW() != 0;
-
- // if last paragraph is open, add the new elements to the paragraph
- // else this is the last paragraph
- if (lastPar == null) {
- lastPar = new Paragraph(this,
- textAlignment, textAlignmentLast,
- textIndent.getValue(this), lastLineEndIndent.getValue(this));
- lastPar.startParagraph(availIPD.opt);
- if (log.isTraceEnabled()) {
- trace.append(" [");
- }
- } else {
- if (log.isTraceEnabled()) {
- trace.append(" +");
- }
- }
- if (singleElement != null) {
- lastPar.add(singleElement);
- } else {
- lastPar.addAll(sequence);
- }
- if (log.isTraceEnabled()) {
- trace.append(" I");
- }
-
- // finish last paragraph if it was closed with a linefeed
- if (lastElement.isPenalty()
- && ((KnuthPenalty) lastElement).getP()
- == -KnuthPenalty.INFINITE) {
- // a penalty item whose value is -inf
- // represents a preserved linefeed,
- // wich forces a line break
- lastPar.removeLast();
- if (lastPar.size() == 0) {
- //only a forced linefeed on this line
- //-> compensate with a zero width box
- lastPar.add(new KnuthInlineBox(0, null, null, false));
- }
- lastPar.endParagraph();
- ElementListObserver.observe(lastPar, "line", null);
- lastPar = null;
- if (log.isTraceEnabled()) {
- trace.append(" ]");
- }
- bPrevWasKnuthBox = false;
- }
- } else { // the sequence is a block sequence
-/* // "wrap" the Position stored in each element of returnedList
- ListIterator listIter = sequence.listIterator();
- while (listIter.hasNext()) {
- KnuthElement returnedElement = (KnuthElement) listIter.next();
- returnedElement.setPosition
- (new NonLeafPosition(this,
- returnedElement.getPosition()));
- }
-*/ knuthParagraphs.add(sequence);
- if (log.isTraceEnabled()) {
- trace.append(" B");
- }
- }
- } // end of loop over returnedList
- } else {
- // curLM returned null; this can happen
- // if it has nothing more to layout,
- // so just iterate once more to see
- // if there are other children
- }
+ } // end of loop over returnedList
}
if (lastPar != null) {
lastPar.endParagraph();
import org.apache.fop.fo.FOText;
import org.apache.fop.fo.flow.Inline;
import org.apache.fop.fonts.Font;
+import org.apache.fop.layoutmgr.InlineKnuthSequence;
import org.apache.fop.layoutmgr.KnuthBox;
import org.apache.fop.layoutmgr.KnuthElement;
import org.apache.fop.layoutmgr.KnuthGlue;
alignmentContext = context.getAlignmentContext();
LinkedList returnList = new LinkedList();
- KnuthSequence sequence = new KnuthSequence(true);
+ KnuthSequence sequence = new InlineKnuthSequence();
AreaInfo ai = null;
returnList.add(sequence);
(new KnuthGlue(lineEndBAP, 0, 0,
new LeafPosition(this, -1), true));
}
- sequence.add
- (new KnuthPenalty(0, -KnuthElement.INFINITE,
- false, null, false));
- sequence = new KnuthSequence(true);
+ sequence.endSequence();
+ sequence = new InlineKnuthSequence();
returnList.add(sequence);
// advance to the next character