Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

EffRow.java 10KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  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.fo.flow.table;
  19. import java.util.Iterator;
  20. import java.util.List;
  21. import org.apache.fop.fo.Constants;
  22. import org.apache.fop.layoutmgr.Keep;
  23. import org.apache.fop.layoutmgr.table.TableRowIterator;
  24. import org.apache.fop.traits.MinOptMax;
  25. import org.apache.fop.util.BreakUtil;
  26. /**
  27. * This class represents an effective row in a table and holds a list of grid units occupying
  28. * the row as well as some additional values.
  29. */
  30. public class EffRow {
  31. /** Indicates that the row is the first in a table-body */
  32. public static final int FIRST_IN_PART = GridUnit.FIRST_IN_PART;
  33. /** Indicates that the row is the last in a table-body */
  34. public static final int LAST_IN_PART = GridUnit.LAST_IN_PART;
  35. private List gridUnits = new java.util.ArrayList();
  36. private int index;
  37. /** One of HEADER, FOOTER, BODY */
  38. private int bodyType;
  39. private MinOptMax height;
  40. private MinOptMax explicitHeight;
  41. /**
  42. * Creates a new effective row instance.
  43. * @param index index of the row
  44. * @param bodyType type of body (one of HEADER, FOOTER, BODY as found on TableRowIterator)
  45. * @param gridUnits the grid units this row is made of
  46. */
  47. public EffRow(int index, int bodyType, List gridUnits) {
  48. this.index = index;
  49. this.bodyType = bodyType;
  50. this.gridUnits = gridUnits;
  51. // TODO this is ugly, but we may eventually be able to do without that index
  52. for (Iterator guIter = gridUnits.iterator(); guIter.hasNext();) {
  53. Object gu = guIter.next();
  54. if (gu instanceof PrimaryGridUnit) {
  55. ((PrimaryGridUnit) gu).setRowIndex(index);
  56. }
  57. }
  58. }
  59. /** @return the index of the EffRow in the sequence of rows */
  60. public int getIndex() {
  61. return this.index;
  62. }
  63. /**
  64. * @return an indicator what type of body this EffRow is in (one of HEADER, FOOTER, BODY
  65. * as found on TableRowIterator)
  66. */
  67. public int getBodyType() {
  68. return this.bodyType;
  69. }
  70. /** @return the table-row FO for this EffRow, or null if there is no table-row. */
  71. public TableRow getTableRow() {
  72. return getGridUnit(0).getRow();
  73. }
  74. /**
  75. * Returns the calculated height for this EffRow, including the cells'
  76. * bpds/paddings/borders, and the table's border-separation.
  77. *
  78. * @return the row's height
  79. */
  80. public MinOptMax getHeight() {
  81. return this.height;
  82. }
  83. /**
  84. * Sets the calculated height for this EffRow, including everything (cells' bpds,
  85. * paddings, borders, and border-separation).
  86. *
  87. * @param mom the calculated height
  88. */
  89. public void setHeight(MinOptMax mom) {
  90. this.height = mom;
  91. }
  92. /** @return the explicit height of the EffRow (as specified through properties) */
  93. public MinOptMax getExplicitHeight() {
  94. return this.explicitHeight;
  95. }
  96. /**
  97. * Sets the height for this row that resulted from the explicit height properties specified
  98. * by the user.
  99. * @param mom the height
  100. */
  101. public void setExplicitHeight(MinOptMax mom) {
  102. this.explicitHeight = mom;
  103. }
  104. /** @return the list of GridUnits for this EffRow */
  105. public List getGridUnits() {
  106. return gridUnits;
  107. }
  108. /**
  109. * Returns the grid unit at a given position.
  110. * @param column index of the grid unit in the row (zero based)
  111. * @return the requested grid unit.
  112. */
  113. public GridUnit getGridUnit(int column) {
  114. return (GridUnit)gridUnits.get(column);
  115. }
  116. /**
  117. * Returns the grid unit at a given position. In contrast to getGridUnit() this
  118. * method returns null if there's no grid unit at the given position. The number of
  119. * grid units for row x can be smaller than the number of grid units for row x-1.
  120. * @param column index of the grid unit in the row (zero based)
  121. * @return the requested grid unit or null if there's no grid unit at this position.
  122. */
  123. public GridUnit safelyGetGridUnit(int column) {
  124. if (column < gridUnits.size()) {
  125. return (GridUnit)gridUnits.get(column);
  126. } else {
  127. return null;
  128. }
  129. }
  130. /**
  131. * Returns a flag for this effective row. Only a subset of the flags on GridUnit is supported.
  132. * The flag is determined by inspecting flags on the EffRow's GridUnits.
  133. * @param which the requested flag (one of {@link EffRow#FIRST_IN_PART} or {@link
  134. * EffRow#LAST_IN_PART})
  135. * @return true if the flag is set
  136. */
  137. public boolean getFlag(int which) {
  138. if (which == FIRST_IN_PART) {
  139. return getGridUnit(0).getFlag(GridUnit.FIRST_IN_PART);
  140. } else if (which == LAST_IN_PART) {
  141. return getGridUnit(0).getFlag(GridUnit.LAST_IN_PART);
  142. } else {
  143. throw new IllegalArgumentException("Illegal flag queried: " + which);
  144. }
  145. }
  146. /**
  147. * Returns the strength of the keep constraint if the enclosing (if any) fo:table-row element
  148. * of this row, or if any of the cells starting on this row, have keep-with-previous set.
  149. *
  150. * @return the strength of the keep-with-previous constraint
  151. */
  152. public Keep getKeepWithPrevious() {
  153. Keep keep = Keep.KEEP_AUTO;
  154. TableRow row = getTableRow();
  155. if (row != null) {
  156. keep = Keep.getKeep(row.getKeepWithPrevious());
  157. }
  158. for (Iterator iter = gridUnits.iterator(); iter.hasNext();) {
  159. GridUnit gu = (GridUnit) iter.next();
  160. if (gu.isPrimary()) {
  161. keep = keep.compare(gu.getPrimary().getKeepWithPrevious());
  162. }
  163. }
  164. return keep;
  165. }
  166. /**
  167. * Returns the strength of the keep constraint if the enclosing (if any) fo:table-row element
  168. * of this row, or if any of the cells ending on this row, have keep-with-next set.
  169. *
  170. * @return the strength of the keep-with-next constraint
  171. */
  172. public Keep getKeepWithNext() {
  173. Keep keep = Keep.KEEP_AUTO;
  174. TableRow row = getTableRow();
  175. if (row != null) {
  176. keep = Keep.getKeep(row.getKeepWithNext());
  177. }
  178. for (Iterator iter = gridUnits.iterator(); iter.hasNext();) {
  179. GridUnit gu = (GridUnit) iter.next();
  180. if (!gu.isEmpty() && gu.getColSpanIndex() == 0 && gu.isLastGridUnitRowSpan()) {
  181. keep = keep.compare(gu.getPrimary().getKeepWithNext());
  182. }
  183. }
  184. return keep;
  185. }
  186. /**
  187. * Returns the keep-together strength for this element. Note: The keep strength returned does
  188. * not take the parent table's keeps into account!
  189. * @return the keep-together strength
  190. */
  191. public Keep getKeepTogether() {
  192. TableRow row = getTableRow();
  193. Keep keep = Keep.KEEP_AUTO;
  194. if (row != null) {
  195. keep = Keep.getKeep(row.getKeepTogether());
  196. }
  197. return keep;
  198. }
  199. /**
  200. * Returns the break class for this row. This is a combination of break-before set on
  201. * the first children of any cells starting on this row.
  202. * <p><strong>Note:</strong> this method doesn't take into account break-before set on
  203. * the enclosing fo:table-row element, if any, as it must be ignored if the row
  204. * belongs to a group of spanned rows (see XSL-FO 1.1, 7.20.2).
  205. * <p><strong>Note:</strong> this works only after getNextKuthElements on the
  206. * corresponding TableCellLM have been called!</p>
  207. *
  208. * @return one of {@link Constants#EN_AUTO}, {@link Constants#EN_COLUMN}, {@link
  209. * Constants#EN_PAGE}, {@link Constants#EN_EVEN_PAGE}, {@link Constants#EN_ODD_PAGE}
  210. */
  211. public int getBreakBefore() {
  212. int breakBefore = Constants.EN_AUTO;
  213. for (Iterator iter = gridUnits.iterator(); iter.hasNext();) {
  214. GridUnit gu = (GridUnit) iter.next();
  215. if (gu.isPrimary()) {
  216. breakBefore = BreakUtil.compareBreakClasses(breakBefore,
  217. gu.getPrimary().getBreakBefore());
  218. }
  219. }
  220. return breakBefore;
  221. }
  222. /**
  223. * Returns the break class for this row. This is a combination of break-after set on
  224. * the last children of any cells ending on this row.
  225. * <p><strong>Note:</strong> this method doesn't take into account break-after set on
  226. * the enclosing fo:table-row element, if any, as it must be ignored if the row
  227. * belongs to a group of spanned rows (see XSL-FO 1.1, 7.20.1).
  228. * <p><strong>Note:</strong> this works only after getNextKuthElements on the
  229. * corresponding TableCellLM have been called!</p>
  230. *
  231. * @return one of {@link Constants#EN_AUTO}, {@link Constants#EN_COLUMN}, {@link
  232. * Constants#EN_PAGE}, {@link Constants#EN_EVEN_PAGE}, {@link Constants#EN_ODD_PAGE}
  233. */
  234. public int getBreakAfter() {
  235. int breakAfter = Constants.EN_AUTO;
  236. for (Iterator iter = gridUnits.iterator(); iter.hasNext();) {
  237. GridUnit gu = (GridUnit) iter.next();
  238. if (!gu.isEmpty() && gu.getColSpanIndex() == 0 && gu.isLastGridUnitRowSpan()) {
  239. breakAfter = BreakUtil.compareBreakClasses(breakAfter,
  240. gu.getPrimary().getBreakAfter());
  241. }
  242. }
  243. return breakAfter;
  244. }
  245. /** {@inheritDoc} */
  246. public String toString() {
  247. StringBuffer sb = new StringBuffer("EffRow {");
  248. sb.append(index);
  249. if (getBodyType() == TableRowIterator.BODY) {
  250. sb.append(" in body");
  251. } else if (getBodyType() == TableRowIterator.HEADER) {
  252. sb.append(" in header");
  253. } else {
  254. sb.append(" in footer");
  255. }
  256. sb.append(", ").append(height);
  257. sb.append(", ").append(explicitHeight);
  258. sb.append(", ").append(gridUnits.size()).append(" gu");
  259. sb.append("}");
  260. return sb.toString();
  261. }
  262. }