001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /* $Id: TableRow.java 554104 2007-07-07 01:07:10Z adelmelle $ */
019:
020: package org.apache.fop.fo.flow;
021:
022: import java.util.BitSet;
023: import java.util.List;
024:
025: import org.xml.sax.Attributes;
026: import org.xml.sax.Locator;
027:
028: import org.apache.fop.apps.FOPException;
029: import org.apache.fop.datatypes.Length;
030: import org.apache.fop.fo.FONode;
031: import org.apache.fop.fo.PropertyList;
032: import org.apache.fop.fo.ValidationException;
033: import org.apache.fop.fo.properties.CommonAccessibility;
034: import org.apache.fop.fo.properties.CommonAural;
035: import org.apache.fop.fo.properties.CommonBorderPaddingBackground;
036: import org.apache.fop.fo.properties.CommonRelativePosition;
037: import org.apache.fop.fo.properties.KeepProperty;
038: import org.apache.fop.fo.properties.LengthRangeProperty;
039:
040: /**
041: * Class modelling the fo:table-row object.
042: */
043: public class TableRow extends TableFObj {
044: // The value of properties relevant for fo:table-row.
045: private LengthRangeProperty blockProgressionDimension;
046: private CommonBorderPaddingBackground commonBorderPaddingBackground;
047: private int breakAfter;
048: private int breakBefore;
049: private Length height;
050: private KeepProperty keepTogether;
051: private KeepProperty keepWithNext;
052: private KeepProperty keepWithPrevious;
053: // Unused but valid items, commented out for performance:
054: // private CommonAccessibility commonAccessibility;
055: // private CommonAural commonAural;
056: // private CommonRelativePosition commonRelativePosition;
057: // private int visibility;
058: // End of property values
059:
060: private boolean setup = false;
061:
062: protected List pendingSpans;
063: protected BitSet usedColumnIndices;
064: private int columnIndex = 1;
065:
066: /**
067: * @param parent FONode that is the parent of this object
068: */
069: public TableRow(FONode parent) {
070: super (parent);
071: }
072:
073: /**
074: * @see org.apache.fop.fo.FObj#bind(PropertyList)
075: */
076: public void bind(PropertyList pList) throws FOPException {
077: blockProgressionDimension = pList.get(
078: PR_BLOCK_PROGRESSION_DIMENSION).getLengthRange();
079: commonBorderPaddingBackground = pList
080: .getBorderPaddingBackgroundProps();
081: breakAfter = pList.get(PR_BREAK_AFTER).getEnum();
082: breakBefore = pList.get(PR_BREAK_BEFORE).getEnum();
083: height = pList.get(PR_HEIGHT).getLength();
084: keepTogether = pList.get(PR_KEEP_TOGETHER).getKeep();
085: keepWithNext = pList.get(PR_KEEP_WITH_NEXT).getKeep();
086: keepWithPrevious = pList.get(PR_KEEP_WITH_PREVIOUS).getKeep();
087: super .bind(pList);
088: }
089:
090: /**
091: * @see org.apache.fop.fo.FONode#processNode(String, Locator,
092: * Attributes, PropertyList)
093: */
094: public void processNode(String elementName, Locator locator,
095: Attributes attlist, PropertyList pList) throws FOPException {
096: if (!inMarker()) {
097: TableBody body = (TableBody) parent;
098: body.resetColumnIndex();
099: pendingSpans = body.pendingSpans;
100: usedColumnIndices = body.usedColumnIndices;
101: while (usedColumnIndices.get(columnIndex - 1)) {
102: columnIndex++;
103: }
104: }
105: super .processNode(elementName, locator, attlist, pList);
106: }
107:
108: /**
109: * @see org.apache.fop.fo.FONode#addChildNode(FONode)
110: */
111: protected void addChildNode(FONode child) throws FOPException {
112: if (!inMarker()) {
113: Table t = getTable();
114: TableBody body = (TableBody) getParent();
115: if (body.isFirst(this )) {
116: TableCell cell = (TableCell) child;
117: int colNr = cell.getColumnNumber();
118: int colSpan = cell.getNumberColumnsSpanned();
119: Length colWidth = null;
120:
121: if (cell.getWidth().getEnum() != EN_AUTO
122: && colSpan == 1) {
123: colWidth = cell.getWidth();
124: }
125:
126: for (int i = colNr; i < colNr + colSpan; ++i) {
127: if (t.columns.size() < i
128: || t.columns.get(i - 1) == null) {
129: t.addDefaultColumn(colWidth, i == colNr ? cell
130: .getColumnNumber() : 0);
131: } else {
132: TableColumn col = (TableColumn) t.columns
133: .get(i - 1);
134: if (!col.isDefaultColumn() && colWidth != null) {
135: col.setColumnWidth(colWidth);
136: }
137: }
138: }
139: }
140: }
141: super .addChildNode(child);
142: }
143:
144: /**
145: * @see org.apache.fop.fo.FONode#startOfNode
146: */
147: protected void startOfNode() throws FOPException {
148: super .startOfNode();
149: getFOEventHandler().startRow(this );
150: }
151:
152: /**
153: * @see org.apache.fop.fo.FONode#endOfNode
154: */
155: protected void endOfNode() throws FOPException {
156: if (firstChild == null) {
157: missingChildElementError("(table-cell+)");
158: }
159: if (!inMarker()) {
160: pendingSpans = null;
161: usedColumnIndices = null;
162: }
163: getFOEventHandler().endRow(this );
164: }
165:
166: /**
167: * @see org.apache.fop.fo.FONode#validateChildNode(Locator, String, String)
168: * XSL Content Model: (table-cell+)
169: */
170: protected void validateChildNode(Locator loc, String nsURI,
171: String localName) throws ValidationException {
172: if (!(FO_URI.equals(nsURI) && localName.equals("table-cell"))) {
173: invalidChildError(loc, nsURI, localName);
174: }
175: }
176:
177: /** @return the "break-after" property. */
178: public int getBreakAfter() {
179: return breakAfter;
180: }
181:
182: /** @return the "break-before" property. */
183: public int getBreakBefore() {
184: return breakBefore;
185: }
186:
187: /** @return the "keep-with-previous" property. */
188: public KeepProperty getKeepWithPrevious() {
189: return keepWithPrevious;
190: }
191:
192: /** @return the "keep-with-next" property. */
193: public KeepProperty getKeepWithNext() {
194: return keepWithNext;
195: }
196:
197: /** @return the "keep-together" property. */
198: public KeepProperty getKeepTogether() {
199: return keepTogether;
200: }
201:
202: /**
203: * Convenience method to check if a keep-together
204: * constraint is specified.
205: * @return true if keep-together is active.
206: */
207: public boolean mustKeepTogether() {
208: return !getKeepTogether().getWithinPage().isAuto()
209: || !getKeepTogether().getWithinColumn().isAuto();
210: }
211:
212: /**
213: * Convenience method to check if a keep-with-next
214: * constraint is specified.
215: * @return true if keep-with-next is active.
216: */
217: public boolean mustKeepWithNext() {
218: return !getKeepWithNext().getWithinPage().isAuto()
219: || !getKeepWithNext().getWithinColumn().isAuto();
220: }
221:
222: /**
223: * Convenience method to check if a keep-with-previous
224: * constraint is specified.
225: * @return true if keep-with-previous is active.
226: */
227: public boolean mustKeepWithPrevious() {
228: return !getKeepWithPrevious().getWithinPage().isAuto()
229: || !getKeepWithPrevious().getWithinColumn().isAuto();
230: }
231:
232: /**
233: * @return the "block-progression-dimension" property.
234: */
235: public LengthRangeProperty getBlockProgressionDimension() {
236: return blockProgressionDimension;
237: }
238:
239: /**
240: * @return the "height" property.
241: */
242: public Length getHeight() {
243: return height;
244: }
245:
246: /**
247: * @return the Common Border, Padding, and Background Properties.
248: */
249: public CommonBorderPaddingBackground getCommonBorderPaddingBackground() {
250: return commonBorderPaddingBackground;
251: }
252:
253: /** @see org.apache.fop.fo.FONode#getLocalName() */
254: public String getLocalName() {
255: return "table-row";
256: }
257:
258: /** @see org.apache.fop.fo.FObj#getNameId() */
259: public int getNameId() {
260: return FO_TABLE_ROW;
261: }
262:
263: /**
264: * Returns the current column index of the TableRow
265: *
266: * @return the next column number to use
267: */
268: public int getCurrentColumnIndex() {
269: return columnIndex;
270: }
271:
272: /**
273: * Sets the current column index to a specific value
274: * in case a column-number was explicitly specified
275: * (used by ColumnNumberPropertyMaker.make())
276: *
277: * @param newIndex new value for column index
278: */
279: public void setCurrentColumnIndex(int newIndex) {
280: columnIndex = newIndex;
281: }
282:
283: /**
284: * Checks whether a given column-number is already in use
285: * for the current row (used by TableCell.bind());
286: *
287: * @param colNr the column-number to check
288: * @return true if column-number is already occupied
289: */
290: public boolean isColumnNumberUsed(int colNr) {
291: return usedColumnIndices.get(colNr - 1);
292: }
293:
294: /**
295: * @see org.apache.fop.fo.flow.TableFObj#flagColumnIndices(int, int)
296: */
297: protected void flagColumnIndices(int start, int end) {
298: for (int i = start; i < end; i++) {
299: usedColumnIndices.set(i);
300: }
301: // update columnIndex for the next cell
302: while (usedColumnIndices.get(columnIndex - 1)) {
303: columnIndex++;
304: }
305: }
306: }
|