| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You 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.LinkedList; |
| import java.util.List; |
| |
| import org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager; |
| import org.apache.fop.layoutmgr.inline.KnuthInlineBox; |
| |
| |
| /** |
| * Represents a list of inline Knuth elements. |
| * If closed, it represents all elements of a Knuth paragraph. |
| */ |
| public class InlineKnuthSequence extends KnuthSequence { |
| |
| private static final long serialVersionUID = 1354774188859946549L; |
| |
| private boolean isClosed; |
| |
| /** |
| * 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; |
| } |
| |
| /** {@inheritDoc} */ |
| public boolean canAppendSequence(KnuthSequence sequence) { |
| return sequence.isInlineSequence() && !isClosed; |
| } |
| |
| /** {@inheritDoc} */ |
| public boolean appendSequence(KnuthSequence sequence) { |
| if (!canAppendSequence(sequence)) { |
| return false; |
| } |
| // does the first element of the first paragraph add to an existing word? |
| ListElement lastOldElement; |
| ListElement firstNewElement; |
| lastOldElement = getLast(); |
| firstNewElement = sequence.getElement(0); |
| if (firstNewElement.isBox() && !((KnuthElement) firstNewElement).isAuxiliary() |
| && lastOldElement.isBox() && ((KnuthElement) lastOldElement).getWidth() != 0) { |
| addALetterSpace(); |
| } |
| addAll(sequence); |
| return true; |
| } |
| |
| /** {@inheritDoc} */ |
| public boolean appendSequence(KnuthSequence sequence, boolean keepTogether, |
| BreakElement breakElement) { |
| return appendSequence(sequence); |
| } |
| |
| |
| /** {@inheritDoc} */ |
| public KnuthSequence endSequence() { |
| if (!isClosed) { |
| add(new KnuthPenalty(0, -KnuthElement.INFINITE, false, null, false)); |
| isClosed = true; |
| } |
| return this; |
| } |
| |
| /** |
| * Add letter space. |
| */ |
| public void addALetterSpace() { |
| KnuthBox prevBox = (KnuthBox) getLast(); |
| if (prevBox.isAuxiliary() |
| && (size() < 4 |
| || !getElement(size() - 2).isGlue() |
| || !getElement(size() - 3).isPenalty() |
| || !getElement(size() - 4).isBox() |
| ) |
| ) { |
| // Not the sequence we are expecting |
| return; |
| } |
| 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)); |
| // prevBox may not be a KnuthInlineBox; |
| // this may happen if it is a padding box; see bug 39571. |
| if (prevBox instanceof KnuthInlineBox && ((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()); |
| } |
| } |
| |
| } |