Line 0
Link Here
|
|
|
1 |
/* |
2 |
* Copyright 2005 The Apache Software Foundation. |
3 |
* |
4 |
* Licensed under the Apache License, Version 2.0 (the "License"); |
5 |
* you may not use this file except in compliance with the License. |
6 |
* You may obtain a copy of the License at |
7 |
* |
8 |
* http://www.apache.org/licenses/LICENSE-2.0 |
9 |
* |
10 |
* Unless required by applicable law or agreed to in writing, software |
11 |
* distributed under the License is distributed on an "AS IS" BASIS, |
12 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
13 |
* See the License for the specific language governing permissions and |
14 |
* limitations under the License. |
15 |
*/ |
16 |
|
17 |
package org.apache.fop.render.txt; |
18 |
|
19 |
import java.io.OutputStream; |
20 |
import java.util.Arrays; |
21 |
import java.util.Iterator; |
22 |
import java.util.List; |
23 |
|
24 |
import org.apache.fop.apps.FOPException; |
25 |
import org.apache.fop.apps.FOUserAgent; |
26 |
import org.apache.fop.area.AreaTreeHandler; |
27 |
import org.apache.fop.datatypes.CompoundDatatype; |
28 |
import org.apache.fop.datatypes.Length; |
29 |
import org.apache.fop.datatypes.PercentBaseContext; |
30 |
import org.apache.fop.fo.Constants; |
31 |
import org.apache.fop.fo.FONode; |
32 |
import org.apache.fop.fo.FOText; |
33 |
import org.apache.fop.fo.expr.NumericProperty; |
34 |
import org.apache.fop.fo.flow.Block; |
35 |
import org.apache.fop.fo.flow.BlockContainer; |
36 |
import org.apache.fop.fo.flow.ExternalGraphic; |
37 |
import org.apache.fop.fo.flow.Inline; |
38 |
import org.apache.fop.fo.flow.ListBlock; |
39 |
import org.apache.fop.fo.flow.ListItem; |
40 |
import org.apache.fop.fo.flow.Table; |
41 |
import org.apache.fop.fo.flow.TableCell; |
42 |
import org.apache.fop.fo.flow.TableColumn; |
43 |
import org.apache.fop.fo.pagination.PageSequence; |
44 |
import org.apache.fop.fo.properties.CommonAbsolutePosition; |
45 |
import org.apache.fop.fo.properties.CommonBorderPaddingBackground; |
46 |
import org.apache.fop.fo.properties.CommonFont; |
47 |
import org.apache.fop.fo.properties.CommonMarginBlock; |
48 |
import org.apache.fop.fo.properties.FixedLength; |
49 |
import org.apache.fop.fo.properties.Property; |
50 |
import org.apache.fop.fo.properties.SpaceProperty; |
51 |
import org.apache.fop.layoutmgr.BlockLayoutManager; |
52 |
|
53 |
/** |
54 |
* Handler for formatting objects in case of rendering to txt. |
55 |
* |
56 |
* This handler gets page-sequence, modifies formatting objects and return them |
57 |
* to superclass. So areas are generated from modified FO. Idea of modifying is |
58 |
* to quantize FO properties, making them divisible by width of char or height |
59 |
* of char. |
60 |
*/ |
61 |
public class TXTHandler extends AreaTreeHandler { |
62 |
|
63 |
/** Percent base context. Needed for line-height. */ |
64 |
private static final PercentBaseContext CONTEXT = |
65 |
new BlockLayoutManager(new Block(null)); |
66 |
|
67 |
/** Modified font size in millipoints. */ |
68 |
private static final int MODIFIED_FONT_SIZE = 10000; |
69 |
|
70 |
/** Quantum for each side (BEFORE, AFTER, START, END). */ |
71 |
private final int[] quantum = { TXTRenderer.CHAR_HEIGHT, |
72 |
TXTRenderer.CHAR_HEIGHT, TXTRenderer.CHAR_WIDTH, |
73 |
TXTRenderer.CHAR_WIDTH }; |
74 |
|
75 |
/** Keeps overpatching for each side. */ |
76 |
private int[] overPatching = new int[4]; |
77 |
|
78 |
/** |
79 |
* Keeps last overpatching for each side. Needed for selective modifying of |
80 |
* start-indent and end-indent. |
81 |
*/ |
82 |
private int[] lastOverPatching = new int[4]; |
83 |
|
84 |
public TXTHandler(FOUserAgent userAgent, OutputStream stream) |
85 |
throws FOPException { |
86 |
super(userAgent, Constants.RENDER_TXT, stream); |
87 |
} |
88 |
|
89 |
/** |
90 |
* Sets a component <code>CP_LENGTH</code> of <code>cd</code> to |
91 |
* <code>value</code>. |
92 |
*/ |
93 |
private static void setLength(CompoundDatatype cd, int value) { |
94 |
cd.setComponent(Constants.CP_LENGTH, new FixedLength(value), true); |
95 |
} |
96 |
|
97 |
/** |
98 |
* Sets components <code>CP_MINIMUM, CP_OPTIMUM, CP_MAXIMUM</code> of |
99 |
* <code>cd</code> to <code>p</code>. |
100 |
* |
101 |
* @param cd instance of CompoundDatatype for modifying. |
102 |
* @param p property for setting. |
103 |
*/ |
104 |
private static void setMinOptMax(CompoundDatatype cd, Property p) { |
105 |
cd.setComponent(Constants.CP_MINIMUM, p, true); |
106 |
cd.setComponent(Constants.CP_OPTIMUM, p, true); |
107 |
cd.setComponent(Constants.CP_MAXIMUM, p, true); |
108 |
} |
109 |
|
110 |
/** |
111 |
* Modifies border of side. If there is no border of given side, does |
112 |
* nothing, otherwise sets border-width to half of char width or char height |
113 |
* depending on side. <p> |
114 |
* Difference between values of new border-width and old border-width is |
115 |
* saved in <code>lastOverPatching</code>. |
116 |
* |
117 |
* @param side side to modify. |
118 |
* @param bpb instance of CommonBorderPaddingBackground for modifying. |
119 |
*/ |
120 |
private void modifyBorder(int side, CommonBorderPaddingBackground bpb) { |
121 |
CommonBorderPaddingBackground.BorderInfo bi = bpb.getBorderInfo(side); |
122 |
|
123 |
if (bi != null) { |
124 |
int width = bpb.getBorderWidth(side, false); |
125 |
setLength(bi.getWidth(), quantum[side] / 2); |
126 |
lastOverPatching[side] += bpb.getBorderWidth(side, false) - width; |
127 |
} |
128 |
} |
129 |
|
130 |
/** |
131 |
* Modifies padding of side. First rounds padding to nearest integer, |
132 |
* divisible by char width or char height depending on side. If border of |
133 |
* given side is available, modifies padding in such a way, so sum of border |
134 |
* width and padding will be divisible by char width or char height, |
135 |
* depending on side. <p> |
136 |
* Difference between values of new padding and old padding is saved |
137 |
* in <code>lastOverPatching</code>. |
138 |
* |
139 |
* @param side side to modify. |
140 |
* @param bpb instance of CommonBorderPaddingBackground for modifying. |
141 |
*/ |
142 |
private void modifyPadding(int side, CommonBorderPaddingBackground bpb) { |
143 |
int oldPadding = bpb.getPadding(side, false, null); |
144 |
int newPadding = Helper.round(oldPadding, quantum[side]); |
145 |
if (bpb.getBorderInfo(side) != null) { |
146 |
newPadding = Math.max(newPadding, quantum[side]) |
147 |
- bpb.getBorderWidth(side, false); |
148 |
} |
149 |
|
150 |
setLength(bpb.getPaddingLengthProperty(side), newPadding); |
151 |
lastOverPatching[side] += newPadding - oldPadding; |
152 |
} |
153 |
|
154 |
/** |
155 |
* Modifies borders and paddings of <code>bpb</code>. |
156 |
* |
157 |
* @param bpb instance of CommonBorderPaddingBackground for modifying. |
158 |
*/ |
159 |
private void modifyBPB(CommonBorderPaddingBackground bpb) { |
160 |
modifyBorder(CommonBorderPaddingBackground.BEFORE, bpb); |
161 |
modifyBorder(CommonBorderPaddingBackground.AFTER, bpb); |
162 |
modifyBorder(CommonBorderPaddingBackground.START, bpb); |
163 |
modifyBorder(CommonBorderPaddingBackground.END, bpb); |
164 |
|
165 |
modifyPadding(CommonBorderPaddingBackground.BEFORE, bpb); |
166 |
modifyPadding(CommonBorderPaddingBackground.AFTER, bpb); |
167 |
modifyPadding(CommonBorderPaddingBackground.START, bpb); |
168 |
modifyPadding(CommonBorderPaddingBackground.END, bpb); |
169 |
} |
170 |
|
171 |
/** |
172 |
* Rounds optimum value of <code>space</code> to nearest integer, |
173 |
* divisible by <code>quantum</code>. |
174 |
* |
175 |
* @param space instance of SpaceProperty. |
176 |
* @param quantum integer. |
177 |
*/ |
178 |
private void modifySpace(SpaceProperty space, int quantum) { |
179 |
int value = space.getOptimum(null).getLength().getValue(); |
180 |
setMinOptMax(space, new FixedLength(Helper.round(value, quantum))); |
181 |
} |
182 |
|
183 |
/** |
184 |
* @param length instance of Length. |
185 |
* @param quantum integer. |
186 |
* @return instance of Length, having value nearest to value of |
187 |
* <code>length</code>, and divisible by <code>quantum</code>. |
188 |
*/ |
189 |
private Length roundLength(Length length, int quantum) { |
190 |
int x = Helper.round(length.getValue(), quantum); |
191 |
return new FixedLength(x); |
192 |
} |
193 |
|
194 |
/** |
195 |
* @param length instance of Length. |
196 |
* @param quantum integer. |
197 |
* @return instance of Length, having minimal value, greater value of |
198 |
* <code>length</code>, and divisible by <code>quantum</code>. |
199 |
*/ |
200 |
private Length ceilLength(Length length, int quantum) { |
201 |
int x = Helper.ceil(length.getValue(), quantum); |
202 |
return new FixedLength(x); |
203 |
} |
204 |
|
205 |
/** |
206 |
* Modifies indent for given side. Summarizes value of indent and modifing |
207 |
* error (i.e. overPatching). Rounds result to nearest integer, divisible by |
208 |
* quantum. |
209 |
* |
210 |
* @param indent Length to modify. |
211 |
* @param side an integer, representing side. |
212 |
* @return modified Length. |
213 |
*/ |
214 |
private Length modifyIndent(Length indent, int side) { |
215 |
if (indent instanceof NumericProperty) { |
216 |
overPatching[side] += lastOverPatching[side]; |
217 |
} |
218 |
int newValue = indent.getValue() + overPatching[side]; |
219 |
newValue = Helper.round(newValue, quantum[side]); |
220 |
return new FixedLength(newValue); |
221 |
} |
222 |
|
223 |
/** |
224 |
* Modifies Common Margin Properties-Block: |
225 |
* <ul> |
226 |
* <li>margin-top, margin-left, margin-bottom, margin-right |
227 |
* <li>start-indent, end-indent |
228 |
* <li>space-before, space-after. |
229 |
* </ul> |
230 |
* |
231 |
* @param cmb instance of CommonMarginBlock to modify. |
232 |
*/ |
233 |
private void modifyCommonMarginBlock(CommonMarginBlock cmb) { |
234 |
cmb.marginTop = roundLength(cmb.marginTop, TXTRenderer.CHAR_HEIGHT); |
235 |
cmb.marginBottom = roundLength(cmb.marginBottom, |
236 |
TXTRenderer.CHAR_HEIGHT); |
237 |
cmb.marginLeft = roundLength(cmb.marginLeft, TXTRenderer.CHAR_WIDTH); |
238 |
cmb.marginRight = roundLength(cmb.marginRight, TXTRenderer.CHAR_WIDTH); |
239 |
|
240 |
modifySpace(cmb.spaceBefore, TXTRenderer.CHAR_HEIGHT); |
241 |
modifySpace(cmb.spaceAfter, TXTRenderer.CHAR_HEIGHT); |
242 |
|
243 |
cmb.startIndent = modifyIndent(cmb.startIndent, |
244 |
CommonBorderPaddingBackground.START); |
245 |
cmb.endIndent = modifyIndent(cmb.endIndent, |
246 |
CommonBorderPaddingBackground.END); |
247 |
} |
248 |
|
249 |
/** |
250 |
* Modifies fo:table attributes: |
251 |
* <ul> |
252 |
* <li>Common Margin Properties Block |
253 |
* <li>Common Border, Padding, and Background Properties |
254 |
* <li>columns. |
255 |
* </ul> |
256 |
* |
257 |
* @param table Table to modify. |
258 |
*/ |
259 |
private void modifyTable(Table table) { |
260 |
CommonMarginBlock cmb = table.getCommonMarginBlock(); |
261 |
if (table.getBorderCollapse() == Constants.EN_COLLAPSE) { |
262 |
// If border-collapse == "collapse", add space-after in order to |
263 |
// impove interaction with other FO. |
264 |
int value = cmb.spaceAfter.getOptimum(null).getLength().getValue(); |
265 |
value += TXTRenderer.CHAR_HEIGHT; |
266 |
setMinOptMax(cmb.spaceAfter, new FixedLength(value)); |
267 |
} |
268 |
modifyCommonMarginBlock(cmb); |
269 |
|
270 |
modifyBPB(table.getCommonBorderPaddingBackground()); |
271 |
|
272 |
// modify all table-columns |
273 |
List columnList = table.getColumns(); |
274 |
Iterator iter = columnList.iterator(); |
275 |
while (iter.hasNext()) { |
276 |
modifyTableColumn((TableColumn) iter.next()); |
277 |
} |
278 |
} |
279 |
|
280 |
/** |
281 |
* Modifies fo:table-column attributes: |
282 |
* <ul> |
283 |
* <li>width. |
284 |
* </ul> |
285 |
* |
286 |
* @param column TableColumn to modify. |
287 |
*/ |
288 |
private void modifyTableColumn(TableColumn column) { |
289 |
column.setColumnWidth(ceilLength(column.getColumnWidth(), |
290 |
TXTRenderer.CHAR_WIDTH)); |
291 |
} |
292 |
|
293 |
/** |
294 |
* Modifies padding of fo:table-cell. |
295 |
* |
296 |
* @param side side. |
297 |
* @param bpb instance of CommonBorderPaddingBackground to modify. |
298 |
*/ |
299 |
private void modifyCellPadding(int side, CommonBorderPaddingBackground bpb) { |
300 |
if (bpb.getBorderInfo(side) == null) { |
301 |
int oldPadding = bpb.getPadding(side, false, null); |
302 |
int newPadding = oldPadding + quantum[side] / 2; |
303 |
setLength(bpb.getPaddingLengthProperty(side), newPadding); |
304 |
} |
305 |
} |
306 |
|
307 |
/** |
308 |
* Modifies table-cell properties: |
309 |
* <ul> |
310 |
* <li>Common Border, Padding, and Background Properties. |
311 |
* </ul> |
312 |
* |
313 |
* @param c TableCell to modify. |
314 |
*/ |
315 |
private void modifyTableCell(TableCell c) { |
316 |
CommonBorderPaddingBackground bpb = c |
317 |
.getCommonBorderPaddingBackground(); |
318 |
modifyBPB(bpb); |
319 |
modifyCellPadding(CommonBorderPaddingBackground.BEFORE, bpb); |
320 |
modifyCellPadding(CommonBorderPaddingBackground.AFTER, bpb); |
321 |
modifyCellPadding(CommonBorderPaddingBackground.START, bpb); |
322 |
modifyCellPadding(CommonBorderPaddingBackground.END, bpb); |
323 |
} |
324 |
|
325 |
/** |
326 |
* Modifies Common Absolute Position Properties: |
327 |
* <ul> |
328 |
* <li>left |
329 |
* <li>top. |
330 |
* </ul> |
331 |
* |
332 |
* @param cap CommonAbsolutePosition to modify. |
333 |
*/ |
334 |
private void modifyCommonAbsolutePosition(CommonAbsolutePosition cap) { |
335 |
if (cap.absolutePosition == Constants.EN_ABSOLUTE) { |
336 |
cap.left = roundLength(cap.left, TXTRenderer.CHAR_WIDTH); |
337 |
cap.top = roundLength(cap.top, TXTRenderer.CHAR_HEIGHT); |
338 |
} |
339 |
} |
340 |
|
341 |
/** |
342 |
* Modifies line-height property. Sets a value of line-height to max(char |
343 |
* height; lowest integer, divisible by char height). |
344 |
* |
345 |
* @param lineHeight SpaceProperty to modify. |
346 |
*/ |
347 |
private void modifyLineHeight(SpaceProperty lineHeight) { |
348 |
Property p = lineHeight.getOptimum(null); |
349 |
int value = p.getLength().getValue(CONTEXT); |
350 |
|
351 |
int height = TXTRenderer.CHAR_HEIGHT; |
352 |
int newValue = Math.max(Helper.floor(value, height), height); |
353 |
setMinOptMax(lineHeight, new FixedLength(newValue)); |
354 |
} |
355 |
|
356 |
/** |
357 |
* Modifies Common Font Properties: |
358 |
* <ul> |
359 |
* <li>font-family = Courier; |
360 |
* <li>font-size = MODIFIED_FONT_SIZE; |
361 |
* <li>font-stretch = EN_NORMAL; |
362 |
* <li>font-weight = EN_NORMAL. |
363 |
* </ul> |
364 |
* |
365 |
* @param cf the font to modify. |
366 |
*/ |
367 |
private void modifyCommonFont(CommonFont cf) { |
368 |
if (cf != null) { |
369 |
cf.fontFamily = "Courier"; |
370 |
cf.fontSize = new FixedLength(MODIFIED_FONT_SIZE); |
371 |
cf.fontStretch = Constants.EN_NORMAL; |
372 |
cf.fontWeight = Constants.EN_NORMAL; |
373 |
} |
374 |
} |
375 |
|
376 |
/** |
377 |
* Modifies fo:block: |
378 |
* <ul> |
379 |
* <li>Common Border, Padding, and Background Properties |
380 |
* <li>Common Margin Properties-Block |
381 |
* <li>Common Font Properties |
382 |
* <li>line-height. |
383 |
* </ul> |
384 |
* |
385 |
* @param block Block to modify. |
386 |
*/ |
387 |
private void modifyBlock(Block block) { |
388 |
modifyBPB(block.getCommonBorderPaddingBackground()); |
389 |
modifyCommonMarginBlock(block.getCommonMarginBlock()); |
390 |
modifyCommonFont(block.getCommonFont()); |
391 |
modifyLineHeight(block.getLineHeight()); |
392 |
} |
393 |
|
394 |
/** |
395 |
* Modifies fo:block-container: |
396 |
* <ul> |
397 |
* <li>Common Border, Padding, and Background Properties |
398 |
* <li>Common Margin Properties-Block |
399 |
* <li>Common Absolute Position Properties. |
400 |
* </ul> |
401 |
* |
402 |
* @param bc BlockContainer to modify. |
403 |
*/ |
404 |
private void modifyBlockContainer(BlockContainer bc) { |
405 |
modifyBPB(bc.getCommonBorderPaddingBackground()); |
406 |
modifyCommonMarginBlock(bc.getCommonMarginBlock()); |
407 |
modifyCommonAbsolutePosition(bc.getCommonAbsolutePosition()); |
408 |
} |
409 |
|
410 |
/** |
411 |
* Modifies fo:inline: |
412 |
* <ul> |
413 |
* <li>Common Font Properties |
414 |
* </ul> |
415 |
* |
416 |
* @param inline Inline to modify. |
417 |
*/ |
418 |
private void modifyInline(Inline inline) { |
419 |
modifyCommonFont(inline.getCommonFont()); |
420 |
} |
421 |
|
422 |
/** |
423 |
* Modifies FOText: |
424 |
* <ul> |
425 |
* <li>Common Font Properties |
426 |
* </ul> |
427 |
* |
428 |
* @param text FOText to modify. |
429 |
*/ |
430 |
private void modifyFOText(FOText text) { |
431 |
modifyCommonFont(text.getCommonFont()); |
432 |
} |
433 |
|
434 |
/** |
435 |
* Modifies fo:external-graphic: |
436 |
* <ul> |
437 |
* <li>Common Border, Padding, and Background Properties |
438 |
* <li>line-height. |
439 |
* </ul> |
440 |
* |
441 |
* @param eg ExternalGraphic to modify. |
442 |
*/ |
443 |
private void modifyExternalGraphic(ExternalGraphic eg) { |
444 |
modifyBPB(eg.getCommonBorderPaddingBackground()); |
445 |
modifyLineHeight(eg.getLineHeight()); |
446 |
} |
447 |
|
448 |
/** |
449 |
* Modifies fo:list-block: |
450 |
* <ul> |
451 |
* <li>Common Border, Padding, and Background Properties |
452 |
* <li>Common Margin Properties-Block. |
453 |
* </ul> |
454 |
* |
455 |
* @param lb ListBlock to modify. |
456 |
*/ |
457 |
private void modifyListBlock(ListBlock lb) { |
458 |
modifyBPB(lb.getCommonBorderPaddingBackground()); |
459 |
modifyCommonMarginBlock(lb.getCommonMarginBlock()); |
460 |
} |
461 |
|
462 |
/** |
463 |
* Modifies fo:list-item: |
464 |
* <ul> |
465 |
* <li>Common Border, Padding, and Background Properties |
466 |
* <li>Common Margin Properties-Block. |
467 |
* </ul> |
468 |
* <p> |
469 |
* Make refinement for fo:list-item-label and fo:list-item-body. |
470 |
* |
471 |
* @param li ListItem to modify. |
472 |
*/ |
473 |
private void modifyListItem(ListItem li) { |
474 |
modifyBPB(li.getCommonBorderPaddingBackground()); |
475 |
modifyCommonMarginBlock(li.getCommonMarginBlock()); |
476 |
refinement(li.getLabel()); |
477 |
refinement(li.getBody()); |
478 |
} |
479 |
|
480 |
/** |
481 |
* Does refinement for particular node. Modifies node's properties and |
482 |
* refines its children recursively. |
483 |
* |
484 |
* @param node the node to refine. |
485 |
*/ |
486 |
private void refinement(FONode node) { |
487 |
int[] saveOverPatching = (int[]) overPatching.clone(); |
488 |
Arrays.fill(lastOverPatching, 0); |
489 |
|
490 |
if (node instanceof Block) { |
491 |
modifyBlock((Block) node); |
492 |
} else if (node instanceof BlockContainer) { |
493 |
modifyBlockContainer((BlockContainer) node); |
494 |
} else if (node instanceof Inline) { |
495 |
modifyInline((Inline) node); |
496 |
} else if (node instanceof FOText) { |
497 |
modifyFOText((FOText) node); |
498 |
} else if (node instanceof Table) { |
499 |
modifyTable((Table) node); |
500 |
Arrays.fill(overPatching, 0); |
501 |
} else if (node instanceof TableCell) { |
502 |
modifyTableCell((TableCell) node); |
503 |
} else if (node instanceof ExternalGraphic) { |
504 |
modifyExternalGraphic((ExternalGraphic) node); |
505 |
} else if (node instanceof ListBlock) { |
506 |
modifyListBlock((ListBlock) node); |
507 |
} else if (node instanceof ListItem) { |
508 |
modifyListItem((ListItem) node); |
509 |
} |
510 |
|
511 |
Iterator it = node.getChildNodes(); |
512 |
if (it != null) { |
513 |
while (it.hasNext()) { |
514 |
refinement((FONode) it.next()); |
515 |
} |
516 |
} |
517 |
overPatching = saveOverPatching; |
518 |
} |
519 |
|
520 |
/** |
521 |
* Run refinement for: |
522 |
* <ul> |
523 |
* <li>mainflow (xsl-region-body) |
524 |
* <li>staticflow (xsl-region-before, xsl-region-after, xsl-region-start, |
525 |
* xsl-region-end). |
526 |
* </ul> |
527 |
* |
528 |
* @param pageSequence PageSequence to refine. |
529 |
*/ |
530 |
public void endPageSequence(PageSequence pageSequence) { |
531 |
Arrays.fill(overPatching, 0); |
532 |
|
533 |
refinement(pageSequence.getMainFlow()); |
534 |
|
535 |
if (pageSequence.getStaticContent("xsl-region-before") != null) { |
536 |
refinement(pageSequence.getStaticContent("xsl-region-before")); |
537 |
} |
538 |
if (pageSequence.getStaticContent("xsl-region-after") != null) { |
539 |
refinement(pageSequence.getStaticContent("xsl-region-after")); |
540 |
} |
541 |
if (pageSequence.getStaticContent("xsl-region-start") != null) { |
542 |
refinement(pageSequence.getStaticContent("xsl-region-start")); |
543 |
} |
544 |
if (pageSequence.getStaticContent("xsl-region-end") != null) { |
545 |
refinement(pageSequence.getStaticContent("xsl-region-end")); |
546 |
} |
547 |
|
548 |
super.endPageSequence(pageSequence); |
549 |
} |
550 |
} |