Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

FixedColRowGroupBuilder.java 6.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  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.ArrayList;
  20. import java.util.Iterator;
  21. import java.util.List;
  22. import java.util.ListIterator;
  23. import org.apache.fop.fo.Constants;
  24. import org.apache.fop.fo.ValidationException;
  25. /**
  26. * A row group builder optimised for a fixed number of columns, known before the parsing
  27. * of cells starts (that is, if the fo:table has explicit fo:table-column children).
  28. */
  29. class FixedColRowGroupBuilder extends RowGroupBuilder {
  30. /** Number of columns in the corresponding table. */
  31. private int numberOfColumns;
  32. private TableRow currentTableRow = null;
  33. /** 0-based, index in the row group. */
  34. private int currentRowIndex;
  35. /** The rows belonging to this row group. List of List of {@link GridUnit}s. */
  36. private List/*<List<GridUnit>>*/ rows;
  37. private boolean firstInPart = true;
  38. /** The last encountered row. This is the last row of the table if it has no footer. */
  39. private List lastRow;
  40. private BorderResolver borderResolver;
  41. FixedColRowGroupBuilder(Table t) {
  42. super(t);
  43. numberOfColumns = t.getNumberOfColumns();
  44. if (t.isSeparateBorderModel()) {
  45. borderResolver = new SeparateBorderResolver();
  46. } else {
  47. borderResolver = new CollapsingBorderResolver(t);
  48. }
  49. initialize();
  50. }
  51. /**
  52. * Prepares this builder for creating a new row group.
  53. */
  54. private void initialize() {
  55. rows = new ArrayList();
  56. currentRowIndex = 0;
  57. }
  58. /** {@inheritDoc} */
  59. void addTableCell(TableCell cell) {
  60. for (int i = rows.size(); i < currentRowIndex + cell.getNumberRowsSpanned(); i++) {
  61. List effRow = new ArrayList(numberOfColumns);
  62. for (int j = 0; j < numberOfColumns; j++) {
  63. effRow.add(null);
  64. }
  65. rows.add(effRow);
  66. }
  67. int columnIndex = cell.getColumnNumber() - 1;
  68. PrimaryGridUnit pgu = new PrimaryGridUnit(cell, columnIndex);
  69. List row = (List) rows.get(currentRowIndex);
  70. row.set(columnIndex, pgu);
  71. // TODO
  72. GridUnit[] cellRow = new GridUnit[cell.getNumberColumnsSpanned()];
  73. cellRow[0] = pgu;
  74. for (int j = 1; j < cell.getNumberColumnsSpanned(); j++) {
  75. GridUnit gu = new GridUnit(pgu, j, 0);
  76. row.set(columnIndex + j, gu);
  77. cellRow[j] = gu;
  78. }
  79. pgu.addRow(cellRow);
  80. for (int i = 1; i < cell.getNumberRowsSpanned(); i++) {
  81. row = (List) rows.get(currentRowIndex + i);
  82. cellRow = new GridUnit[cell.getNumberColumnsSpanned()];
  83. for (int j = 0; j < cell.getNumberColumnsSpanned(); j++) {
  84. GridUnit gu = new GridUnit(pgu, j, i);
  85. row.set(columnIndex + j, gu);
  86. cellRow[j] = gu;
  87. }
  88. pgu.addRow(cellRow);
  89. }
  90. }
  91. private static void setFlagForCols(int flag, List row) {
  92. for (ListIterator iter = row.listIterator(); iter.hasNext();) {
  93. ((GridUnit) iter.next()).setFlag(flag);
  94. }
  95. }
  96. /** {@inheritDoc} */
  97. void startTableRow(TableRow tableRow) {
  98. currentTableRow = tableRow;
  99. }
  100. /** {@inheritDoc} */
  101. void endTableRow() {
  102. assert currentTableRow != null;
  103. if (currentRowIndex > 0 && currentTableRow.getBreakBefore() != Constants.EN_AUTO) {
  104. TableEventProducer eventProducer = TableEventProducer.Provider.get(
  105. currentTableRow.getUserAgent().getEventBroadcaster());
  106. eventProducer.breakIgnoredDueToRowSpanning(this, currentTableRow.getName(), true,
  107. currentTableRow.getLocator());
  108. }
  109. if (currentRowIndex < rows.size() - 1
  110. && currentTableRow.getBreakAfter() != Constants.EN_AUTO) {
  111. TableEventProducer eventProducer = TableEventProducer.Provider.get(
  112. currentTableRow.getUserAgent().getEventBroadcaster());
  113. eventProducer.breakIgnoredDueToRowSpanning(this, currentTableRow.getName(), false,
  114. currentTableRow.getLocator());
  115. }
  116. for (Iterator iter = ((List) rows.get(currentRowIndex)).iterator(); iter.hasNext();) {
  117. GridUnit gu = (GridUnit) iter.next();
  118. // The row hasn't been filled with empty grid units yet
  119. if (gu != null) {
  120. gu.setRow(currentTableRow);
  121. }
  122. }
  123. handleRowEnd(currentTableRow);
  124. }
  125. /** {@inheritDoc} */
  126. void endRow(TablePart part) {
  127. handleRowEnd(part);
  128. }
  129. private void handleRowEnd(TableCellContainer container) {
  130. List currentRow = (List) rows.get(currentRowIndex);
  131. lastRow = currentRow;
  132. // Fill gaps with empty grid units
  133. for (int i = 0; i < numberOfColumns; i++) {
  134. if (currentRow.get(i) == null) {
  135. currentRow.set(i, new EmptyGridUnit(table, currentTableRow, i));
  136. }
  137. }
  138. borderResolver.endRow(currentRow, container);
  139. if (firstInPart) {
  140. setFlagForCols(GridUnit.FIRST_IN_PART, currentRow);
  141. firstInPart = false;
  142. }
  143. if (currentRowIndex == rows.size() - 1) {
  144. // Means that the current row has no cell spanning over following rows
  145. container.getTablePart().addRowGroup(rows);
  146. initialize();
  147. } else {
  148. currentRowIndex++;
  149. }
  150. currentTableRow = null;
  151. }
  152. /** {@inheritDoc} */
  153. void startTablePart(TablePart part) {
  154. firstInPart = true;
  155. borderResolver.startPart(part);
  156. }
  157. /** {@inheritDoc} */
  158. void endTablePart() throws ValidationException {
  159. if (rows.size() > 0) {
  160. throw new ValidationException(
  161. "A table-cell is spanning more rows than available in its parent element.");
  162. }
  163. setFlagForCols(GridUnit.LAST_IN_PART, lastRow);
  164. borderResolver.endPart();
  165. }
  166. /** {@inheritDoc} */
  167. void endTable() {
  168. borderResolver.endTable();
  169. }
  170. }