001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /* $Id: InlineKnuthSequence.java 426576 2006-07-28 15:44:37Z jeremias $ */
019:
020: package org.apache.fop.layoutmgr;
021:
022: import java.util.LinkedList;
023: import java.util.List;
024:
025: import org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager;
026: import org.apache.fop.layoutmgr.inline.KnuthInlineBox;
027:
028: /**
029: * Represents a list of inline Knuth elements.
030: * If closed, it represents all elements of a Knuth paragraph.
031: */
032: public class InlineKnuthSequence extends KnuthSequence {
033:
034: private boolean isClosed = false;
035:
036: /**
037: * Creates a new and empty list.
038: */
039: public InlineKnuthSequence() {
040: super ();
041: }
042:
043: /**
044: * Creates a new list from an existing list.
045: * @param list The list from which to create the new list.
046: */
047: public InlineKnuthSequence(List list) {
048: super (list);
049: }
050:
051: /**
052: * Is this an inline or a block sequence?
053: * @return false
054: */
055: public boolean isInlineSequence() {
056: return true;
057: }
058:
059: /* (non-Javadoc)
060: * @see org.apache.fop.layoutmgr.KnuthSequence#canAppendSequence(org.apache.fop.layoutmgr.KnuthSequence)
061: */
062: public boolean canAppendSequence(KnuthSequence sequence) {
063: return sequence.isInlineSequence() && !isClosed;
064: }
065:
066: /* (non-Javadoc)
067: * @see org.apache.fop.layoutmgr.KnuthSequence#appendSequence(org.apache.fop.layoutmgr.KnuthSequence)
068: */
069: public boolean appendSequence(KnuthSequence sequence) {
070: if (!canAppendSequence(sequence)) {
071: return false;
072: }
073: // does the first element of the first paragraph add to an existing word?
074: ListElement lastOldElement, firstNewElement;
075: lastOldElement = getLast();
076: firstNewElement = sequence.getElement(0);
077: if (firstNewElement.isBox()
078: && !((KnuthElement) firstNewElement).isAuxiliary()
079: && lastOldElement.isBox()
080: && ((KnuthElement) lastOldElement).getW() != 0) {
081: addALetterSpace();
082: }
083: addAll(sequence);
084: return true;
085: }
086:
087: /* (non-Javadoc)
088: * @see KnuthSequence#appendSequence(KnuthSequence, boolean, BreakElement)
089: */
090: public boolean appendSequence(KnuthSequence sequence,
091: boolean keepTogether, BreakElement breakElement) {
092: return appendSequence(sequence);
093: }
094:
095: /* (non-Javadoc)
096: * @see org.apache.fop.layoutmgr.KnuthSequence#endSequence()
097: */
098: public KnuthSequence endSequence() {
099: if (!isClosed) {
100: add(new KnuthPenalty(0, -KnuthElement.INFINITE, false,
101: null, false));
102: isClosed = true;
103: }
104: return this ;
105: }
106:
107: public void addALetterSpace() {
108: KnuthBox prevBox = (KnuthBox) getLast();
109: if (prevBox.isAuxiliary()
110: && (size() < 4 || !getElement(size() - 2).isGlue()
111: || !getElement(size() - 3).isPenalty() || !getElement(
112: size() - 4).isBox())) {
113: // Not the sequence we are expecting
114: return;
115: }
116: removeLast();
117: LinkedList oldList = new LinkedList();
118: // if there are two consecutive KnuthBoxes the
119: // first one does not represent a whole word,
120: // so it must be given one more letter space
121: if (!prevBox.isAuxiliary()) {
122: // if letter spacing is constant,
123: // only prevBox needs to be replaced;
124: oldList.add(prevBox);
125: } else {
126: // prevBox is the last element
127: // in the sub-sequence
128: // <box> <aux penalty> <aux glue> <aux box>
129: // the letter space is added to <aux glue>,
130: // while the other elements are not changed
131: oldList.add(prevBox);
132: oldList.addFirst((KnuthGlue) removeLast());
133: oldList.addFirst((KnuthPenalty) removeLast());
134: oldList.addFirst((KnuthBox) removeLast());
135: }
136: // adding a letter space could involve, according to the text
137: // represented by oldList, replacing a glue element or adding
138: // new elements
139: addAll(((InlineLevelLayoutManager) prevBox.getLayoutManager())
140: .addALetterSpaceTo(oldList));
141: // prevBox may not be a KnuthInlineBox;
142: // this may happen if it is a padding box; see bug 39571.
143: if (prevBox instanceof KnuthInlineBox
144: && ((KnuthInlineBox) prevBox).isAnchor()) {
145: // prevBox represents a footnote citation: copy footnote info
146: // from prevBox to the new box
147: KnuthInlineBox newBox = (KnuthInlineBox) getLast();
148: newBox.setFootnoteBodyLM(((KnuthInlineBox) prevBox)
149: .getFootnoteBodyLM());
150: }
151: }
152:
153: }
|