Source Code Cross Referenced for InfiniteMajorAxisLayoutStep.java in  » Report » pentaho-report » org » jfree » report » layout » process » 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 » Report » pentaho report » org.jfree.report.layout.process 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         * ===========================================
003:         * JFreeReport : a free Java reporting library
004:         * ===========================================
005:         *
006:         * Project Info:  http://reporting.pentaho.org/
007:         *
008:         * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
009:         *
010:         * This library is free software; you can redistribute it and/or modify it under the terms
011:         * of the GNU Lesser General Public License as published by the Free Software Foundation;
012:         * either version 2.1 of the License, or (at your option) any later version.
013:         *
014:         * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
015:         * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016:         * See the GNU Lesser General Public License for more details.
017:         *
018:         * You should have received a copy of the GNU Lesser General Public License along with this
019:         * library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020:         * Boston, MA 02111-1307, USA.
021:         *
022:         * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
023:         * in the United States and other countries.]
024:         *
025:         * ------------
026:         * InfiniteMajorAxisLayoutStep.java
027:         * ------------
028:         * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029:         */package org.jfree.report.layout.process;
030:
031:        import org.jfree.report.ElementAlignment;
032:        import org.jfree.report.layout.model.BlockRenderBox;
033:        import org.jfree.report.layout.model.FinishedRenderNode;
034:        import org.jfree.report.layout.model.InlineRenderBox;
035:        import org.jfree.report.layout.model.LogicalPageBox;
036:        import org.jfree.report.layout.model.ParagraphPoolBox;
037:        import org.jfree.report.layout.model.ParagraphRenderBox;
038:        import org.jfree.report.layout.model.RenderBox;
039:        import org.jfree.report.layout.model.RenderLength;
040:        import org.jfree.report.layout.model.RenderNode;
041:        import org.jfree.report.layout.model.RenderableReplacedContent;
042:        import org.jfree.report.layout.model.RenderableText;
043:        import org.jfree.report.layout.model.WatermarkAreaBox;
044:        import org.jfree.report.layout.model.context.BoxDefinition;
045:        import org.jfree.report.layout.model.context.StaticBoxLayoutProperties;
046:        import org.jfree.report.layout.process.valign.BoxAlignContext;
047:        import org.jfree.report.layout.process.valign.InlineBlockAlignContext;
048:        import org.jfree.report.layout.process.valign.NodeAlignContext;
049:        import org.jfree.report.layout.process.valign.ReplacedContentAlignContext;
050:        import org.jfree.report.layout.process.valign.TextElementAlignContext;
051:        import org.jfree.report.layout.process.valign.VerticalAlignmentProcessor;
052:        import org.jfree.report.style.ElementStyleKeys;
053:        import org.jfree.report.util.geom.StrictGeomUtility;
054:        import org.jfree.util.Log;
055:
056:        /**
057:         * Computes the absolute layout. The computed height and y positions of all abolutely positioned elements will be stored
058:         * in the 'canvasY' and 'canvasHeight' properties of RenderNode. Percentages will be resolved to zero.
059:         *
060:         * @author Thomas Morgner
061:         */
062:        public final class InfiniteMajorAxisLayoutStep extends
063:                IterateVisualProcessStep {
064:            // Set the maximum height to an incredibly high value. This is now 2^43 micropoints or more than
065:            // 3000 kilometers. Please call me directly at any time if you need more space for printing.
066:            private static final long MAX_AUTO = StrictGeomUtility
067:                    .toInternalValue(0x80000000000L);
068:
069:            private MajorAxisParagraphBreakState breakState;
070:            private RenderBox continuedElement;
071:            private VerticalAlignmentProcessor processor;
072:
073:            public InfiniteMajorAxisLayoutStep() {
074:                this .breakState = new MajorAxisParagraphBreakState();
075:                this .processor = new VerticalAlignmentProcessor();
076:            }
077:
078:            public void compute(final LogicalPageBox pageBox) {
079:                this .breakState.deinit();
080:                this .continuedElement = null;
081:                try {
082:                    startProcessing(pageBox);
083:                } finally {
084:                    this .continuedElement = null;
085:                    this .breakState.deinit();
086:                }
087:            }
088:
089:            /**
090:             * Continues processing. The renderbox must have a valid x-layout (that is: X, content-X1, content-X2 and Width)
091:             *
092:             * @param box
093:             */
094:            public void continueComputation(final RenderBox box) {
095:                // This is most-likely wrong, but as we do not support inline-block elements yet, we can ignore this for now.
096:                if (box.getContentAreaX2() == 0 || box.getCachedWidth() == 0) {
097:                    throw new IllegalStateException(
098:                            "Box must be layouted a bit ..");
099:                }
100:
101:                this .breakState.deinit();
102:                this .continuedElement = box;
103:                startProcessing(box);
104:                this .continuedElement = null;
105:                this .breakState.deinit();
106:            }
107:
108:            protected boolean startBlockLevelBox(final RenderBox box) {
109:                if (box.isIgnorableForRendering()) {
110:                    return false;
111:                }
112:
113:                if (box.isCacheValid()) {
114:                    return false;
115:                }
116:
117:                // Compute the block-position of the box. The box is positioned relative to the previous silbling or
118:                // relative to the parent.
119:                box.setCachedY(computeVerticalBlockPosition(box));
120:
121:                if (breakState.isActive()) {
122:                    // No breakstate and not being suspended? Why this?
123:                    if (breakState.isSuspended() == false) {
124:                        throw new IllegalStateException("This cannot be.");
125:                    }
126:
127:                    // this way or another - we are suspended now. So there is no need to look
128:                    // at the children anymore ..
129:
130:                    // This code is only executed for inline-block elements. Inline-block elements are not part of
131:                    // the 0.8.9 or 1.0 engine layouting.
132:                    return false;
133:                }
134:
135:                if (box instanceof  ParagraphRenderBox) {
136:                    final ParagraphRenderBox paragraphBox = (ParagraphRenderBox) box;
137:                    // We cant cache that ... the shift operations later would misbehave
138:                    // One way around would be to at least store the layouted offsets
139:                    // (which should be immutable as long as the line did not change its
140:                    // contents) and to reapply them on each run. This is cheaper than
141:                    // having to compute the whole v-align for the whole line.
142:                    breakState.init(paragraphBox);
143:                }
144:
145:                return true;
146:            }
147:
148:            protected void processBlockLevelNode(final RenderNode node) {
149:                // This could be anything, text, or an image.
150:                node.setCachedY(computeVerticalBlockPosition(node));
151:
152:                if (node instanceof  FinishedRenderNode) {
153:                    final FinishedRenderNode fnode = (FinishedRenderNode) node;
154:                    node.setCachedHeight(fnode.getLayoutedHeight());
155:                } else if (node instanceof  InlineRenderBox) {
156:                    throw new IllegalStateException(
157:                            "A Inline-Box must be contained in a paragraph.");
158:                } else if (node instanceof  RenderableReplacedContent) {
159:                    final RenderableReplacedContent rpc = (RenderableReplacedContent) node;
160:                    node.setCachedHeight(rpc.computeHeight(
161:                            computeBlockContextWidth(node), node
162:                                    .getComputedWidth()));
163:                }
164:            }
165:
166:            protected void finishBlockLevelBox(final RenderBox box) {
167:                if (box instanceof  BlockRenderBox) {
168:                    // make sure that we resolve against zero.
169:                    box.setCachedHeight(computeBlockHeightAndAlign(box, 0));
170:                } else {
171:                    box.setCachedHeight(computeCanvasHeight(box));
172:                }
173:
174:                if (breakState.isActive()) {
175:                    final Object suspender = breakState.getSuspendItem();
176:                    if (box.getInstanceId() == suspender) {
177:                        breakState.setSuspendItem(null);
178:                        return;
179:                    }
180:                    if (suspender != null) {
181:                        return;
182:                    }
183:
184:                    if (box instanceof  ParagraphRenderBox) {
185:                        breakState.deinit();
186:                    }
187:                }
188:            }
189:
190:            private long computeVerticalBlockPosition(final RenderNode node) {
191:                // we have no margins yet ..
192:                final long marginTop = 0;
193:
194:                // The y-position of a box depends on the parent.
195:                final RenderBox parent = node.getParent();
196:
197:                // A table row is something special. Although it is a block box,
198:                // it layouts its children from left to right
199:                if (parent instanceof  BlockRenderBox) {
200:                    final RenderNode prev = node.getVisiblePrev();
201:                    if (prev != null) {
202:                        // we have a silbling. Position yourself directly below your silbling ..
203:                        return (marginTop + prev.getCachedY() + prev
204:                                .getCachedHeight());
205:                    } else {
206:                        final StaticBoxLayoutProperties blp = parent
207:                                .getStaticBoxLayoutProperties();
208:                        final BoxDefinition bdef = parent.getBoxDefinition();
209:                        final long insetTop = (blp.getBorderTop() + bdef
210:                                .getPaddingTop());
211:
212:                        return (marginTop + insetTop + parent.getCachedY());
213:                    }
214:                } else {
215:                    // there's no parent ..
216:                    return (marginTop);
217:                }
218:            }
219:
220:            private long computeBlockHeightAndAlign(final RenderBox box,
221:                    final long resolveSize) {
222:                // For the water-mark area, this computation is different. The Watermark-area uses the known height of
223:                // the parent (=the page size)
224:                if (box instanceof  WatermarkAreaBox) {
225:                    final WatermarkAreaBox watermarkAreaBox = (WatermarkAreaBox) box;
226:                    final LogicalPageBox lpb = watermarkAreaBox
227:                            .getLogicalPage();
228:                    // set the page-height as watermark size.
229:                    return lpb.getPageHeight();
230:                }
231:
232:                // Check the height. Set the height.
233:                final BoxDefinition boxDefinition = box.getBoxDefinition();
234:                final RenderLength preferredHeight = boxDefinition
235:                        .getPreferredHeight();
236:                final RenderLength minimumHeight = boxDefinition
237:                        .getMinimumHeight();
238:                final RenderLength maximumHeight = boxDefinition
239:                        .getMaximumHeight();
240:
241:                final long usedHeight;
242:                final long childY2;
243:                final long childY1;
244:                final RenderNode lastChildNode = box.getLastChild();
245:                if (lastChildNode != null) {
246:                    childY1 = box.getFirstChild().getCachedY();
247:                    childY2 = lastChildNode.getCachedY()
248:                            + lastChildNode.getCachedHeight()
249:                            + lastChildNode.getEffectiveMarginBottom();
250:                    usedHeight = (childY2 - childY1);
251:                } else {
252:                    usedHeight = 0;
253:                    childY2 = 0;
254:                    childY1 = 0;
255:                }
256:
257:                //final long blockContextWidth = box.getStaticBoxLayoutProperties().getBlockContextWidth();
258:                final long rminH = minimumHeight.resolve(resolveSize, 0);
259:                final long rmaxH = maximumHeight.resolve(resolveSize, MAX_AUTO);
260:
261:                final StaticBoxLayoutProperties blp = box
262:                        .getStaticBoxLayoutProperties();
263:                final long insetBottom = blp.getBorderBottom()
264:                        + boxDefinition.getPaddingBottom();
265:                final long insetTop = blp.getBorderTop()
266:                        + boxDefinition.getPaddingTop();
267:
268:                final long computedHeight;
269:                if (boxDefinition.isSizeSpecifiesBorderBox()) {
270:                    final long rprefH = preferredHeight.resolve(resolveSize,
271:                            usedHeight + insetTop + insetBottom);
272:                    final long specifiedHeight = computeHeight(rminH, rmaxH,
273:                            rprefH);
274:                    computedHeight = specifiedHeight - insetTop - insetBottom;
275:                } else {
276:                    final long rprefH = preferredHeight.resolve(resolveSize,
277:                            usedHeight);
278:                    final long specifiedHeight = computeHeight(rminH, rmaxH,
279:                            rprefH);
280:                    computedHeight = specifiedHeight;
281:                }
282:
283:                if (lastChildNode != null) {
284:                    // grab the node's y2
285:                    if (computedHeight > usedHeight) {
286:                        // we have extra space to distribute. So lets shift some boxes.
287:                        final ElementAlignment valign = box
288:                                .getNodeLayoutProperties()
289:                                .getVerticalAlignment();
290:                        if (ElementAlignment.BOTTOM.equals(valign)) {
291:                            final long boxBottom = (box.getCachedY()
292:                                    + box.getCachedHeight() - insetBottom);
293:                            final long delta = boxBottom - childY2;
294:                            CacheBoxShifter.shiftBoxChilds(box, delta);
295:                        } else if (ElementAlignment.MIDDLE.equals(valign)) {
296:                            final long extraHeight = computedHeight
297:                                    - usedHeight;
298:                            final long boxTop = box.getCachedY() + insetTop
299:                                    + (extraHeight / 2);
300:                            final long delta = boxTop - childY1;
301:                            CacheBoxShifter.shiftBoxChilds(box, delta);
302:                        }
303:                        return Math.max(0, computedHeight + insetTop
304:                                + insetBottom);
305:                    }
306:                    return Math.max(0, computedHeight + insetTop + insetBottom);
307:                } else {
308:                    return Math.max(0, computedHeight + insetTop + insetBottom);
309:                }
310:            }
311:
312:            private long computeBlockContextWidth(final RenderNode box) {
313:                final RenderBox parentBlockContext = box.getParent();
314:                if (parentBlockContext == null) {
315:                    final LogicalPageBox logicalPage = box.getLogicalPage();
316:                    if (logicalPage == null) {
317:                        return 0;
318:                    }
319:                    return logicalPage.getPageWidth();
320:                }
321:                return parentBlockContext.getStaticBoxLayoutProperties()
322:                        .getBlockContextWidth();
323:            }
324:
325:            protected void processParagraphChilds(final ParagraphRenderBox box) {
326:                // Process the direct childs of the paragraph
327:                // Each direct child represents a line ..
328:
329:                RenderNode node = box.getVisibleFirst();
330:                while (node != null) {
331:                    // all childs of the linebox container must be inline boxes. They
332:                    // represent the lines in the paragraph. Any other element here is
333:                    // a error that must be reported
334:                    if (node instanceof  ParagraphPoolBox == false) {
335:                        throw new IllegalStateException("Encountered "
336:                                + node.getClass());
337:                    }
338:                    final ParagraphPoolBox inlineRenderBox = (ParagraphPoolBox) node;
339:                    if (startLine(inlineRenderBox)) {
340:                        processBoxChilds(inlineRenderBox);
341:                        finishLine(inlineRenderBox);
342:                    }
343:
344:                    node = node.getVisibleNext();
345:                }
346:            }
347:
348:            private boolean startLine(final ParagraphPoolBox box) {
349:                box.setCachedY(computeVerticalBlockPosition(box));
350:
351:                if (breakState.isActive() == false) {
352:                    return false;
353:                }
354:
355:                if (breakState.isSuspended()) {
356:                    return false;
357:                }
358:
359:                breakState.openContext(new BoxAlignContext(box));
360:                return true;
361:            }
362:
363:            private void finishLine(final ParagraphPoolBox inlineRenderBox) {
364:                if (breakState.isActive() == false || breakState.isSuspended()) {
365:                    return;
366:                }
367:
368:                final BoxAlignContext boxAlignContext = breakState
369:                        .closeContext();
370:
371:                // This aligns all direct childs. Once that is finished, we have to
372:                // check, whether possibly existing inner-paragraphs are still valid
373:                // or whether moving them violated any of the inner-pagebreak constraints.
374:
375:                final StaticBoxLayoutProperties blp = inlineRenderBox
376:                        .getStaticBoxLayoutProperties();
377:                final BoxDefinition bdef = inlineRenderBox.getBoxDefinition();
378:                final long insetTop = (blp.getBorderTop() + bdef
379:                        .getPaddingTop());
380:
381:                final long contentAreaY1 = inlineRenderBox.getCachedY()
382:                        + insetTop;
383:                final long lineHeight = inlineRenderBox.getLineHeight();
384:                processor.align(boxAlignContext, contentAreaY1, lineHeight);
385:            }
386:
387:            protected boolean startInlineLevelBox(final RenderBox box) {
388:                if (box.isCacheValid()) {
389:                    return false;
390:                }
391:
392:                box.setCachedY(computeVerticalInlinePosition(box));
393:                computeBaselineInfo(box);
394:
395:                if (breakState == null) {
396:                    // ignore .. should not happen anyway ..
397:                    return true;
398:                }
399:
400:                if (breakState.isSuspended()) {
401:                    return false;
402:                }
403:
404:                if (box instanceof  InlineRenderBox) {
405:                    breakState.openContext(new BoxAlignContext(box));
406:                    return true;
407:                }
408:
409:                breakState.getCurrentLine().addChild(
410:                        new InlineBlockAlignContext(box));
411:                breakState.setSuspendItem(box.getInstanceId());
412:                return false;
413:            }
414:
415:            private void computeBaselineInfo(final RenderBox box) {
416:                if (box.getBaselineInfo() == null) {
417:                    return;
418:                }
419:
420:                RenderNode node = box.getVisibleFirst();
421:                while (node != null) {
422:                    if (node instanceof  RenderableText) {
423:                        // grab the baseline info from there ...
424:                        final RenderableText text = (RenderableText) node;
425:                        box.setBaselineInfo(text.getBaselineInfo());
426:                        break;
427:                    }
428:
429:                    node = node.getVisibleNext();
430:                }
431:
432:                // If we have no baseline info here, ask the parent. If that one has none
433:                // either, then we cant do anything about it.
434:                if (box.getBaselineInfo() == null) {
435:                    box.setBaselineInfo(box.getStaticBoxLayoutProperties()
436:                            .getNominalBaselineInfo());
437:                }
438:            }
439:
440:            protected void processInlineLevelNode(final RenderNode node) {
441:                // compute the intial position.
442:                node.setCachedY(computeVerticalInlinePosition(node));
443:                // the height and the real position will be computed during the vertical-alignment computation. 
444:
445:                if (breakState.isActive() == false || breakState.isSuspended()) {
446:                    return;
447:                }
448:
449:                if (node instanceof  RenderableText) {
450:                    breakState.getCurrentLine().addChild(
451:                            new TextElementAlignContext((RenderableText) node));
452:                } else if (node instanceof  RenderableReplacedContent) {
453:                    breakState.getCurrentLine().addChild(
454:                            new ReplacedContentAlignContext(
455:                                    (RenderableReplacedContent) node));
456:                } else {
457:                    breakState.getCurrentLine().addChild(
458:                            new NodeAlignContext(node));
459:                }
460:            }
461:
462:            protected void finishInlineLevelBox(final RenderBox box) {
463:                // The height of an inline-level box will be computed when the vertical-alignemnt is done.
464:
465:                if (breakState.isActive() == false) {
466:                    return;
467:                }
468:
469:                if (box instanceof  InlineRenderBox) {
470:                    breakState.closeContext();
471:                    return;
472:                }
473:
474:                final Object suspender = breakState.getSuspendItem();
475:                if (box.getInstanceId() == suspender) {
476:                    breakState.setSuspendItem(null);
477:                    return;
478:                }
479:
480:                if (suspender != null) {
481:                    return;
482:                }
483:
484:                if (box instanceof  ParagraphRenderBox) {
485:                    throw new IllegalStateException("This cannot be.");
486:                }
487:            }
488:
489:            private long computeVerticalInlinePosition(final RenderNode node) {
490:                final RenderBox parent = node.getParent();
491:
492:                if (parent != null) {
493:                    // the computed position of an inline-element must be the same as the position of the parent element.
494:                    // A inline-box always has an other inline-box as parent (the paragraph-pool-box is the only exception;
495:                    // and this one is handled elsewhere).
496:
497:                    // Top and bottom margins are not applied to inline-elements.
498:                    final StaticBoxLayoutProperties blp = parent
499:                            .getStaticBoxLayoutProperties();
500:                    final BoxDefinition bdef = parent.getBoxDefinition();
501:                    final long insetTop = (blp.getBorderTop() + bdef
502:                            .getPaddingTop());
503:
504:                    return (insetTop + parent.getCachedY());
505:                } else {
506:                    // there's no parent .. Should not happen, shouldn't it?
507:                    return (0);
508:                }
509:            }
510:
511:            protected boolean startCanvasLevelBox(final RenderBox box) {
512:                if (box.isCacheValid()) {
513:                    return false;
514:                }
515:
516:                if (box.isIgnorableForRendering()) {
517:                    return false;
518:                }
519:
520:                box.setCachedY(computeVerticalCanvasPosition(box));
521:
522:                if (breakState.isActive() == false) {
523:                    if (box instanceof  ParagraphRenderBox) {
524:                        final ParagraphRenderBox paragraphBox = (ParagraphRenderBox) box;
525:                        // We cant cache that ... the shift operations later would misbehave
526:                        // One way around would be to at least store the layouted offsets
527:                        // (which should be immutable as long as the line did not change its
528:                        // contents) and to reapply them on each run. This is cheaper than
529:                        // having to compute the whole v-align for the whole line.
530:                        breakState.init(paragraphBox);
531:                    }
532:
533:                    return true;
534:                }
535:
536:                // No breakstate and not being suspended? Why this?
537:                if (breakState.isSuspended() == false) {
538:                    throw new IllegalStateException("This cannot be.");
539:                }
540:
541:                // this way or another - we are suspended now. So there is no need to look
542:                // at the children anymore ..
543:                return false;
544:            }
545:
546:            protected void processCanvasLevelNode(final RenderNode node) {
547:                node.setCachedY(computeVerticalCanvasPosition(node));
548:
549:                // docmark
550:                if (node instanceof  RenderableReplacedContent) {
551:                    final RenderableReplacedContent rpc = (RenderableReplacedContent) node;
552:                    final long computedHeight = rpc.computeHeight(0, node
553:                            .getComputedWidth());
554:                    node.setCachedHeight(computedHeight);
555:                } else if (node instanceof  FinishedRenderNode) {
556:                    final FinishedRenderNode fnode = (FinishedRenderNode) node;
557:                    node.setCachedHeight(fnode.getLayoutedHeight());
558:                } else {
559:                    node.setCachedHeight(0);
560:                }
561:            }
562:
563:            /**
564:             * Finishes up a canvas level box. This updates/affects the height of the parent, as the canvas model defines that the
565:             * parent always fully encloses all of its childs.
566:             * <p/>
567:             * When no preferred height is defined, the height of an element is the maximum of its minimum-height and the absolute
568:             * height of all of its direct children.
569:             * <p/>
570:             * To resolve the value of percentages, the system uses the maximum of the parent's height and the maximum of all (y +
571:             * height) of all children.)
572:             *
573:             * @param box
574:             */
575:            protected void finishCanvasLevelBox(final RenderBox box) {
576:                if (box instanceof  BlockRenderBox) {
577:                    // make sure that we resolve against zero.
578:                    box.setCachedHeight(computeBlockHeightAndAlign(box, 0));
579:                } else {
580:
581:                    box.setCachedHeight(computeCanvasHeight(box));
582:                }
583:
584:                if (breakState.isActive()) {
585:                    final Object suspender = breakState.getSuspendItem();
586:                    if (box.getInstanceId() == suspender) {
587:                        breakState.setSuspendItem(null);
588:                        return;
589:                    }
590:                    if (suspender != null) {
591:                        return;
592:                    }
593:
594:                    if (box instanceof  ParagraphRenderBox) {
595:                        breakState.deinit();
596:                    }
597:                }
598:            }
599:
600:            private long computeVerticalCanvasPosition(final RenderNode node) {
601:                final RenderBox parent = node.getParent();
602:                final long parentPosition;
603:                if (parent == null) {
604:                    parentPosition = 0;
605:                } else {
606:                    final StaticBoxLayoutProperties blp = parent
607:                            .getStaticBoxLayoutProperties();
608:                    final BoxDefinition bdef = parent.getBoxDefinition();
609:                    final long insetsTop = (blp.getBorderTop() + bdef
610:                            .getPaddingTop());
611:                    parentPosition = parent.getCachedY() + insetsTop;
612:                }
613:
614:                final double posY = node.getStyleSheet()
615:                        .getDoubleStyleProperty(ElementStyleKeys.POS_Y, 0);
616:                if (node.isSizeSpecifiesBorderBox()) {
617:                    return (parentPosition + RenderLength
618:                            .resolveLength(0, posY));
619:                } else {
620:                    final long insetsTop;
621:                    if (node instanceof  RenderBox) {
622:                        final RenderBox box = (RenderBox) node;
623:                        final StaticBoxLayoutProperties blp = box
624:                                .getStaticBoxLayoutProperties();
625:                        final BoxDefinition bdef = box.getBoxDefinition();
626:                        insetsTop = (blp.getBorderTop() + bdef.getPaddingTop());
627:                    } else {
628:                        insetsTop = 0;
629:                    }
630:                    return (parentPosition
631:                            + RenderLength.resolveLength(0, posY) - insetsTop);
632:                }
633:            }
634:
635:            private long computeCanvasHeight(final RenderBox box) {
636:                final StaticBoxLayoutProperties blp = box
637:                        .getStaticBoxLayoutProperties();
638:                final BoxDefinition bdef = box.getBoxDefinition();
639:
640:                final BoxDefinition boxDefinition = box.getBoxDefinition();
641:                final RenderLength minHeight = boxDefinition.getMinimumHeight();
642:                final RenderLength preferredHeight = boxDefinition
643:                        .getPreferredHeight();
644:                final RenderLength maxHeight = boxDefinition.getMaximumHeight();
645:
646:                final long insetsTop = (blp.getBorderTop() + bdef
647:                        .getPaddingTop());
648:                final long insetsBottom = blp.getBorderBottom()
649:                        + bdef.getPaddingBottom();
650:                final long insets = insetsTop + insetsBottom;
651:
652:                // find the maximum of the used height (for all childs) and the specified min-height.
653:                long consumedHeight = minHeight.resolve(0);
654:
655:                if (box.isSizeSpecifiesBorderBox()) {
656:                    consumedHeight = Math.max(0, consumedHeight - insetsBottom);
657:                } else {
658:                    consumedHeight = Math.max(0, consumedHeight + insetsTop);
659:                }
660:
661:                final long boxY = box.getCachedY();
662:
663:                RenderNode node = box.getFirstChild();
664:                while (node != null) {
665:                    final long childY2 = (insetsTop + (node.getCachedY() + node
666:                            .getCachedHeight()));
667:                    final long childLocalY2 = childY2 - boxY;
668:                    if (childLocalY2 > consumedHeight) {
669:                        consumedHeight = childLocalY2;
670:                    }
671:                    node = node.getNext();
672:                }
673:
674:                consumedHeight += insetsBottom;
675:
676:                // The consumed height computed above specifies the size at the border-edge.
677:                // However, depending on the box-sizing property, we may have to resolve them against the
678:                // content-edge instead.
679:
680:                if (box.isSizeSpecifiesBorderBox()) {
681:                    final long minHeightResolved = minHeight.resolve(0);
682:                    final long maxHeightResolved = maxHeight.resolve(0);
683:                    final long prefHeightResolved;
684:                    if (preferredHeight == RenderLength.AUTO) {
685:                        prefHeightResolved = consumedHeight;
686:                    } else {
687:                        prefHeightResolved = preferredHeight.resolve(0);
688:                    }
689:
690:                    final long height = computeHeight(minHeightResolved,
691:                            maxHeightResolved, prefHeightResolved);
692:                    return (height);
693:                } else {
694:                    consumedHeight = Math.max(0, consumedHeight - insets);
695:                    final long minHeightResolved = minHeight.resolve(0);
696:                    final long maxHeightResolved = maxHeight.resolve(0);
697:                    final long prefHeightResolved;
698:                    if (preferredHeight == RenderLength.AUTO) {
699:                        prefHeightResolved = consumedHeight;
700:                    } else {
701:                        prefHeightResolved = preferredHeight.resolve(0);
702:                    }
703:
704:                    final long height = computeHeight(minHeightResolved,
705:                            maxHeightResolved, prefHeightResolved);
706:                    return (height + insets);
707:                }
708:            }
709:
710:            public static long computeHeight(final long min, final long max,
711:                    final long pref) {
712:                if (pref > max) {
713:                    if (max < min) {
714:                        return min;
715:                    }
716:                    return max;
717:                }
718:
719:                if (pref < min) {
720:                    if (max < min) {
721:                        return max;
722:                    }
723:                    return min;
724:                }
725:
726:                if (max < pref) {
727:                    return max;
728:                }
729:                return pref;
730:            }
731:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.