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: * SimpleLinebreaker.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.Arrays;
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: * This implementation is used in the simple mode. The pool-box is used as is - none of the nodes get derived,
040: * but we keep track of the calls in case we encounter a manual break later. In that case, the SimpleLinebreaker
041: * converts itself into a FullLinebreaker.
042: *
043: * @author Thomas Morgner
044: */
045: public class SimpleLinebreaker implements ParagraphLinebreaker {
046: // private class Call
047: // {
048: // private Call next;
049: // private Object parameter;
050: // private int method;
051: //
052: // protected Call(final int method, final Object parameter, final Call next)
053: // {
054: // this.next = next;
055: // this.method = method;
056: // this.parameter = parameter;
057: // }
058: //
059: // public Call getNext()
060: // {
061: // return next;
062: // }
063: //
064: // public Object getParameter()
065: // {
066: // return parameter;
067: // }
068: //
069: // public int getMethod()
070: // {
071: // return method;
072: // }
073: // }
074:
075: private static final int MTH_START_BLOCK = 0;
076: private static final int MTH_FINISH_BLOCK = 1;
077: private static final int MTH_START_INLINE = 2;
078: private static final int MTH_FINISH_INLINE = 3;
079: private static final int MTH_ADD_NODE = 4;
080:
081: private int[] methods;
082: private Object[] parameters;
083: private int counter;
084:
085: private ParagraphRenderBox paragraphRenderBox;
086: private Object suspendItem;
087: private boolean breakRequested;
088:
089: public SimpleLinebreaker(final ParagraphRenderBox paragraphRenderBox) {
090: this .paragraphRenderBox = paragraphRenderBox;
091: this .methods = new int[paragraphRenderBox.getPoolSize()];
092: this .parameters = new Object[paragraphRenderBox.getPoolSize()];
093: }
094:
095: private void add(final int method, final Object parameter) {
096: if (methods.length == counter) {
097: // Grow the arrays ..
098: final int nextSize = Math.max(10, (methods.length * 2));
099: final int[] newMethods = new int[nextSize];
100: System.arraycopy(methods, 0, newMethods, 0, methods.length);
101:
102: final Object[] newParameters = new Object[nextSize];
103: System.arraycopy(parameters, 0, newParameters, 0,
104: parameters.length);
105:
106: this .methods = newMethods;
107: this .parameters = newParameters;
108: }
109:
110: methods[counter] = method;
111: parameters[counter] = parameter;
112: counter += 1;
113: }
114:
115: public boolean isWritable() {
116: return true;
117: }
118:
119: public FullLinebreaker startComplexLayout() {
120: final FullLinebreaker fullBreaker = new FullLinebreaker(
121: paragraphRenderBox);
122: for (int i = 0; i < counter; i++) {
123: final int method = methods[i];
124: final Object parameter = parameters[i];
125: switch (method) {
126: case MTH_START_BLOCK: {
127: fullBreaker.startBlockBox((RenderBox) parameter);
128: break;
129: }
130: case MTH_FINISH_BLOCK: {
131: fullBreaker.finishBlockBox((RenderBox) parameter);
132: break;
133: }
134: case MTH_START_INLINE: {
135: fullBreaker.startInlineBox((InlineRenderBox) parameter);
136: break;
137: }
138: case MTH_FINISH_INLINE: {
139: fullBreaker
140: .finishInlineBox((InlineRenderBox) parameter);
141: break;
142: }
143: case MTH_ADD_NODE: {
144: fullBreaker.addNode((RenderNode) parameter);
145: break;
146: }
147: default: {
148: throw new IllegalStateException();
149: }
150: }
151: }
152:
153: paragraphRenderBox.setPoolSize(counter);
154: // replay ..
155: return fullBreaker;
156: }
157:
158: public void startBlockBox(final RenderBox child) {
159: if (suspendItem != null) {
160: suspendItem = child.getInstanceId();
161: }
162:
163: add(MTH_START_BLOCK, child);
164: }
165:
166: public void finishBlockBox(final RenderBox box) {
167: if (suspendItem == box.getInstanceId()) {
168: suspendItem = null;
169: }
170:
171: add(MTH_FINISH_BLOCK, box);
172: }
173:
174: public ParagraphLinebreaker startParagraphBox(
175: final ParagraphRenderBox box) {
176: throw new UnsupportedOperationException();
177: }
178:
179: public void finishParagraphBox(final ParagraphRenderBox box) {
180: throw new UnsupportedOperationException();
181: }
182:
183: public boolean isSuspended() {
184: return suspendItem != null;
185: }
186:
187: public void finish() {
188: paragraphRenderBox.setPoolSize(counter);
189: paragraphRenderBox.setLineBoxAge(paragraphRenderBox.getPool()
190: .getChangeTracker());
191: counter = 0;
192: Arrays.fill(parameters, null);
193: }
194:
195: public void startInlineBox(final InlineRenderBox box) {
196: add(MTH_START_INLINE, box);
197: }
198:
199: public void finishInlineBox(final InlineRenderBox box) {
200: add(MTH_FINISH_INLINE, box);
201: }
202:
203: public boolean isBreakRequested() {
204: return breakRequested;
205: }
206:
207: public void addNode(final RenderNode node) {
208: add(MTH_ADD_NODE, node);
209: }
210:
211: public void setBreakRequested(final boolean breakRequested) {
212: this.breakRequested = breakRequested;
213: }
214: }
|