You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

InlineKnuthSequence.java 5.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /*
  2. * Licensed to the Apache Software Foundation (ASF) under one or more
  3. * contributor license agreements. See the NOTICE file distributed with
  4. * this work for additional information regarding copyright ownership.
  5. * The ASF licenses this file to You under the Apache License, Version 2.0
  6. * (the "License"); you may not use this file except in compliance with
  7. * the License. You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /* $Id$ */
  18. package org.apache.fop.layoutmgr;
  19. import java.util.LinkedList;
  20. import java.util.List;
  21. import org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager;
  22. import org.apache.fop.layoutmgr.inline.KnuthInlineBox;
  23. /**
  24. * Represents a list of inline Knuth elements.
  25. * If closed, it represents all elements of a Knuth paragraph.
  26. */
  27. public class InlineKnuthSequence extends KnuthSequence {
  28. private static final long serialVersionUID = 1354774188859946549L;
  29. private boolean isClosed = false;
  30. /**
  31. * Creates a new and empty list.
  32. */
  33. public InlineKnuthSequence() {
  34. super();
  35. }
  36. /**
  37. * Creates a new list from an existing list.
  38. * @param list The list from which to create the new list.
  39. */
  40. public InlineKnuthSequence(List list) {
  41. super(list);
  42. }
  43. /**
  44. * Is this an inline or a block sequence?
  45. * @return false
  46. */
  47. public boolean isInlineSequence() {
  48. return true;
  49. }
  50. /** {@inheritDoc} */
  51. public boolean canAppendSequence(KnuthSequence sequence) {
  52. return sequence.isInlineSequence() && !isClosed;
  53. }
  54. /** {@inheritDoc} */
  55. public boolean appendSequence(KnuthSequence sequence) {
  56. if (!canAppendSequence(sequence)) {
  57. return false;
  58. }
  59. // does the first element of the first paragraph add to an existing word?
  60. ListElement lastOldElement, firstNewElement;
  61. lastOldElement = getLast();
  62. firstNewElement = sequence.getElement(0);
  63. if (firstNewElement.isBox() && !((KnuthElement) firstNewElement).isAuxiliary()
  64. && lastOldElement.isBox() && ((KnuthElement) lastOldElement).getWidth() != 0) {
  65. addALetterSpace();
  66. }
  67. addAll(sequence);
  68. return true;
  69. }
  70. /** {@inheritDoc} */
  71. public boolean appendSequence(KnuthSequence sequence, boolean keepTogether,
  72. BreakElement breakElement) {
  73. return appendSequence(sequence);
  74. }
  75. /** {@inheritDoc} */
  76. public KnuthSequence endSequence() {
  77. if (!isClosed) {
  78. add(new KnuthPenalty(0, -KnuthElement.INFINITE, false, null, false));
  79. isClosed = true;
  80. }
  81. return this;
  82. }
  83. /**
  84. * Add letter space.
  85. */
  86. public void addALetterSpace() {
  87. KnuthBox prevBox = (KnuthBox) getLast();
  88. if (prevBox.isAuxiliary()
  89. && (size() < 4
  90. || !getElement(size() - 2).isGlue()
  91. || !getElement(size() - 3).isPenalty()
  92. || !getElement(size() - 4).isBox()
  93. )
  94. ) {
  95. // Not the sequence we are expecting
  96. return;
  97. }
  98. removeLast();
  99. LinkedList oldList = new LinkedList();
  100. // if there are two consecutive KnuthBoxes the
  101. // first one does not represent a whole word,
  102. // so it must be given one more letter space
  103. if (!prevBox.isAuxiliary()) {
  104. // if letter spacing is constant,
  105. // only prevBox needs to be replaced;
  106. oldList.add(prevBox);
  107. } else {
  108. // prevBox is the last element
  109. // in the sub-sequence
  110. // <box> <aux penalty> <aux glue> <aux box>
  111. // the letter space is added to <aux glue>,
  112. // while the other elements are not changed
  113. oldList.add(prevBox);
  114. oldList.addFirst((KnuthGlue) removeLast());
  115. oldList.addFirst((KnuthPenalty) removeLast());
  116. oldList.addFirst((KnuthBox) removeLast());
  117. }
  118. // adding a letter space could involve, according to the text
  119. // represented by oldList, replacing a glue element or adding
  120. // new elements
  121. addAll(((InlineLevelLayoutManager)
  122. prevBox.getLayoutManager())
  123. .addALetterSpaceTo(oldList));
  124. // prevBox may not be a KnuthInlineBox;
  125. // this may happen if it is a padding box; see bug 39571.
  126. if ( prevBox instanceof KnuthInlineBox && ((KnuthInlineBox) prevBox).isAnchor()) {
  127. // prevBox represents a footnote citation: copy footnote info
  128. // from prevBox to the new box
  129. KnuthInlineBox newBox = (KnuthInlineBox) getLast();
  130. newBox.setFootnoteBodyLM(((KnuthInlineBox) prevBox).getFootnoteBodyLM());
  131. }
  132. }
  133. }