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.

RestartAtLM.java 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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.Collections;
  20. import java.util.Iterator;
  21. import java.util.LinkedList;
  22. import org.apache.fop.events.EventBroadcaster;
  23. /**
  24. * Class to find the restart layoutmanager for changing IPD
  25. */
  26. class RestartAtLM {
  27. protected boolean invalidPosition;
  28. protected LayoutManager getRestartAtLM(AbstractBreaker breaker, PageBreakingAlgorithm alg,
  29. boolean ipdChangesOnNextPage, boolean onLastPageAndIPDChanges,
  30. boolean visitedBefore, AbstractBreaker.BlockSequence blockList, int start) {
  31. BreakingAlgorithm.KnuthNode optimalBreak = ipdChangesOnNextPage ? alg.getBestNodeBeforeIPDChange() : alg
  32. .getBestNodeForLastPage();
  33. if (onLastPageAndIPDChanges && visitedBefore && breaker.originalRestartAtLM == null) {
  34. optimalBreak = null;
  35. }
  36. int positionIndex = findPositionIndex(breaker, optimalBreak, alg, start);
  37. if (ipdChangesOnNextPage || (breaker.positionAtBreak != null && breaker.positionAtBreak.getIndex() > -1)) {
  38. breaker.firstElementsForRestart = Collections.EMPTY_LIST;
  39. if (ipdChangesOnNextPage) {
  40. if (breaker.containsNonRestartableLM(breaker.positionAtBreak)) {
  41. if (alg.getIPDdifference() > 0) {
  42. EventBroadcaster eventBroadcaster = breaker.getCurrentChildLM().getFObj()
  43. .getUserAgent().getEventBroadcaster();
  44. BlockLevelEventProducer eventProducer = BlockLevelEventProducer.Provider
  45. .get(eventBroadcaster);
  46. eventProducer.nonRestartableContentFlowingToNarrowerPage(this);
  47. }
  48. breaker.firstElementsForRestart = new LinkedList();
  49. boolean boxFound = false;
  50. Iterator iter = blockList.listIterator(positionIndex + 1);
  51. Position position = null;
  52. while (iter.hasNext()
  53. && (position == null || breaker.containsNonRestartableLM(position))) {
  54. positionIndex++;
  55. KnuthElement element = (KnuthElement) iter.next();
  56. position = element.getPosition();
  57. if (element.isBox()) {
  58. boxFound = true;
  59. breaker.firstElementsForRestart.add(element);
  60. } else if (boxFound) {
  61. breaker.firstElementsForRestart.add(element);
  62. }
  63. }
  64. if (position instanceof SpaceResolver.SpaceHandlingBreakPosition) {
  65. /* Retrieve the original position wrapped into this space position */
  66. breaker.positionAtBreak = position.getPosition();
  67. } else {
  68. breaker.positionAtBreak = null;
  69. }
  70. }
  71. }
  72. }
  73. LayoutManager restartAtLM = null;
  74. if (ipdChangesOnNextPage || !(breaker.positionAtBreak != null && breaker.positionAtBreak.getIndex() > -1)) {
  75. if (breaker.positionAtBreak != null && breaker.positionAtBreak.getIndex() == -1) {
  76. Position position;
  77. Iterator iter = blockList.listIterator(positionIndex + 1);
  78. do {
  79. KnuthElement nextElement = (KnuthElement) iter.next();
  80. position = nextElement.getPosition();
  81. } while (position == null
  82. || position instanceof SpaceResolver.SpaceHandlingPosition
  83. || position instanceof SpaceResolver.SpaceHandlingBreakPosition
  84. && position.getPosition().getIndex() == -1);
  85. LayoutManager surroundingLM = breaker.positionAtBreak.getLM();
  86. while (position.getLM() != surroundingLM) {
  87. position = position.getPosition();
  88. }
  89. if (position.getPosition() == null) {
  90. position.getLM().getFObj().setForceKeepTogether(true);
  91. invalidPosition = true;
  92. return null;
  93. }
  94. restartAtLM = position.getPosition().getLM();
  95. }
  96. if (onLastPageAndIPDChanges && restartAtLM != null) {
  97. if (breaker.originalRestartAtLM == null) {
  98. breaker.originalRestartAtLM = restartAtLM;
  99. } else {
  100. restartAtLM = breaker.originalRestartAtLM;
  101. }
  102. breaker.firstElementsForRestart = Collections.EMPTY_LIST;
  103. }
  104. }
  105. if (onLastPageAndIPDChanges && !visitedBefore && breaker.positionAtBreak.getPosition() != null) {
  106. restartAtLM = breaker.positionAtBreak.getPosition().getLM();
  107. }
  108. return restartAtLM;
  109. }
  110. private int findPositionIndex(AbstractBreaker breaker, BreakingAlgorithm.KnuthNode optimalBreak,
  111. PageBreakingAlgorithm alg, int start) {
  112. int positionIndex = (optimalBreak != null) ? optimalBreak.position : start;
  113. for (int i = positionIndex; i < alg.par.size(); i++) {
  114. KnuthElement elementAtBreak = alg.getElement(i);
  115. if (elementAtBreak.getPosition() == null) {
  116. elementAtBreak = alg.getElement(0);
  117. }
  118. breaker.positionAtBreak = elementAtBreak.getPosition();
  119. /* Retrieve the original position wrapped into this space position */
  120. breaker.positionAtBreak = breaker.positionAtBreak.getPosition();
  121. if (breaker.positionAtBreak != null) {
  122. return i;
  123. }
  124. }
  125. return positionIndex;
  126. }
  127. }