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: * FullLinebreaker.java
027: * ------------
028: * (C) Copyright 2001-2007, by Object Refinery Ltd, Pentaho Corporation and Contributors.
029: */package org.jfree.report.layout.process.linebreak;
030:
031: import java.util.Stack;
032:
033: import org.jfree.report.layout.model.InlineRenderBox;
034: import org.jfree.report.layout.model.ParagraphRenderBox;
035: import org.jfree.report.layout.model.RenderBox;
036: import org.jfree.report.layout.model.RenderNode;
037:
038: /**
039: * Creation-Date: 25.04.2007, 13:44:48
040: *
041: * @author Thomas Morgner
042: */
043: public class FullLinebreaker implements ParagraphLinebreaker {
044: private RenderBox insertationPoint;
045: private ParagraphRenderBox paragraphRenderBox;
046: private Object suspendItem;
047: private boolean breakRequested;
048:
049: public FullLinebreaker(final ParagraphRenderBox paragraphRenderBox) {
050: this .paragraphRenderBox = paragraphRenderBox;
051: final RenderBox pool = (RenderBox) paragraphRenderBox.getPool()
052: .deriveFrozen(false);
053: final RenderBox lineboxContainer = this .paragraphRenderBox
054: .createLineboxContainer();
055: lineboxContainer.clear();
056: lineboxContainer.addGeneratedChild(pool);
057: this .paragraphRenderBox.setLineBoxAge(0);
058: this .insertationPoint = pool;
059: }
060:
061: public boolean isWritable() {
062: return true;
063: }
064:
065: public void startBlockBox(final RenderBox child) {
066: final RenderBox derived = (RenderBox) child.deriveFrozen(false);
067: insertationPoint.addGeneratedChild(derived);
068: insertationPoint = derived;
069: if (suspendItem != null) {
070: suspendItem = derived.getInstanceId();
071: }
072: }
073:
074: public void finishBlockBox(final RenderBox box) {
075: insertationPoint = insertationPoint.getParent();
076: if (suspendItem == box.getInstanceId()) {
077: suspendItem = null;
078: }
079: }
080:
081: public ParagraphLinebreaker startParagraphBox(
082: final ParagraphRenderBox box) {
083: startBlockBox(box);
084: return new FullLinebreaker(
085: (ParagraphRenderBox) insertationPoint);
086: }
087:
088: public void finishParagraphBox(final ParagraphRenderBox box) {
089: finishBlockBox(box);
090: }
091:
092: public boolean isSuspended() {
093: return suspendItem != null;
094: }
095:
096: public FullLinebreaker startComplexLayout() {
097: return this ;
098: }
099:
100: public void finish() {
101: paragraphRenderBox.setLineBoxAge(paragraphRenderBox.getPool()
102: .getChangeTracker());
103: }
104:
105: public void startInlineBox(final InlineRenderBox box) {
106: final RenderBox child = (RenderBox) box.deriveFrozen(false);
107: insertationPoint.addGeneratedChild(child);
108: insertationPoint = child;
109: }
110:
111: public void finishInlineBox(final InlineRenderBox box) {
112: insertationPoint = insertationPoint.getParent();
113: }
114:
115: public void addNode(final RenderNode node) {
116: insertationPoint.addGeneratedChild(node.deriveFrozen(true));
117: }
118:
119: public void performBreak() {
120:
121: // If we come that far, it means, we have a forced linebreak and we
122: // are a node in the middle of the tree ..
123: final Stack contexts = new Stack();
124:
125: // perform a simple split
126: // as long as the splitted element is at the end of it's box, it is not
127: // needed to split the box at all. Just let it end naturally is enough for
128: // them to look good.
129:
130: // As the real context (from the break-State) is currently being built,
131: // we have to use the original pool to query the 'is-end-of-line' flag.
132: RenderBox context = insertationPoint;
133: final RenderBox lines = paragraphRenderBox
134: .getLineboxContainer();
135: while (context != lines) {
136: // save the context ..
137: if (context instanceof InlineRenderBox == false) {
138: throw new IllegalStateException(
139: "Confused: I expect InlineBoxes ..");
140: }
141:
142: final InlineRenderBox inline = (InlineRenderBox) context;
143: contexts.push(inline.split(RenderNode.HORIZONTAL_AXIS));
144: context = context.getParent();
145: }
146:
147: // reset to a known state and add all saved contexts ..
148: insertationPoint = lines;
149: while (contexts.isEmpty() == false) {
150: final RenderBox box = (RenderBox) contexts.pop();
151: insertationPoint.addGeneratedChild(box);
152: insertationPoint = box;
153: }
154:
155: breakRequested = false;
156: }
157:
158: public boolean isBreakRequested() {
159: return breakRequested;
160: }
161:
162: public void setBreakRequested(final boolean breakRequested) {
163: this.breakRequested = breakRequested;
164: }
165: }
|