KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > fop > fo > flow > Block


1 /*
2  * $Id: Block.java,v 1.41.2.18 2003/04/11 00:24:38 pietsch Exp $
3  * ============================================================================
4  * The Apache Software License, Version 1.1
5  * ============================================================================
6  *
7  * Copyright (C) 1999-2003 The Apache Software Foundation. All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without modifica-
10  * tion, are permitted provided that the following conditions are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  *
19  * 3. The end-user documentation included with the redistribution, if any, must
20  * include the following acknowledgment: "This product includes software
21  * developed by the Apache Software Foundation (http://www.apache.org/)."
22  * Alternately, this acknowledgment may appear in the software itself, if
23  * and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. The names "FOP" and "Apache Software Foundation" must not be used to
26  * endorse or promote products derived from this software without prior
27  * written permission. For written permission, please contact
28  * apache@apache.org.
29  *
30  * 5. Products derived from this software may not be called "Apache", nor may
31  * "Apache" appear in their name, without prior written permission of the
32  * Apache Software Foundation.
33  *
34  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
35  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
36  * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
37  * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
38  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU-
39  * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
40  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
41  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
42  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
43  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44  * ============================================================================
45  *
46  * This software consists of voluntary contributions made by many individuals
47  * on behalf of the Apache Software Foundation and was originally created by
48  * James Tauber <jtauber@jtauber.com>. For more information on the Apache
49  * Software Foundation, please see <http://www.apache.org/>.
50  */

51 package org.apache.fop.fo.flow;
52
53 // FOP
54
import org.apache.fop.fo.*;
55 import org.apache.fop.layout.*;
56 import org.apache.fop.apps.FOPException;
57
58 /*
59   Modified by Mark Lillywhite mark-fop@inomial.com. The changes
60   here are based on memory profiling and do not change functionality.
61   Essentially, the Block object had a pointer to a BlockArea object
62   that it created. The BlockArea was not referenced after the Block
63   was finished except to determine the size of the BlockArea, however
64   a reference to the BlockArea was maintained and this caused a lot of
65   GC problems, and was a major reason for FOP memory leaks. So,
66   the reference to BlockArea was made local, the required information
67   is now stored (instead of a reference to the complex BlockArea object)
68   and it appears that there are a lot of changes in this file, in fact
69   there are only a few sematic changes; mostly I just got rid of
70   "this." from blockArea since BlockArea is now local.
71   */

72
73 public class Block extends FObjMixed {
74
75     public static class Maker extends FObj.Maker {
76         public FObj make(FObj parent, PropertyList propertyList,
77                          String JavaDoc systemId, int line, int column)
78             throws FOPException {
79             return new Block(parent, propertyList, systemId, line, column);
80         }
81
82     }
83
84     public static FObj.Maker maker() {
85         return new Block.Maker();
86     }
87
88     int align;
89     int alignLast;
90     int breakAfter;
91     int lineHeight;
92     int startIndent;
93     int endIndent;
94     int spaceBefore;
95     int spaceAfter;
96     int textIndent;
97     int keepWithNext;
98
99     int areaHeight = 0;
100     int contentWidth = 0;
101     int infLoopThreshhold = 50;
102
103     String JavaDoc id;
104     int span;
105     boolean breakStatusBeforeChecked = false;
106
107     // this may be helpful on other FOs too
108
boolean anythingLaidOut = false;
109     //Added to see how long it's been since nothing was laid out.
110
int noLayoutCount = 0;
111
112     public Block(FObj parent, PropertyList propertyList,
113                  String JavaDoc systemId, int line, int column)
114         throws FOPException {
115         super(parent, propertyList, systemId, line, column);
116         this.span = this.properties.get("span").getEnum();
117     }
118
119     public String JavaDoc getName() {
120         return "fo:block";
121     }
122
123     public int layout(Area area) throws FOPException {
124         if (!breakStatusBeforeChecked) {
125             breakStatusBeforeChecked = true;
126             // no break if first in area tree, or leading in context
127
// area
128
int breakBeforeStatus = propMgr.checkBreakBefore(area);
129             if (breakBeforeStatus != Status.OK) {
130                 return breakBeforeStatus;
131             }
132         }
133
134         BlockArea blockArea;
135
136         if (!anythingLaidOut) {
137             noLayoutCount++;
138         }
139         if (noLayoutCount > infLoopThreshhold) {
140             throw new FOPException(
141                 "No meaningful layout in block after many attempts. "+
142                 "Infinite loop is assumed. Processing halted.",
143                 systemId, line, column);
144         }
145
146         // log.error(" b:LAY[" + marker + "] ");
147

148         if (this.marker == BREAK_AFTER) {
149             return Status.OK;
150         }
151
152         if (this.marker == START) {
153             noLayoutCount=0; // Reset the "loop counter".
154

155             // Common Accessibility Properties
156
AccessibilityProps mAccProps = propMgr.getAccessibilityProps();
157
158             // Common Aural Properties
159
AuralProps mAurProps = propMgr.getAuralProps();
160
161             // Common Border, Padding, and Background Properties
162
BorderAndPadding bap = propMgr.getBorderAndPadding();
163             BackgroundProps bProps = propMgr.getBackgroundProps();
164
165             // Common Font Properties
166
//this.fontState = propMgr.getFontState(area.getFontInfo());
167

168             // Common Hyphenation Properties
169
HyphenationProps mHyphProps = propMgr.getHyphenationProps();
170
171             // Common Margin Properties-Block
172
MarginProps mProps = propMgr.getMarginProps();
173
174             // Common Relative Position Properties
175
RelativePositionProps mRelProps = propMgr.getRelativePositionProps();
176
177             this.align = this.properties.get("text-align").getEnum();
178             this.alignLast = this.properties.get("text-align-last").getEnum();
179             this.breakAfter = this.properties.get("break-after").getEnum();
180             this.lineHeight =
181                 this.properties.get("line-height").getLength().mvalue();
182             this.startIndent =
183                 this.properties.get("start-indent").getLength().mvalue();
184             this.endIndent =
185                 this.properties.get("end-indent").getLength().mvalue();
186             this.spaceBefore =
187                 this.properties.get("space-before.optimum").getLength().mvalue();
188             this.spaceAfter =
189                 this.properties.get("space-after.optimum").getLength().mvalue();
190             this.textIndent =
191                 this.properties.get("text-indent").getLength().mvalue();
192             this.keepWithNext =
193                 this.properties.get("keep-with-next").getEnum();
194
195             this.id = this.properties.get("id").getString();
196
197             if (area instanceof BlockArea) {
198                 area.end();
199             }
200
201             if (area.getIDReferences() != null) {
202                 try {
203                     area.getIDReferences().createID(id);
204                 }
205                 catch(FOPException e) {
206                     if (!e.isLocationSet()) {
207                         e.setLocation(systemId, line, column);
208                     }
209                     throw e;
210                 }
211             }
212
213             this.marker = 0;
214         }
215
216         if ((spaceBefore != 0) && (this.marker == 0)) {
217             area.addDisplaySpace(spaceBefore);
218         }
219
220         if (anythingLaidOut) {
221             this.textIndent = 0;
222         }
223
224         if (marker == 0 && area.getIDReferences() != null) {
225             area.getIDReferences().configureID(id, area);
226         }
227
228         int spaceLeft = area.spaceLeft();
229         blockArea =
230             new BlockArea(propMgr.getFontState(area.getFontInfo()),
231                           area.getAllocationWidth(), area.spaceLeft(),
232                           startIndent, endIndent, textIndent, align,
233                           alignLast, lineHeight);
234         blockArea.setGeneratedBy(this);
235         this.areasGenerated++;
236         if (this.areasGenerated == 1)
237             blockArea.isFirst(true);
238         // markers
239
// if (this.hasMarkers())
240
// blockArea.addMarkers(this.getMarkers());
241

242         blockArea.setParent(area); // BasicLink needs it
243
blockArea.setPage(area.getPage());
244         blockArea.setBackground(propMgr.getBackgroundProps());
245         blockArea.setBorderAndPadding(propMgr.getBorderAndPadding());
246         blockArea.setHyphenation(propMgr.getHyphenationProps());
247         blockArea.start();
248
249         blockArea.setAbsoluteHeight(area.getAbsoluteHeight());
250         blockArea.setIDReferences(area.getIDReferences());
251
252         blockArea.setTableCellXOffset(area.getTableCellXOffset());
253
254         int numChildren = this.children.size();
255         for (int i = this.marker; i < numChildren; i++) {
256             FONode fo = (FONode)children.get(i);
257             int status = fo.layout(blockArea);
258             if (Status.isIncomplete(status)) {
259                 this.marker = i;
260                 if (status == Status.AREA_FULL_NONE) {
261                     if (i == 0) {
262                         // Nothing was laid out.
263
anythingLaidOut = false;
264                         return status;
265                     } else {
266                         // A previous child has already been laid out.
267
area.addChild(blockArea);
268                         area.setMaxHeight(area.getMaxHeight() - spaceLeft
269                                           + blockArea.getMaxHeight());
270                         area.increaseHeight(blockArea.getHeight());
271                         anythingLaidOut = true;
272                         return Status.AREA_FULL_SOME;
273                     }
274                 }
275                 // Something has been laid out.
276
area.addChild(blockArea);
277                 area.setMaxHeight(area.getMaxHeight() - spaceLeft
278                                   + blockArea.getMaxHeight());
279                 area.increaseHeight(blockArea.getHeight());
280                 anythingLaidOut = true;
281                 return status;
282             }
283             anythingLaidOut = true;
284         }
285
286         blockArea.end();
287         blockArea.isLast(true);
288         area.addChild(blockArea);
289         area.setMaxHeight(area.getMaxHeight() - spaceLeft
290                           + blockArea.getMaxHeight());
291         area.increaseHeight(blockArea.getHeight());
292
293         if (spaceAfter != 0) {
294             area.addDisplaySpace(spaceAfter);
295         }
296
297         if (area instanceof BlockArea) {
298             area.start();
299         }
300         areaHeight= blockArea.getHeight();
301         contentWidth= blockArea.getContentWidth();
302
303         // no break if last in area tree, or trailing in context
304
// area
305
int breakAfterStatus = propMgr.checkBreakAfter(area);
306         if (breakAfterStatus != Status.OK) {
307             this.marker = BREAK_AFTER;
308             blockArea = null;
309             return breakAfterStatus;
310         }
311         if (keepWithNext != 0) {
312             return Status.KEEP_WITH_NEXT;
313         }
314         return Status.OK;
315     }
316
317     public int getAreaHeight() {
318         return areaHeight;
319     }
320
321
322     /**
323      * Return the content width of the boxes generated by this FO.
324      */

325     public int getContentWidth() {
326         return contentWidth; // getAllocationWidth()??
327
}
328
329
330     public int getSpan() {
331         return this.span;
332     }
333
334     public void resetMarker() {
335         anythingLaidOut = false;
336         super.resetMarker();
337     }
338
339 }
340
Popular Tags