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.

Body.java 6.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. /*
  2. * $Id$
  3. * Copyright (C) 2002 The Apache Software Foundation. All rights reserved.
  4. * For details on use and redistribution please refer to the
  5. * LICENSE file included with these sources.
  6. */
  7. package org.apache.fop.layoutmgr.table;
  8. import org.apache.fop.layoutmgr.BlockStackingLayoutManager;
  9. import org.apache.fop.layoutmgr.LeafPosition;
  10. import org.apache.fop.layoutmgr.BreakPoss;
  11. import org.apache.fop.layoutmgr.LayoutContext;
  12. import org.apache.fop.layoutmgr.PositionIterator;
  13. import org.apache.fop.layoutmgr.BreakPossPosIter;
  14. import org.apache.fop.layoutmgr.Position;
  15. import org.apache.fop.fo.FObj;
  16. import org.apache.fop.area.Area;
  17. import org.apache.fop.area.Block;
  18. import org.apache.fop.area.MinOptMax;
  19. import java.util.ArrayList;
  20. import java.util.List;
  21. /**
  22. * LayoutManager for a table-header, table-footer and table body FO.
  23. * These fo objects have either rows or cells underneath.
  24. * Cells are organised into rows.
  25. */
  26. public class Body extends BlockStackingLayoutManager {
  27. private boolean rows = true;
  28. private List columns;
  29. private int yoffset;
  30. private int bodyHeight;
  31. private Block curBlockArea;
  32. private ArrayList childBreaks = new ArrayList();
  33. /**
  34. * Create a new body layout manager.
  35. *
  36. * @param fobj the formatting object that created this manager
  37. */
  38. public Body(FObj fobj) {
  39. super(fobj);
  40. }
  41. /**
  42. * Set the columns from the table.
  43. *
  44. * @param cols the list of columns used for this body
  45. */
  46. public void setColumns(List cols) {
  47. columns = cols;
  48. }
  49. /**
  50. * Breaks for this layout manager are of the form of before
  51. * or after a row and inside a row.
  52. *
  53. * @param context the layout context for finding the breaks
  54. * @return the next break possibility
  55. */
  56. public BreakPoss getNextBreakPoss(LayoutContext context) {
  57. Row curLM; // currently active LM
  58. MinOptMax stackSize = new MinOptMax();
  59. BreakPoss lastPos = null;
  60. while ((curLM = (Row)getChildLM()) != null) {
  61. // Make break positions
  62. // Set up a LayoutContext
  63. int ipd = context.getRefIPD();
  64. BreakPoss bp;
  65. LayoutContext childLC = new LayoutContext(0);
  66. childLC.setStackLimit(
  67. MinOptMax.subtract(context.getStackLimit(),
  68. stackSize));
  69. childLC.setRefIPD(ipd);
  70. curLM.setColumns(columns);
  71. while (!curLM.isFinished()) {
  72. if ((bp = curLM.getNextBreakPoss(childLC)) != null) {
  73. stackSize.add(bp.getStackingSize());
  74. if (stackSize.opt > context.getStackLimit().max) {
  75. // reset to last break
  76. if (lastPos != null) {
  77. reset(lastPos.getPosition());
  78. } else {
  79. curLM.resetPosition(null);
  80. }
  81. break;
  82. }
  83. lastPos = bp;
  84. childBreaks.add(bp);
  85. childLC.setStackLimit(MinOptMax.subtract(
  86. context.getStackLimit(), stackSize));
  87. }
  88. }
  89. BreakPoss breakPoss = new BreakPoss(
  90. new LeafPosition(this, childBreaks.size() - 1));
  91. breakPoss.setStackingSize(stackSize);
  92. return breakPoss;
  93. }
  94. setFinished(true);
  95. return null;
  96. }
  97. /**
  98. * Set the y offset of this body within the table.
  99. * This is used to set the row offsets.
  100. *
  101. * @param off the y offset position
  102. */
  103. public void setYOffset(int off) {
  104. yoffset = off;
  105. }
  106. /**
  107. * Add the areas for the break points.
  108. * This sets the offset of each row as it is added.
  109. *
  110. * @param parentIter the position iterator
  111. * @param layoutContext the layout context for adding areas
  112. */
  113. public void addAreas(PositionIterator parentIter,
  114. LayoutContext layoutContext) {
  115. getParentArea(null);
  116. addID();
  117. Row childLM;
  118. int iStartPos = 0;
  119. LayoutContext lc = new LayoutContext(0);
  120. int rowoffset = 0;
  121. while (parentIter.hasNext()) {
  122. LeafPosition lfp = (LeafPosition) parentIter.next();
  123. // Add the block areas to Area
  124. PositionIterator breakPosIter =
  125. new BreakPossPosIter(childBreaks, iStartPos,
  126. lfp.getLeafPos() + 1);
  127. iStartPos = lfp.getLeafPos() + 1;
  128. int lastheight = 0;
  129. while ((childLM = (Row)breakPosIter.getNextChildLM()) != null) {
  130. childLM.setYOffset(yoffset + rowoffset);
  131. childLM.addAreas(breakPosIter, lc);
  132. lastheight = childLM.getRowHeight();
  133. }
  134. rowoffset += lastheight;
  135. }
  136. bodyHeight = rowoffset;
  137. flush();
  138. childBreaks.clear();
  139. curBlockArea = null;
  140. }
  141. /**
  142. * Get the body height of the body after adjusting.
  143. * Should only be called after adding the body areas.
  144. *
  145. * @return the body height of this body
  146. */
  147. public int getBodyHeight() {
  148. return bodyHeight;
  149. }
  150. /**
  151. * Return an Area which can contain the passed childArea. The childArea
  152. * may not yet have any content, but it has essential traits set.
  153. * In general, if the LayoutManager already has an Area it simply returns
  154. * it. Otherwise, it makes a new Area of the appropriate class.
  155. * It gets a parent area for its area by calling its parent LM.
  156. * Finally, based on the dimensions of the parent area, it initializes
  157. * its own area. This includes setting the content IPD and the maximum
  158. * BPD.
  159. *
  160. * @param childArea the child area
  161. * @return the parent are of the child
  162. */
  163. public Area getParentArea(Area childArea) {
  164. return parentLM.getParentArea(childArea);
  165. }
  166. /**
  167. * Add the child area.
  168. * The table-header, table-footer and table-body areas return
  169. * the areas return by the children.
  170. *
  171. * @param childArea the child area to add
  172. * @return unused
  173. */
  174. public boolean addChild(Area childArea) {
  175. return parentLM.addChild(childArea);
  176. }
  177. /**
  178. * Reset the position of the layout manager.
  179. *
  180. * @param resetPos the position to reset to
  181. */
  182. public void resetPosition(Position resetPos) {
  183. if (resetPos == null) {
  184. reset(null);
  185. }
  186. }
  187. }