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.

KnuthSequence.java 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216
  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 org.apache.fop.util.ListUtil;
  20. import java.util.ArrayList;
  21. import java.util.List;
  22. import java.util.ListIterator;
  23. /**
  24. * Represents a list of {@link KnuthElement Knuth elements}.
  25. */
  26. public abstract class KnuthSequence extends ArrayList {
  27. //TODO: do not extend ArrayList
  28. /**
  29. * Creates a new and empty list.
  30. */
  31. public KnuthSequence() {
  32. super();
  33. }
  34. /**
  35. * Creates a new list from an existing list.
  36. * @param list The list from which to create the new list.
  37. */
  38. public KnuthSequence(List list) {
  39. super(list);
  40. }
  41. /**
  42. * Marks the start of the sequence.
  43. */
  44. public void startSequence() {
  45. }
  46. /**
  47. * Finalizes a Knuth sequence.
  48. * @return a finalized sequence.
  49. */
  50. public abstract KnuthSequence endSequence();
  51. /**
  52. * Can sequence be appended to this sequence?
  53. * @param sequence The sequence that may be appended.
  54. * @return whether the sequence can be appended to this sequence.
  55. */
  56. public abstract boolean canAppendSequence(KnuthSequence sequence);
  57. /**
  58. * Append sequence to this sequence if it can be appended.
  59. * @param sequence The sequence that is to be appended.
  60. * @param keepTogether Whether the two sequences must be kept together.
  61. * @param breakElement The BreakElement that may be inserted between the two sequences.
  62. * @return whether the sequence was succesfully appended to this sequence.
  63. */
  64. public abstract boolean appendSequence(KnuthSequence sequence, boolean keepTogether,
  65. BreakElement breakElement);
  66. /**
  67. * Append sequence to this sequence if it can be appended.
  68. * @param sequence The sequence that is to be appended.
  69. * @return whether the sequence was succesfully appended to this sequence.
  70. */
  71. public abstract boolean appendSequence(KnuthSequence sequence);
  72. /**
  73. * Append sequence to this sequence if it can be appended.
  74. * If that is not possible, close this sequence.
  75. * @param sequence The sequence that is to be appended.
  76. * @return whether the sequence was succesfully appended to this sequence.
  77. */
  78. public boolean appendSequenceOrClose(KnuthSequence sequence) {
  79. if (!appendSequence(sequence)) {
  80. endSequence();
  81. return false;
  82. } else {
  83. return true;
  84. }
  85. }
  86. /**
  87. * Append sequence to this sequence if it can be appended.
  88. * If that is not possible, close this sequence.
  89. * @param sequence The sequence that is to be appended.
  90. * @param keepTogether Whether the two sequences must be kept together.
  91. * @param breakElement The BreakElement that may be inserted between the two sequences.
  92. * @return whether the sequence was succesfully appended to this sequence.
  93. */
  94. public boolean appendSequenceOrClose(KnuthSequence sequence, boolean keepTogether,
  95. BreakElement breakElement) {
  96. if (!appendSequence(sequence, keepTogether, breakElement)) {
  97. endSequence();
  98. return false;
  99. } else {
  100. return true;
  101. }
  102. }
  103. /**
  104. * Wrap the Positions of the elements of this sequence in a Position for LayoutManager lm.
  105. * @param lm The LayoutManager for the Positions that will be created.
  106. */
  107. public void wrapPositions(LayoutManager lm) {
  108. ListIterator listIter = listIterator();
  109. ListElement element;
  110. while (listIter.hasNext()) {
  111. element = (ListElement) listIter.next();
  112. element.setPosition
  113. (lm.notifyPos(new NonLeafPosition(lm, element.getPosition())));
  114. }
  115. }
  116. /**
  117. * @return the last element of this sequence.
  118. */
  119. public ListElement getLast() {
  120. return (isEmpty()
  121. ? null
  122. : (ListElement) ListUtil.getLast(this));
  123. }
  124. /**
  125. * Remove the last element of this sequence.
  126. * @return the removed element.
  127. */
  128. public ListElement removeLast() {
  129. return (isEmpty()
  130. ? null
  131. : (ListElement) ListUtil.removeLast(this));
  132. }
  133. /**
  134. * @param index The index of the element to be returned
  135. * @return the element at index index.
  136. */
  137. public ListElement getElement(int index) {
  138. return (index >= size() || index < 0)
  139. ? null
  140. : (ListElement) get(index);
  141. }
  142. /** @return the position index of the first box in this sequence */
  143. protected int getFirstBoxIndex() {
  144. if (isEmpty()) {
  145. return -1;
  146. } else {
  147. return getFirstBoxIndex(0);
  148. }
  149. }
  150. /**
  151. * Get the position index of the first box in this sequence,
  152. * starting at the given index. If there is no box after the
  153. * passed {@code startIndex}, the starting index itself is returned.
  154. * @param startIndex the starting index for the lookup
  155. * @return the absolute position index of the next box element
  156. */
  157. protected int getFirstBoxIndex(int startIndex) {
  158. if (isEmpty() || startIndex < 0 || startIndex >= size()) {
  159. return -1;
  160. } else {
  161. ListElement element = null;
  162. int posIndex = startIndex;
  163. int lastIndex = size();
  164. while ( posIndex < lastIndex ) {
  165. element = getElement(posIndex);
  166. if ( !element.isBox() ) {
  167. posIndex++;
  168. } else {
  169. break;
  170. }
  171. }
  172. if ( posIndex != startIndex ) {
  173. if ( ( element != null ) && element.isBox() ) {
  174. return posIndex - 1;
  175. } else {
  176. return startIndex;
  177. }
  178. } else {
  179. return startIndex;
  180. }
  181. }
  182. }
  183. /**
  184. * Is this an inline or a block sequence?
  185. * @return true if this is an inline sequence
  186. */
  187. public abstract boolean isInlineSequence();
  188. /** {@inheritDoc} */
  189. public String toString() {
  190. return "<KnuthSequence " + super.toString() + ">";
  191. }
  192. }