blob: af4791a409d5294467d512f971b883908daa4014 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
|
/*
* $Id$
* Copyright (C) 2001 The Apache Software Foundation. All rights reserved.
* For details on use and redistribution please refer to the
* LICENSE file included with these sources.
*/
package org.apache.fop.fo;
// FOP
import org.apache.fop.apps.FOPException;
import org.apache.fop.layout.Area;
import org.apache.fop.layout.AreaClass;
import org.apache.fop.layout.LinkSet;
import org.apache.fop.system.BufferManager;
import org.apache.fop.fo.flow.Marker;
import org.apache.log.Logger;
// Java
import java.util.Vector;
import java.util.Hashtable;
/**
* base class for nodes in the formatting object tree
*
* Modified by Mark Lillywhite mark-fop@inomial.com. Made
* Vector a protected member. (/me things this should be
* a private member with an API for adding children;
* this woudl save a lot of memory because the Vector
* would not have to be instantiated unless the node had
* children).
*/
abstract public class FONode {
protected FObj parent;
protected String areaClass = AreaClass.UNASSIGNED;
public BufferManager bufferManager;
protected Vector children = new Vector(); // made public for searching for id's
/**
* value of marker before layout begins
*/
public final static int START = -1000;
/**
* value of marker after break-after
*/
public final static int BREAK_AFTER = -1001;
/**
* where the layout was up to.
* for FObjs it is the child number
* for FOText it is the character number
*/
protected int marker = START;
protected boolean isInTableCell = false;
protected int forcedStartOffset = 0;
protected int forcedWidth = 0;
protected int widows = 0;
protected int orphans = 0;
protected LinkSet linkSet;
// count of areas generated-by/returned-by
public int areasGenerated = 0;
// markers
protected Hashtable markers;
protected Logger log;
protected FONode(FObj parent) {
this.parent = parent;
if (parent != null) {
this.bufferManager = parent.bufferManager;
}
markers = new Hashtable();
if (null != parent)
this.areaClass = parent.areaClass;
}
public void setLogger(Logger logger) {
log = logger;
}
public void setIsInTableCell() {
this.isInTableCell = true;
// made recursive by Eric Schaeffer
for (int i = 0; i < this.children.size(); i++) {
FONode child = (FONode)this.children.elementAt(i);
child.setIsInTableCell();
}
}
public void forceStartOffset(int offset) {
this.forcedStartOffset = offset;
// made recursive by Eric Schaeffer
for (int i = 0; i < this.children.size(); i++) {
FONode child = (FONode)this.children.elementAt(i);
child.forceStartOffset(offset);
}
}
public void forceWidth(int width) {
this.forcedWidth = width;
// made recursive by Eric Schaeffer
for (int i = 0; i < this.children.size(); i++) {
FONode child = (FONode)this.children.elementAt(i);
child.forceWidth(width);
}
}
public void resetMarker() {
this.marker = START;
int numChildren = this.children.size();
for (int i = 0; i < numChildren; i++) {
((FONode)children.elementAt(i)).resetMarker();
}
}
public void setWidows(int wid) {
widows = wid;
}
public void setOrphans(int orph) {
orphans = orph;
}
public void removeAreas() {
// still to do
}
protected void addChild(FONode child) {
children.addElement(child);
}
public FObj getParent() {
return this.parent;
}
public void setBufferManager(BufferManager bufferManager) {
this.bufferManager = bufferManager;
}
public BufferManager getBufferManager() {
return this.bufferManager;
}
public void setLinkSet(LinkSet linkSet) {
this.linkSet = linkSet;
for (int i = 0; i < this.children.size(); i++) {
FONode child = (FONode)this.children.elementAt(i);
child.setLinkSet(linkSet);
}
}
public LinkSet getLinkSet() {
return this.linkSet;
}
abstract public Status layout(Area area) throws FOPException;
/**
* lets outside sources access the property list
* first used by PageNumberCitation to find the "id" property
* returns null by default, overide this function when there is a property list
* @param name - the name of the desired property to obtain
* @returns the property
*/
public Property getProperty(String name) {
return (null);
}
/**
* At the start of a new span area layout may be partway through a
* nested FO, and balancing requires rollback to this known point.
* The snapshot records exactly where layout is at.
* @param snapshot a Vector of markers (Integer)
* @returns the updated Vector of markers (Integers)
*/
public Vector getMarkerSnapshot(Vector snapshot) {
snapshot.addElement(new Integer(this.marker));
// terminate if no kids or child not yet accessed
if (this.marker < 0)
return snapshot;
else if (children.isEmpty())
return snapshot;
else
return ((FONode)children.elementAt(this.marker)).getMarkerSnapshot(snapshot);
}
/**
* When balancing occurs, the flow layout() method restarts at the
* point specified by the current marker snapshot, which is retrieved
* and restored using this method.
* @param snapshot the Vector of saved markers (Integers)
*/
public void rollback(Vector snapshot) {
this.marker = ((Integer)snapshot.elementAt(0)).intValue();
snapshot.removeElementAt(0);
if (this.marker == START) {
// make sure all the children of this FO are also reset
resetMarker();
return;
} else if ((this.marker == -1) || children.isEmpty())
return;
int numChildren = this.children.size();
if (this.marker <= START) {
return;
}
for (int i = this.marker + 1; i < numChildren; i++) {
FONode fo = (FONode)children.elementAt(i);
fo.resetMarker();
}
((FONode)children.elementAt(this.marker)).rollback(snapshot);
}
public void addMarker(Marker marker) throws FOPException {
String mcname = marker.getMarkerClassName();
if (!markers.containsKey(mcname) && children.isEmpty()) {
markers.put(mcname, marker);
} else {
log.error("fo:marker must be an initial child,"
+ "and 'marker-class-name' must be unique for same parent");
throw new FOPException("fo:marker must be an initial child,"
+ "and 'marker-class-name' must be unique for same parent");
}
}
public boolean hasMarkers() {
return !markers.isEmpty();
}
public Vector getMarkers() {
return new Vector(markers.values());
}
}
|