Source Code Cross Referenced for ParagraphLineBreakStep.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:         * ParagraphLineBreakStep.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.layout.model.BlockRenderBox;
032:        import org.jfree.report.layout.model.CanvasRenderBox;
033:        import org.jfree.report.layout.model.InlineRenderBox;
034:        import org.jfree.report.layout.model.LogicalPageBox;
035:        import org.jfree.report.layout.model.ParagraphRenderBox;
036:        import org.jfree.report.layout.model.RenderBox;
037:        import org.jfree.report.layout.model.RenderNode;
038:        import org.jfree.report.layout.model.RenderableText;
039:        import org.jfree.report.layout.process.linebreak.EmptyLinebreaker;
040:        import org.jfree.report.layout.process.linebreak.FullLinebreaker;
041:        import org.jfree.report.layout.process.linebreak.ParagraphLinebreaker;
042:        import org.jfree.report.layout.process.linebreak.SimpleLinebreaker;
043:        import org.jfree.util.FastStack;
044:
045:        /**
046:         * This static computation step performs manual linebreaks on all paragraphs.
047:         * This transforms the pool-collection into the lines-collection.
048:         * <p/>
049:         * For now, we follow a very simple path: A paragraph cannot be validated, if it
050:         * is not yet closed. The linebreaking, be it the static one here or the dynamic
051:         * one later, must be redone when the paragraph changes.
052:         * <p/>
053:         * Splitting for linebreaks happens only between inline-boxes. BlockBoxes that
054:         * are contained in inline-boxes (like 'inline-block' elements or
055:         * 'inline-tables') are considered unbreakable according to the CSS specs.
056:         * Linebreaking can be suspended in these cases.
057:         * <p/>
058:         * As paragraphs itself are block elements, the linebreaks can be done
059:         * iterative, using a simple stack to store the context of possibly nested
060:         * paragraphs. The paragraph's pool contains the elements that should be
061:         * processed, and the line-container will receive the pool's content (contained
062:         * in an artificial inline element, as the linecontainer is a block-level
063:         * element).
064:         * <p/>
065:         * Change-tracking should take place on the paragraph's pool element instead of
066:         * the paragraph itself. This way, only structural changes are taken into
067:         * account.
068:         *
069:         * @author Thomas Morgner
070:         */
071:        public final class ParagraphLineBreakStep extends
072:                IterateStructuralProcessStep {
073:            private static final EmptyLinebreaker LEAF_BREAK_STATE = new EmptyLinebreaker();
074:
075:            private FastStack paragraphNesting;
076:            private ParagraphLinebreaker breakState;
077:
078:            public ParagraphLineBreakStep() {
079:                paragraphNesting = new FastStack();
080:            }
081:
082:            public void compute(final LogicalPageBox root) {
083:                paragraphNesting.clear();
084:                try {
085:                    startProcessing(root);
086:                } finally {
087:                    paragraphNesting.clear();
088:                    breakState = null;
089:                }
090:            }
091:
092:            protected boolean startBlockBox(final BlockRenderBox box) {
093:                if (box instanceof  ParagraphRenderBox) {
094:                    final ParagraphRenderBox paragraphBox = (ParagraphRenderBox) box;
095:                    final long poolChangeTracker = paragraphBox.getPool()
096:                            .getChangeTracker();
097:                    final boolean unchanged = poolChangeTracker == paragraphBox
098:                            .getLineBoxAge();
099:
100:                    if (unchanged) {
101:                        // If the paragraph is unchanged (no new elements have been added to the pool) then we can take a
102:                        // shortcut. The childs of this paragraph will also be unchanged (as any structural change would have increased
103:                        // the change-tracker).
104:                        paragraphNesting.push(LEAF_BREAK_STATE);
105:                        breakState = LEAF_BREAK_STATE;
106:                        return false;
107:                    }
108:
109:                    // When the paragraph has changed, this can only be caused by someone adding a new node to the paragraph
110:                    // or to one of the childs.
111:
112:                    // Paragraphs can be nested whenever a Inline-Level element declares to be a Block-Layouter. (This is an
113:                    // Inline-Block or Inline-Table case in CSS)
114:
115:                    // It is guaranteed, that if a child is changed, the parent is marked as changed as well.
116:                    // So we have only two cases to deal with: (1) The child is unchanged (2) the child is changed.
117:
118:                    if (breakState == null) {
119:                        if (paragraphBox.isComplexParagraph()) {
120:                            final ParagraphLinebreaker item = new FullLinebreaker(
121:                                    paragraphBox);
122:                            paragraphNesting.push(item);
123:                            breakState = item;
124:                        } else {
125:                            final ParagraphLinebreaker item = new SimpleLinebreaker(
126:                                    paragraphBox);
127:                            paragraphNesting.push(item);
128:                            breakState = item;
129:                        }
130:                        return true;
131:                    }
132:
133:                    // The breakState indicates that there is a paragraph processing active at the moment. This means, the
134:                    // paragraph-box we are dealing with right now is a nested box.
135:
136:                    if (breakState.isWritable() == false) {
137:                        // OK, should not happen, but you never know. I'm good at hiding
138:                        // bugs in the code ..
139:                        throw new IllegalStateException(
140:                                "A child cannot be dirty, if the parent is clean");
141:                    }
142:
143:                    // The paragraph is somehow nested in an other paragraph.
144:                    // This cannot be handled by the simple implementation, as we will most likely start to deriveForAdvance childs sooner
145:                    // or later
146:                    if (breakState instanceof  FullLinebreaker == false) {
147:                        // convert it ..
148:                        final FullLinebreaker fullBreaker = breakState
149:                                .startComplexLayout();
150:                        paragraphNesting.pop();
151:                        paragraphNesting.push(fullBreaker);
152:                        breakState = fullBreaker;
153:                    }
154:
155:                    final ParagraphLinebreaker subFlow = breakState
156:                            .startParagraphBox(paragraphBox);
157:                    paragraphNesting.push(subFlow);
158:                    breakState = subFlow;
159:                    return true;
160:                }
161:
162:                // some other block box ..
163:                if (breakState == null) {
164:                    if (box.getChangeTracker() == box.getCachedAge()) {
165:                        return false;
166:                    }
167:                    // Not nested in a paragraph, thats easy ..
168:                    return true;
169:                }
170:
171:                if (breakState.isWritable() == false) {
172:                    throw new IllegalStateException(
173:                            "This cannot be: There is an active break-state, but the box is not writable.");
174:                }
175:
176:                breakState.startBlockBox(box);
177:                return true;
178:            }
179:
180:            public boolean startCanvasBox(final CanvasRenderBox box) {
181:                if (breakState == null) {
182:                    if (box.getChangeTracker() == box.getCachedAge()) {
183:                        return false;
184:                    }
185:
186:                    return true;
187:                }
188:
189:                // some other block box .. suspend.
190:                if (breakState.isWritable() == false) {
191:                    throw new IllegalStateException(
192:                            "A child cannot be dirty, if the parent is clean");
193:                }
194:
195:                breakState.startBlockBox(box);
196:                return true;
197:            }
198:
199:            public void finishCanvasBox(final CanvasRenderBox box) {
200:                if (breakState != null) {
201:                    if (breakState.isWritable() == false) {
202:                        throw new IllegalStateException(
203:                                "A child cannot be dirty, if the parent is clean");
204:                    }
205:
206:                    breakState.finishBlockBox(box);
207:                }
208:            }
209:
210:            protected void finishBlockBox(final BlockRenderBox box) {
211:                if (box instanceof  ParagraphRenderBox) {
212:                    // do the linebreak jiggle ...
213:                    // This is the first test case whether it is possible to avoid
214:                    // composition-recursion on such computations. I'd prefer to have
215:                    // an iterator pattern here ...
216:
217:                    // finally update the change tracker ..
218:                    breakState.finish();
219:                    paragraphNesting.pop();
220:                    if (paragraphNesting.isEmpty()) {
221:                        breakState = null;
222:                    } else {
223:                        breakState = (ParagraphLinebreaker) paragraphNesting
224:                                .peek();
225:                        breakState.finishParagraphBox((ParagraphRenderBox) box);
226:                    }
227:                    return;
228:                }
229:
230:                if (breakState == null) {
231:                    return;
232:                }
233:
234:                if (breakState.isWritable() == false) {
235:                    throw new IllegalStateException(
236:                            "A child cannot be dirty, if the parent is clean");
237:                }
238:
239:                breakState.finishBlockBox(box);
240:            }
241:
242:            protected boolean startInlineBox(final InlineRenderBox box) {
243:                if (breakState == null || breakState.isWritable() == false) {
244:                    if (box.getChangeTracker() == box.getCachedAge()) {
245:                        return false;
246:                    }
247:                    return true;
248:                }
249:
250:                breakState.startInlineBox(box);
251:                return true;
252:            }
253:
254:            protected void finishInlineBox(final InlineRenderBox box) {
255:                if (breakState == null || breakState.isWritable() == false) {
256:                    return;
257:                }
258:
259:                breakState.finishInlineBox(box);
260:                if (breakState.isBreakRequested() && box.getNext() != null) {
261:                    performBreak();
262:                }
263:            }
264:
265:            protected void processOtherNode(final RenderNode node) {
266:                if (breakState == null || breakState.isWritable() == false) {
267:                    return;
268:                }
269:                if (breakState.isSuspended()
270:                        || node instanceof  RenderableText == false) {
271:                    breakState.addNode(node);
272:                    return;
273:                }
274:
275:                final RenderableText text = (RenderableText) node;
276:                breakState.addNode(text);
277:                if (text.isForceLinebreak() == false) {
278:                    return;
279:                }
280:
281:                // OK, someone requested a manual linebreak.
282:                // Fill a stack with the current context ..
283:                // Check if we are at the end of the line
284:                if (node.getNext() == null) {
285:                    // OK, if we are at the end of the line (for all contexts), so we
286:                    // dont have to perform a break. The text will end anyway ..
287:                    if (isEndOfLine(node)) {
288:                        return;
289:                    }
290:
291:                    // as soon as we are no longer the last element - break!
292:                    // According to the flow rules, that will happen in one of the next
293:                    // finishInlineBox events ..
294:                    breakState.setBreakRequested(true);
295:                    return;
296:                }
297:
298:                performBreak();
299:            }
300:
301:            private boolean isEndOfLine(final RenderNode node) {
302:                boolean endOfLine = true;
303:                RenderBox parent = node.getParent();
304:                while (parent != null) {
305:                    if (parent instanceof  InlineRenderBox == false) {
306:                        break;
307:                    }
308:                    if (parent.getNext() != null) {
309:                        endOfLine = false;
310:                        break;
311:                    }
312:                    parent = parent.getParent();
313:                }
314:                return endOfLine;
315:            }
316:
317:            private void performBreak() {
318:                if (breakState instanceof  FullLinebreaker == false) {
319:                    final FullLinebreaker fullBreaker = breakState
320:                            .startComplexLayout();
321:                    paragraphNesting.pop();
322:                    paragraphNesting.push(fullBreaker);
323:                    breakState = fullBreaker;
324:
325:                    fullBreaker.performBreak();
326:                } else {
327:                    final FullLinebreaker fullBreaker = (FullLinebreaker) breakState;
328:                    fullBreaker.performBreak();
329:                }
330:            }
331:
332:            protected boolean startOtherBox(final RenderBox box) {
333:                if (breakState == null) {
334:                    return false;
335:                }
336:
337:                if (breakState.isWritable() == false) {
338:                    return false;
339:                }
340:
341:                breakState.startBlockBox(box);
342:                return true;
343:            }
344:
345:            protected void finishOtherBox(final RenderBox box) {
346:                if (breakState != null && breakState.isWritable()) {
347:                    breakState.finishBlockBox(box);
348:                }
349:            }
350:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.