選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

MultiSwitchLayoutManager.java 6.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  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. package org.apache.fop.layoutmgr;
  18. import java.util.LinkedList;
  19. import java.util.List;
  20. import org.apache.fop.area.Area;
  21. import org.apache.fop.fo.Constants;
  22. import org.apache.fop.fo.FObj;
  23. import org.apache.fop.fo.flow.MultiSwitch;
  24. public class MultiSwitchLayoutManager extends BlockStackingLayoutManager {
  25. static class WhitespaceManagementPosition extends Position {
  26. private List<ListElement> knuthList;
  27. public WhitespaceManagementPosition(LayoutManager lm) {
  28. super(lm);
  29. }
  30. public List<Position> getPositionList() {
  31. List<Position> positions = new LinkedList<Position>();
  32. if (knuthList != null && !knuthList.isEmpty()) {
  33. SpaceResolver.performConditionalsNotification(knuthList, 0, knuthList.size() - 1, -1);
  34. for (ListElement el : knuthList) {
  35. if (el.getPosition() != null) {
  36. positions.add(el.getPosition());
  37. }
  38. }
  39. }
  40. return positions;
  41. }
  42. public void setKnuthList(List<ListElement> knuthList) {
  43. this.knuthList = knuthList;
  44. }
  45. public List<ListElement> getKnuthList() {
  46. return knuthList;
  47. }
  48. }
  49. private interface KnuthElementsGenerator {
  50. List<ListElement> getKnuthElement(LayoutContext context, int alignment);
  51. }
  52. private class DefaultKnuthListGenerator implements KnuthElementsGenerator {
  53. public List<ListElement> getKnuthElement(LayoutContext context, int alignment) {
  54. List<ListElement> knuthList = new LinkedList<ListElement>();
  55. LayoutManager childLM = getChildLM();
  56. while (!childLM.isFinished()) {
  57. LayoutContext childLC = makeChildLayoutContext(context);
  58. List childElements = childLM.getNextKnuthElements(childLC, alignment);
  59. if (childElements != null) {
  60. List<ListElement> newList = new LinkedList<ListElement>();
  61. wrapPositionElements(childElements, newList);
  62. knuthList.addAll(newList);
  63. }
  64. }
  65. return knuthList;
  66. }
  67. }
  68. private class WhitespaceManagement implements KnuthElementsGenerator {
  69. public List<ListElement> getKnuthElement(LayoutContext context, int alignment) {
  70. MultiSwitchLayoutManager mslm = MultiSwitchLayoutManager.this;
  71. List<ListElement> knuthList = new LinkedList<ListElement>();
  72. WhitespaceManagementPenalty penalty = new WhitespaceManagementPenalty(
  73. new WhitespaceManagementPosition(mslm));
  74. LayoutManager childLM;
  75. while ((childLM = getChildLM()) != null) {
  76. if (!childLM.isFinished()) {
  77. LayoutContext childLC = makeChildLayoutContext(context);
  78. List childElements = childLM.getNextKnuthElements(childLC, alignment);
  79. if (childElements != null) {
  80. List<ListElement> newList = new LinkedList<ListElement>();
  81. wrapPositionElements(childElements, newList);
  82. // TODO Doing space resolution here is wrong.
  83. SpaceResolver.resolveElementList(newList);
  84. int contentLength = ElementListUtils.calcContentLength(newList);
  85. penalty.addVariant(penalty.new Variant(newList, contentLength));
  86. }
  87. }
  88. }
  89. // Prevent the penalty from being ignored if it is at the beginning of the content
  90. knuthList.add(new KnuthBox(0, new Position(mslm), false));
  91. knuthList.add(penalty);
  92. // Prevent the penalty from being ignored if it is at the end of the content
  93. knuthList.add(new KnuthBox(0, new Position(mslm), false));
  94. return knuthList;
  95. }
  96. }
  97. private KnuthElementsGenerator knuthGen;
  98. public MultiSwitchLayoutManager(FObj node) {
  99. super(node);
  100. MultiSwitch multiSwitchNode = (MultiSwitch) node;
  101. if (multiSwitchNode.getAutoToggle() == Constants.EN_SELECT_FIRST_FITTING) {
  102. knuthGen = new WhitespaceManagement();
  103. } else {
  104. knuthGen = new DefaultKnuthListGenerator();
  105. }
  106. }
  107. @Override
  108. public List<ListElement> getNextKnuthElements(LayoutContext context, int alignment) {
  109. referenceIPD = context.getRefIPD();
  110. List<ListElement> knuthList = knuthGen.getKnuthElement(context, alignment);
  111. setFinished(true);
  112. return knuthList;
  113. }
  114. @Override
  115. public Area getParentArea(Area childArea) {
  116. return parentLayoutManager.getParentArea(childArea);
  117. }
  118. @Override
  119. public void addChildArea(Area childArea) {
  120. parentLayoutManager.addChildArea(childArea);
  121. }
  122. @Override
  123. public void addAreas(PositionIterator posIter, LayoutContext context) {
  124. LinkedList<Position> positionList = new LinkedList<Position>();
  125. while (posIter.hasNext()) {
  126. Position pos = posIter.next();
  127. if (pos instanceof WhitespaceManagementPosition) {
  128. positionList.addAll(((WhitespaceManagementPosition) pos).getPositionList());
  129. } else {
  130. positionList.add(pos);
  131. }
  132. }
  133. PositionIterator newPosIter = new PositionIterator(positionList.listIterator());
  134. AreaAdditionUtil.addAreas(this, newPosIter, context);
  135. flush();
  136. }
  137. }