Source Code Cross Referenced for RowPainter.java in  » Graphic-Library » fop » org » apache » fop » layoutmgr » table » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Graphic Library » fop » org.apache.fop.layoutmgr.table 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


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: RowPainter.java 555651 2007-07-12 14:59:06Z vhennebert $ */
019:
020:        package org.apache.fop.layoutmgr.table;
021:
022:        import java.util.Arrays;
023:        import java.util.Iterator;
024:        import java.util.Map;
025:
026:        import org.apache.commons.logging.Log;
027:        import org.apache.commons.logging.LogFactory;
028:        import org.apache.fop.fo.flow.TableRow;
029:        import org.apache.fop.fo.properties.LengthRangeProperty;
030:        import org.apache.fop.layoutmgr.ElementListUtils;
031:        import org.apache.fop.layoutmgr.KnuthElement;
032:        import org.apache.fop.layoutmgr.KnuthPossPosIter;
033:        import org.apache.fop.layoutmgr.LayoutContext;
034:        import org.apache.fop.layoutmgr.SpaceResolver;
035:
036:        class RowPainter {
037:            private static Log log = LogFactory.getLog(RowPainter.class);
038:            /** The fo:table-row containing the currently handled grid rows. */
039:            private TableRow rowFO = null;
040:            private int colCount;
041:            private int yoffset = 0;
042:            private int accumulatedBPD = 0;
043:            /** Currently handled row (= last encountered row). */
044:            private EffRow lastRow = null;
045:            private LayoutContext layoutContext;
046:            /**
047:             * For each part of the table (header, footer, body), index of the first row of that
048:             * part present on the current page.
049:             */
050:            private int[] firstRow = new int[3];
051:            /**
052:             * Keeps track of the y-offsets of each row on a page (for body, header and footer separately).
053:             * This is particularly needed for spanned cells where you need to know the y-offset
054:             * of the starting row when the area is generated at the time the cell is closed.
055:             */
056:            private Map[] rowOffsets = new Map[] { new java.util.HashMap(),
057:                    new java.util.HashMap(), new java.util.HashMap() };
058:
059:            //These three variables are our buffer to recombine the individual steps into cells
060:            /** Primary grid units corresponding to the currently handled grid units, per row. */
061:            private PrimaryGridUnit[] primaryGridUnits;
062:            /**
063:             * Index, in the corresponding table cell's list of Knuth elements, of the first
064:             * element present on the current page, per column.
065:             */
066:            private int[] start;
067:            /**
068:             * Index, in the corresponding table cell's list of Knuth elements, of the last
069:             * element present on the current page, per column.
070:             */
071:            private int[] end;
072:            /**
073:             * Length, for each column, of the elements from the current cell put on the
074:             * current page. This is the corresponding area's bpd.
075:             */
076:            private int[] partBPD;
077:            private TableContentLayoutManager tclm;
078:
079:            public RowPainter(TableContentLayoutManager tclm,
080:                    LayoutContext layoutContext) {
081:                this .tclm = tclm;
082:                this .layoutContext = layoutContext;
083:                this .colCount = tclm.getColumns().getColumnCount();
084:                this .primaryGridUnits = new PrimaryGridUnit[colCount];
085:                this .start = new int[colCount];
086:                this .end = new int[colCount];
087:                this .partBPD = new int[colCount];
088:                Arrays.fill(firstRow, -1);
089:                Arrays.fill(end, -1);
090:            }
091:
092:            public int getAccumulatedBPD() {
093:                return this .accumulatedBPD;
094:            }
095:
096:            /**
097:             * Records the fragment of row represented by the given position. If it belongs to
098:             * another (grid) row than the current one, that latter is painted and flushed first.
099:             * 
100:             * @param tcpos a position representing the row fragment
101:             */
102:            public void handleTableContentPosition(TableContentPosition tcpos) {
103:                if (lastRow != tcpos.row && lastRow != null) {
104:                    addAreasAndFlushRow(false);
105:                }
106:                if (log.isDebugEnabled()) {
107:                    log.debug("===handleTableContentPosition(" + tcpos);
108:                }
109:                rowFO = tcpos.row.getTableRow();
110:                lastRow = tcpos.row;
111:                Iterator partIter = tcpos.gridUnitParts.iterator();
112:                //Iterate over all grid units in the current step
113:                while (partIter.hasNext()) {
114:                    GridUnitPart gup = (GridUnitPart) partIter.next();
115:                    if (log.isDebugEnabled()) {
116:                        log.debug(">" + gup);
117:                    }
118:                    int colIndex = gup.pgu.getStartCol();
119:                    if (primaryGridUnits[colIndex] != gup.pgu) {
120:                        if (primaryGridUnits[colIndex] != null) {
121:                            log.warn("Replacing GU in slot " + colIndex
122:                                    + ". Some content may not be painted.");
123:                        }
124:                        primaryGridUnits[colIndex] = gup.pgu;
125:                        start[colIndex] = gup.start;
126:                        end[colIndex] = gup.end;
127:                    } else {
128:                        if (gup.end < end[colIndex]) {
129:                            throw new IllegalStateException(
130:                                    "Internal Error: stepper problem");
131:                        }
132:                        end[colIndex] = gup.end;
133:                    }
134:                }
135:            }
136:
137:            /**
138:             * Create the areas corresponding to the last row. This method is called either
139:             * because the row is finished (all of the elements present on this row have been
140:             * added), or because this is the last row on the current page, and the part of it
141:             * lying on the current page must be drawn.
142:             * 
143:             * @param forcedFlush true if the elements must be drawn even if the row isn't
144:             * finished yet (last row on the page), or if the row is the last of the current table
145:             * part
146:             * @return the height of the (grid) row
147:             */
148:            public int addAreasAndFlushRow(boolean forcedFlush) {
149:                int actualRowHeight = 0;
150:
151:                int bt = lastRow.getBodyType();
152:                if (log.isDebugEnabled()) {
153:                    log.debug("Remembering yoffset for row "
154:                            + lastRow.getIndex() + ": " + yoffset);
155:                }
156:                rowOffsets[bt].put(new Integer(lastRow.getIndex()),
157:                        new Integer(yoffset));
158:
159:                for (int i = 0; i < primaryGridUnits.length; i++) {
160:                    if ((primaryGridUnits[i] != null)
161:                            && (forcedFlush || (end[i] == primaryGridUnits[i]
162:                                    .getElements().size() - 1))) {
163:                        actualRowHeight = Math.max(actualRowHeight,
164:                                computeSpanHeight(primaryGridUnits[i],
165:                                        start[i], end[i], i, bt));
166:                    }
167:                }
168:                actualRowHeight += 2 * tclm.getTableLM()
169:                        .getHalfBorderSeparationBPD();
170:
171:                //Add areas for row
172:                tclm.addRowBackgroundArea(rowFO, actualRowHeight, layoutContext
173:                        .getRefIPD(), yoffset);
174:                for (int i = 0; i < primaryGridUnits.length; i++) {
175:                    GridUnit currentGU = lastRow.safelyGetGridUnit(i);
176:                    //currentGU can be null if there's no grid unit
177:                    //at this place in the current row (empty cell and no borders to process)
178:
179:                    if (primaryGridUnits[i] != null) {
180:                        if (forcedFlush
181:                                || ((end[i] == primaryGridUnits[i]
182:                                        .getElements().size() - 1) && (currentGU == null || currentGU
183:                                        .isLastGridUnitRowSpan()))) {
184:                            //the last line in the "if" above is to avoid a premature end of a
185:                            //row-spanned cell because no GridUnitParts are generated after a cell is
186:                            //finished with its content.
187:                            //See table-cell_number-rows-spanned_bug38397.xml
188:                            addAreasForCell(primaryGridUnits[i], start[i],
189:                                    end[i], lastRow, partBPD[i],
190:                                    actualRowHeight);
191:                            primaryGridUnits[i] = null;
192:                            start[i] = 0;
193:                            end[i] = -1;
194:                            partBPD[i] = 0;
195:                        }
196:                    } else if (currentGU != null
197:                            && !currentGU.isEmpty()
198:                            && currentGU.getColSpanIndex() == 0
199:                            && (forcedFlush || currentGU
200:                                    .isLastGridUnitRowSpan())) {
201:                        //A row-spanned cell has finished contributing content on the previous page
202:                        //and now still has to cause grid units to be painted.
203:                        //See table-cell_page-break_span.xml
204:                        addAreasForCell(currentGU.getPrimary(), start[i],
205:                                end[i], lastRow, partBPD[i], actualRowHeight);
206:                        start[i] = 0;
207:                        end[i] = -1;
208:                        partBPD[i] = 0;
209:                    }
210:                }
211:                yoffset += actualRowHeight;
212:                accumulatedBPD += actualRowHeight;
213:                if (forcedFlush) {
214:                    // Either the end of the page is reached, then this was the last call of this
215:                    // method and we no longer care about lastRow; or the end of a table-part
216:                    // (header, footer, body) has been reached, and the next row will anyway be
217:                    // different from the current one, and this is unnecessary to recall this
218:                    // method in the first lines of handleTableContentPosition, so we may reset
219:                    // lastRow
220:                    lastRow = null;
221:                }
222:                return actualRowHeight;
223:            }
224:
225:            /**
226:             * Computes the total height of the part of the given cell spanning on the current
227:             * active row, including borders and paddings. The bpd is also stored in partBPD, and
228:             * it is ensured that the cell's or row's explicit height is respected. yoffset is
229:             * updated accordingly.
230:             * 
231:             * @param pgu primary grid unit corresponding to the cell
232:             * @param start index of the first element of the cell occuring on the current page
233:             * @param end index of the last element of the cell occuring on the current page
234:             * @param columnIndex column index of the cell
235:             * @param bodyType {@link TableRowIterator#HEADER}, {@link TableRowIterator#FOOTER}, or
236:             * {@link TableRowIterator#BODY}
237:             * @return the cell's height
238:             */
239:            private int computeSpanHeight(PrimaryGridUnit pgu, int start,
240:                    int end, int columnIndex, int bodyType) {
241:                if (log.isTraceEnabled()) {
242:                    log.trace("getting len for " + columnIndex + " " + start
243:                            + "-" + end);
244:                }
245:                int actualStart = start;
246:                // Skip from the content length calculation glues and penalties occuring at the
247:                // beginning of the page
248:                while (actualStart <= end
249:                        && !((KnuthElement) pgu.getElements().get(actualStart))
250:                                .isBox()) {
251:                    actualStart++;
252:                }
253:                int len = ElementListUtils.calcContentLength(pgu.getElements(),
254:                        actualStart, end);
255:                KnuthElement el = (KnuthElement) pgu.getElements().get(end);
256:                if (el.isPenalty()) {
257:                    len += el.getW();
258:                }
259:                partBPD[columnIndex] = len;
260:                if (log.isTraceEnabled()) {
261:                    log.trace("len of part: " + len);
262:                }
263:
264:                if (start == 0) {
265:                    LengthRangeProperty bpd = pgu.getCell()
266:                            .getBlockProgressionDimension();
267:                    if (!bpd.getMinimum(tclm.getTableLM()).isAuto()) {
268:                        int min = bpd.getMinimum(tclm.getTableLM()).getLength()
269:                                .getValue(tclm.getTableLM());
270:                        if (min > 0) {
271:                            len = Math.max(len, min);
272:                        }
273:                    }
274:                    if (!bpd.getOptimum(tclm.getTableLM()).isAuto()) {
275:                        int opt = bpd.getOptimum(tclm.getTableLM()).getLength()
276:                                .getValue(tclm.getTableLM());
277:                        if (opt > 0) {
278:                            len = Math.max(len, opt);
279:                        }
280:                    }
281:                    if (pgu.getRow() != null) {
282:                        bpd = pgu.getRow().getBlockProgressionDimension();
283:                        if (!bpd.getMinimum(tclm.getTableLM()).isAuto()) {
284:                            int min = bpd.getMinimum(tclm.getTableLM())
285:                                    .getLength().getValue(tclm.getTableLM());
286:                            if (min > 0) {
287:                                len = Math.max(len, min);
288:                            }
289:                        }
290:                    }
291:                }
292:
293:                // Add the padding if any
294:                len += pgu.getBorders()
295:                        .getPaddingBefore(false, pgu.getCellLM());
296:                len += pgu.getBorders().getPaddingAfter(false, pgu.getCellLM());
297:
298:                //Now add the borders to the contentLength
299:                if (tclm.isSeparateBorderModel()) {
300:                    len += pgu.getBorders().getBorderBeforeWidth(false);
301:                    len += pgu.getBorders().getBorderAfterWidth(false);
302:                } else {
303:                    len += pgu.getHalfMaxBeforeBorderWidth();
304:                    len += pgu.getHalfMaxAfterBorderWidth();
305:                }
306:                int startRow = Math.max(pgu.getStartRow(), firstRow[bodyType]);
307:                Integer storedOffset = (Integer) rowOffsets[bodyType]
308:                        .get(new Integer(startRow));
309:                int effYOffset;
310:                if (storedOffset != null) {
311:                    effYOffset = storedOffset.intValue();
312:                } else {
313:                    effYOffset = yoffset;
314:                }
315:                len -= yoffset - effYOffset;
316:                return len;
317:            }
318:
319:            private void addAreasForCell(PrimaryGridUnit pgu, int startPos,
320:                    int endPos, EffRow row, int contentHeight, int rowHeight) {
321:                int bt = row.getBodyType();
322:                if (firstRow[bt] < 0) {
323:                    firstRow[bt] = row.getIndex();
324:                }
325:                //Determine the first row in this sequence
326:                int startRowIndex = Math.max(pgu.getStartRow(), firstRow[bt]);
327:                int lastRowIndex = lastRow.getIndex();
328:
329:                // In collapsing-border model, if the cell spans over several columns/rows then
330:                // dedicated areas will be created for each grid unit to hold the corresponding
331:                // borders. For that we need to know the height of each grid unit, that is of each
332:                // grid row spanned over by the cell
333:                int[] spannedGridRowHeights = null;
334:                if (!tclm.getTableLM().getTable().isSeparateBorderModel()
335:                        && pgu.hasSpanning()) {
336:                    spannedGridRowHeights = new int[lastRowIndex
337:                            - startRowIndex + 1];
338:                    int prevOffset = ((Integer) rowOffsets[bt].get(new Integer(
339:                            startRowIndex))).intValue();
340:                    for (int i = 0; i < lastRowIndex - startRowIndex; i++) {
341:                        int newOffset = ((Integer) rowOffsets[bt]
342:                                .get(new Integer(startRowIndex + i + 1)))
343:                                .intValue();
344:                        spannedGridRowHeights[i] = newOffset - prevOffset;
345:                        prevOffset = newOffset;
346:                    }
347:                    spannedGridRowHeights[lastRowIndex - startRowIndex] = rowHeight;
348:                }
349:
350:                //Determine y offset for the cell
351:                Integer offset = (Integer) rowOffsets[bt].get(new Integer(
352:                        startRowIndex));
353:                while (offset == null) {
354:                    //TODO Figure out what this does and when it's triggered
355:                    //This block is probably never used, at least it's not triggered by any of our tests
356:                    startRowIndex--;
357:                    offset = (Integer) rowOffsets[bt].get(new Integer(
358:                            startRowIndex));
359:                }
360:                int effYOffset = offset.intValue();
361:                int effCellHeight = rowHeight;
362:                effCellHeight += yoffset - effYOffset;
363:                if (log.isDebugEnabled()) {
364:                    log.debug("Creating area for cell:");
365:                    log.debug("  current row: " + row.getIndex());
366:                    log.debug("  start row: " + pgu.getStartRow() + " "
367:                            + yoffset + " " + effYOffset);
368:                    log.debug("  contentHeight: " + contentHeight
369:                            + " rowHeight=" + rowHeight + " effCellHeight="
370:                            + effCellHeight);
371:                }
372:                TableCellLayoutManager cellLM = pgu.getCellLM();
373:                cellLM.setXOffset(tclm.getXOffsetOfGridUnit(pgu));
374:                cellLM.setYOffset(effYOffset);
375:                cellLM.setContentHeight(contentHeight);
376:                cellLM.setRowHeight(effCellHeight);
377:                //cellLM.setRowHeight(row.getHeight().opt);
378:                int prevBreak = ElementListUtils.determinePreviousBreak(pgu
379:                        .getElements(), startPos);
380:                if (endPos >= 0) {
381:                    SpaceResolver.performConditionalsNotification(pgu
382:                            .getElements(), startPos, endPos, prevBreak);
383:                }
384:                cellLM.addAreas(new KnuthPossPosIter(pgu.getElements(),
385:                        startPos, endPos + 1), layoutContext,
386:                        spannedGridRowHeights, startRowIndex
387:                                - pgu.getStartRow(), lastRowIndex
388:                                - pgu.getStartRow() + 1);
389:            }
390:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.