1 /************************************************************************/
2 /* */
3 /* Geometry calculations about external items. */
4 /* */
5 /************************************************************************/
6
7 # include "docLayoutConfig.h"
8
9 # include <stddef.h>
10
11 # include "docLayout.h"
12 # include "docSelectLayout.h"
13 # include <docPageGrid.h>
14 # include <docField.h>
15 # include <docTreeType.h>
16 # include <docTreeNode.h>
17 # include <docTextLine.h>
18 # include <docNotes.h>
19 # include <docRecalculateFields.h>
20
21 # include <appDebugon.h>
22
23 /************************************************************************/
24 /* */
25 /* Determine the box around a header or a footer. */
26 /* */
27 /************************************************************************/
28
docNoteSeparatorBox(DocumentRectangle * dr,int noteItKind,int noteSepKind,int page,int column,const LayoutContext * lc)29 static int docNoteSeparatorBox( DocumentRectangle * dr,
30 int noteItKind,
31 int noteSepKind,
32 int page,
33 int column,
34 const LayoutContext * lc )
35 {
36 DocumentTree * eiNoteSep;
37 int y0Twips;
38 struct DocumentNote * dnFirstNote;
39 DocumentField * dfNote;
40
41 dfNote= docGetFirstNoteInColumn( &dnFirstNote, lc->lcDocument,
42 page, column, noteItKind );
43
44 if ( ! dfNote )
45 { XDEB(dfNote); return -1; }
46
47 if ( docNoteSeparatorRectangle( dr, &eiNoteSep, &y0Twips,
48 dnFirstNote, noteSepKind, lc ) )
49 { LDEB(1); return -1; }
50
51 return 0;
52 }
53
docGetBoxAroundTree(DocumentRectangle * dr,const BufferItem * bodySectNode,const DocumentTree * tree,int justUsed,int page,int column,const LayoutContext * lc)54 int docGetBoxAroundTree( DocumentRectangle * dr,
55 const BufferItem * bodySectNode,
56 const DocumentTree * tree,
57 int justUsed,
58 int page,
59 int column,
60 const LayoutContext * lc )
61 {
62 int rval= 0;
63 BufferItem * treeRoot= tree->dtRoot;
64
65 BlockFrame bf;
66 DocumentRectangle drTwips;
67 DocumentRectangle drBox;
68
69 docLayoutInitBlockFrame( &bf );
70
71 if ( ! treeRoot )
72 { XDEB(treeRoot); rval= -1; goto ready; }
73
74 switch( treeRoot->biTreeType )
75 {
76 case DOCinFIRST_HEADER:
77 case DOCinLEFT_HEADER:
78 case DOCinRIGHT_HEADER:
79 case DOCinFIRST_FOOTER:
80 case DOCinLEFT_FOOTER:
81 case DOCinRIGHT_FOOTER:
82
83 docBlockFrameTwips( &bf, treeRoot, lc->lcDocument, page, column );
84
85 drTwips= bf.bfContentRect;
86
87 if ( justUsed )
88 {
89 drTwips.drY0= tree->dtY0UsedTwips;
90 drTwips.drY1= tree->dtY1UsedTwips;
91 }
92 else{
93 drTwips.drY0= tree->dtY0ReservedTwips;
94 drTwips.drY1= tree->dtY1ReservedTwips;
95 }
96
97 docGetPixelRect( &drBox, lc, &drTwips, page );
98
99 *dr= drBox; break;
100
101 case DOCinFOOTNOTE:
102 case DOCinENDNOTE:
103
104 {
105 DocumentPosition dpTop;
106 DocumentPosition dpBot;
107
108 int lineTop;
109 int lineBot;
110
111 int partTop;
112 int partBot;
113
114 const TextLine * tlTop;
115 const TextLine * tlBot;
116
117 LayoutPosition lpTop;
118 LayoutPosition lpBot;
119
120 docBlockFrameTwips( &bf, tree->dtRoot, lc->lcDocument,
121 page, column );
122
123 if ( docGetFirstInColumnForNode( &dpTop, &lineTop, &partTop,
124 tree->dtRoot, page, column ) )
125 {
126 LLDEB(page,column);
127 SDEB(docTreeTypeStr(tree->dtRoot->biTreeType));
128 rval= -1; goto ready;
129 }
130
131 if ( docGetLastInColumnForNode( &dpBot, &lineBot, &partBot,
132 tree->dtRoot, page, column ) )
133 { LDEB(page); rval= -1; goto ready; }
134
135 tlTop= dpTop.dpNode->biParaLines+ lineTop;
136 tlBot= dpBot.dpNode->biParaLines+ lineBot;
137
138 lpTop= tlTop->tlTopPosition;
139 lpBot= tlBot->tlTopPosition;
140 lpBot.lpPageYTwips += tlBot->tlLineStride;
141
142 docGetPixelRectForPos( &drBox, lc,
143 bf.bfContentRect.drX0, bf.bfContentRect.drX1,
144 &lpTop, &lpBot );
145 }
146
147 *dr= drBox; break;
148
149 case DOCinFTNSEP:
150 case DOCinFTNSEPC:
151 case DOCinFTNCN:
152
153 if ( docNoteSeparatorBox( &drBox,
154 DOCinFOOTNOTE, treeRoot->biTreeType,
155 page, column, lc ) )
156 { LLDEB(page,column); rval= -1; goto ready; }
157
158 *dr= drBox; break;
159
160 case DOCinAFTNSEP:
161 case DOCinAFTNSEPC:
162 case DOCinAFTNCN:
163
164 if ( docNoteSeparatorBox( &drBox,
165 DOCinENDNOTE, treeRoot->biTreeType,
166 page, column, lc ) )
167 { LLDEB(page,column); rval= -1; goto ready; }
168
169 *dr= drBox; break;
170
171 default:
172 LDEB(treeRoot->biTreeType);
173 rval= -1; goto ready;
174 }
175
176 ready:
177
178 docLayoutCleanBlockFrame( &bf );
179
180 return rval;
181 }
182
183 /************************************************************************/
184
docPlaceHeader(DocumentTree * tree,const DocumentGeometry * dgSect)185 static void docPlaceHeader( DocumentTree * tree,
186 const DocumentGeometry * dgSect )
187 {
188 tree->dtY0UsedTwips= tree->dtRoot->biTopPosition.lpPageYTwips;
189 tree->dtY1UsedTwips= tree->dtRoot->biBelowPosition.lpPageYTwips;
190
191 tree->dtY0ReservedTwips= dgSect->dgHeaderPositionTwips;
192 tree->dtY1ReservedTwips= dgSect->dgTopMarginTwips;
193
194 if ( tree->dtY1ReservedTwips < tree->dtY1UsedTwips )
195 { tree->dtY1ReservedTwips= tree->dtY1UsedTwips; }
196
197 return;
198 }
199
docPlaceFooter(DocumentTree * tree,const DocumentGeometry * dgSect)200 static void docPlaceFooter( DocumentTree * tree,
201 const DocumentGeometry * dgSect )
202 {
203 int high= tree->dtRoot->biBelowPosition.lpPageYTwips-
204 tree->dtRoot->biTopPosition.lpPageYTwips;
205
206 tree->dtY1UsedTwips=
207 dgSect->dgPageHighTwips- dgSect->dgFooterPositionTwips;
208 tree->dtY0UsedTwips= tree->dtY1UsedTwips- high;
209
210 tree->dtY0ReservedTwips=
211 dgSect->dgPageHighTwips- dgSect->dgBottomMarginTwips;
212 tree->dtY1ReservedTwips=
213 dgSect->dgPageHighTwips- dgSect->dgFooterPositionTwips;
214
215 if ( tree->dtY0ReservedTwips > tree->dtY0UsedTwips )
216 { tree->dtY0ReservedTwips= tree->dtY0UsedTwips; }
217
218 return;
219 }
220
221 /************************************************************************/
222 /* */
223 /* Do a preliminary layout of a document tree. */
224 /* */
225 /* Inside the tree, geometry is correct. Some trees are however used */
226 /* in different positions and here we just calculate the layout in */
227 /* order to know the size of the tree to use it in geometry */
228 /* calculations about the document as a whole. */
229 /* */
230 /* 1) Remove the bottom of the page master frame. This is the routine */
231 /* that calculates it for future use. */
232 /* */
233 /************************************************************************/
234
docTreePrelayout(DocumentTree * tree,const BufferItem * bodySectNode,LayoutJob * lj)235 int docTreePrelayout( DocumentTree * tree,
236 const BufferItem * bodySectNode,
237 LayoutJob * lj )
238 {
239 int rval= 0;
240 const LayoutContext * lc= &(lj->ljContext);
241 const DocumentGeometry * dgSect= &(bodySectNode->biSectDocumentGeometry);
242 LayoutJob treeLj;
243 LayoutPosition treeLp;
244
245 BlockFrame bf;
246
247 const int recursively= 0;
248
249 docLayoutInitBlockFrame( &bf );
250
251 docInvalidateTreeLayout( tree );
252
253 if ( ! tree->dtRoot )
254 { goto ready; }
255
256 docDelimitTables( tree->dtRoot, recursively );
257
258 tree->dtRoot->biSectDocumentGeometry.dgPageWideTwips=
259 dgSect->dgPageWideTwips;
260 tree->dtRoot->biSectDocumentGeometry.dgLeftMarginTwips=
261 dgSect->dgLeftMarginTwips;
262 tree->dtRoot->biSectDocumentGeometry.dgRightMarginTwips=
263 dgSect->dgRightMarginTwips;
264
265 treeLp.lpPage= tree->dtRoot->biTopPosition.lpPage;
266 treeLp.lpColumn= 0;
267 treeLp.lpPageYTwips= dgSect->dgHeaderPositionTwips;
268 treeLp.lpAtTopOfColumn= 1; /* not really */
269
270 treeLj= *lj;
271 treeLj.ljChangedRectanglePixels= (DocumentRectangle *)0;
272
273 treeLj.ljBodySectNode= bodySectNode;
274 treeLj.ljChangedNode= lj->ljChangedNode;
275
276 docBlockFrameTwips( &bf, tree->dtRoot, lc->lcDocument,
277 treeLp.lpPage, treeLp.lpColumn );
278 bf.bfContentRect.drY0= treeLp.lpPageYTwips;
279 bf.bfFlowRect.drY0= bf.bfContentRect.drY0;
280
281 /* 1 */
282 bf.bfContentRect.drY1= dgSect->dgPageHighTwips;
283 bf.bfFlowRect.drY1= bf.bfContentRect.drY1;
284
285 if ( docLayoutNodeImplementation( &treeLp, &treeLp,
286 tree->dtRoot, &bf, &treeLj ) )
287 { LDEB(1); rval= -1; goto ready; }
288
289 switch( tree->dtRoot->biTreeType )
290 {
291 case DOCinFIRST_HEADER:
292 case DOCinLEFT_HEADER:
293 case DOCinRIGHT_HEADER:
294 docPlaceHeader( tree, dgSect );
295 break;
296
297 case DOCinFIRST_FOOTER:
298 case DOCinLEFT_FOOTER:
299 case DOCinRIGHT_FOOTER:
300 docPlaceFooter( tree, dgSect );
301 break;
302
303 case DOCinFOOTNOTE:
304 case DOCinENDNOTE:
305
306 /* temporarily: will be placed later on */
307 tree->dtY0UsedTwips= tree->dtRoot->biTopPosition.lpPageYTwips;
308 tree->dtY1UsedTwips= tree->dtRoot->biBelowPosition.lpPageYTwips;
309 break;
310
311 case DOCinFTNSEP:
312 case DOCinFTNSEPC:
313 case DOCinFTNCN:
314 case DOCinAFTNSEP:
315 case DOCinAFTNSEPC:
316 case DOCinAFTNCN:
317
318 /* temporarily */
319 tree->dtY0UsedTwips= tree->dtRoot->biTopPosition.lpPageYTwips;
320 tree->dtY1UsedTwips= tree->dtRoot->biBelowPosition.lpPageYTwips;
321 break;
322
323 default:
324 LDEB(tree->dtRoot->biTreeType); rval= -1; goto ready;
325 }
326
327 ready:
328
329 docLayoutCleanBlockFrame( &bf );
330
331 return rval;
332 }
333
334 /************************************************************************/
335 /* */
336 /* Do the preliminary layout of the headers and footers of a section */
337 /* */
338 /************************************************************************/
339
docSectHeaderFooterPrelayout(BufferItem * bodySectNode,LayoutJob * lj)340 int docSectHeaderFooterPrelayout( BufferItem * bodySectNode,
341 LayoutJob * lj )
342 {
343 int hdft;
344 int redraw= 0;
345
346 for ( hdft= 0; hdft < DOC_HeaderFooterTypeCount; hdft++ )
347 {
348 DocumentTree * dtHdFt;
349 unsigned char applies;
350
351 int resY0;
352 int resY1;
353
354 dtHdFt= docSectionHeaderFooter( bodySectNode, &applies,
355 &(lj->ljContext.lcDocument->bdProperties),
356 DOC_HeaderFooterTypes[hdft] );
357 if ( ! dtHdFt )
358 { XDEB(dtHdFt); return -1; }
359
360 resY0= dtHdFt->dtY0ReservedTwips;
361 resY1= dtHdFt->dtY1ReservedTwips;
362
363 if ( ! dtHdFt->dtRoot || ! applies )
364 {
365 dtHdFt->dtY0ReservedTwips= 0;
366 dtHdFt->dtY1ReservedTwips= 0;
367 }
368 else{
369 if ( docTreePrelayout( dtHdFt, bodySectNode, lj ) )
370 { LDEB(1); return -1; }
371 }
372
373 if ( lj->ljChangedRectanglePixels &&
374 ( dtHdFt->dtY0ReservedTwips != resY0 ||
375 dtHdFt->dtY1ReservedTwips != resY1 ) )
376 { redraw++; }
377 }
378
379 if ( redraw )
380 {
381 DocumentRectangle drPixels;
382
383 docGetPixelRectangleForPages( &drPixels, &(lj->ljContext),
384 bodySectNode->biTopPosition.lpPage,
385 bodySectNode->biBelowPosition.lpPage );
386
387 geoUnionRectangle( lj->ljChangedRectanglePixels,
388 lj->ljChangedRectanglePixels, &drPixels );
389 }
390
391 return 0;
392 }
393
394 /************************************************************************/
395 /* */
396 /* Reset page dependent layout administration of headers/footers etc */
397 /* fo force a subsequent recalculation. */
398 /* */
399 /************************************************************************/
400
docResetExternalTreeLayout(BufferDocument * bd)401 void docResetExternalTreeLayout( BufferDocument * bd )
402 {
403 int i;
404
405 docInvalidateTreeLayout( &(bd->bdEiFtnsep) );
406 docInvalidateTreeLayout( &(bd->bdEiFtnsepc) );
407 docInvalidateTreeLayout( &(bd->bdEiFtncn) );
408
409 docInvalidateTreeLayout( &(bd->bdEiAftnsep) );
410 docInvalidateTreeLayout( &(bd->bdEiAftnsepc) );
411 docInvalidateTreeLayout( &(bd->bdEiAftncn) );
412
413 for ( i= 0; i < bd->bdBody.dtRoot->biChildCount; i++ )
414 {
415 BufferItem * bodySectNode= bd->bdBody.dtRoot->biChildren[i];
416
417 docInvalidateSectHeaderFooterLayout( bodySectNode );
418 }
419
420 return;
421 }
422
423 /************************************************************************/
424 /* */
425 /* Verify that the root of a selection is formatted for the current */
426 /* page, if not format it. */
427 /* */
428 /************************************************************************/
429
docGetY0ForSelectedNoteSeparator(int * pY0Twips,BufferItem ** pBodySectNode,const LayoutContext * lc,const DocumentTree * selTree,int noteItKind,int sepItKind)430 static int docGetY0ForSelectedNoteSeparator(
431 int * pY0Twips,
432 BufferItem ** pBodySectNode,
433 const LayoutContext * lc,
434 const DocumentTree * selTree,
435 int noteItKind,
436 int sepItKind )
437 {
438 struct DocumentNote * dnFirstNote;
439 DocumentTree * eiBody;
440 DocumentTree * eiNoteSep;
441 int y0Twips;
442
443 DocumentRectangle drExtern;
444
445 DocumentField * dfNote;
446 BufferItem * bodySectNode;
447
448 dfNote= docGetFirstNoteInColumn( &dnFirstNote, lc->lcDocument,
449 selTree->dtPageSelectedUpon,
450 selTree->dtColumnSelectedIn,
451 noteItKind );
452 if ( ! dfNote )
453 {
454 LLDEB(selTree->dtPageSelectedUpon,selTree->dtColumnSelectedIn);
455 return -1;
456 }
457
458 if ( docGetRootOfSelectionScope( &eiBody, &bodySectNode, lc->lcDocument,
459 &(dfNote->dfSelectionScope) ) )
460 { LDEB(1); return -1; }
461
462 if ( docNoteSeparatorRectangle( &drExtern, &eiNoteSep,
463 &y0Twips, dnFirstNote, sepItKind, lc ) )
464 { LDEB(1); return -1; }
465
466 *pY0Twips= y0Twips;
467 *pBodySectNode= bodySectNode;
468 return 0;
469 }
470
docCheckPageOfSelectedTree(int * pChanged,BufferItem ** pBodySectNode,DocumentRectangle * drChanged,DocumentTree * selTree,const LayoutContext * lc,INIT_LAYOUT_EXTERNAL initLayoutExternal)471 int docCheckPageOfSelectedTree( int * pChanged,
472 BufferItem ** pBodySectNode,
473 DocumentRectangle * drChanged,
474 DocumentTree * selTree,
475 const LayoutContext * lc,
476 INIT_LAYOUT_EXTERNAL initLayoutExternal )
477 {
478 int y0Twips;
479 BufferItem * selRootBodySectNode= (BufferItem *)0;
480 const SelectionScope * selRootScope;
481 const int adjustDocument= 0;
482
483 if ( ! selTree->dtRoot )
484 { XDEB(selTree->dtRoot); return -1; }
485
486 selRootScope= &(selTree->dtRoot->biSectSelectionScope);
487
488 switch( selTree->dtRoot->biTreeType )
489 {
490 case DOCinBODY:
491 LDEB(selTree->dtRoot->biTreeType);
492 return -1;
493
494 case DOCinFIRST_HEADER:
495 case DOCinLEFT_HEADER:
496 case DOCinRIGHT_HEADER:
497
498 case DOCinFIRST_FOOTER:
499 case DOCinLEFT_FOOTER:
500 case DOCinRIGHT_FOOTER:
501
502 selRootBodySectNode= docGetBodySectNodeOfScope( selRootScope,
503 lc->lcDocument );
504
505 y0Twips= selTree->dtY0UsedTwips;
506 break;
507
508 case DOCinFOOTNOTE:
509 case DOCinENDNOTE:
510
511 selRootBodySectNode= docGetBodySectNodeOfScope( selRootScope,
512 lc->lcDocument );
513
514 *pBodySectNode= selRootBodySectNode;
515 *pChanged= 0;
516 return 0;
517
518 case DOCinFTNSEP:
519
520 if ( selTree->dtPageSelectedUpon < 0 )
521 { LDEB(selTree->dtPageSelectedUpon); return -1; }
522
523 if ( docGetY0ForSelectedNoteSeparator( &y0Twips,
524 &selRootBodySectNode,
525 lc, selTree,
526 DOCinFOOTNOTE, DOCinFTNSEP ) )
527 { LDEB(1); return -1; }
528
529 break;
530
531 case DOCinFTNSEPC:
532 case DOCinFTNCN:
533 LDEB(selTree->dtRoot->biTreeType);
534 return -1;
535
536 case DOCinAFTNSEP:
537
538 if ( selTree->dtPageSelectedUpon < 0 )
539 { LDEB(selTree->dtPageSelectedUpon); return -1; }
540
541 if ( docGetY0ForSelectedNoteSeparator( &y0Twips,
542 &selRootBodySectNode,
543 lc, selTree,
544 DOCinENDNOTE, DOCinAFTNSEP ) )
545 { LDEB(1); return -1; }
546
547 break;
548
549 case DOCinAFTNSEPC:
550 case DOCinAFTNCN:
551 SDEB(docTreeTypeStr(selTree->dtRoot->biTreeType));
552 return -1;
553
554 default:
555 LDEB(selTree->dtRoot->biTreeType);
556 return -1;
557 }
558
559 if ( selTree->dtPageSelectedUpon < 0 )
560 { LSDEB(selTree->dtPageSelectedUpon,docTreeTypeStr(selTree->dtRoot->biTreeType)); return -1; }
561
562 if ( selTree->dtPageFormattedFor == selTree->dtPageSelectedUpon &&
563 selTree->dtColumnFormattedFor == selTree->dtColumnSelectedIn )
564 {
565 *pBodySectNode= selRootBodySectNode;
566 *pChanged= 0;
567 return 0;
568 }
569
570 /* We do not expect the tree to change height here */
571 if ( docLayoutDocumentTree( selTree, drChanged,
572 selTree->dtPageSelectedUpon,
573 selTree->dtColumnSelectedIn,
574 y0Twips, selRootBodySectNode, lc,
575 initLayoutExternal, adjustDocument ) )
576 { LDEB(selTree->dtPageSelectedUpon); return -1; }
577
578 *pBodySectNode= selRootBodySectNode;
579 *pChanged= 1; return 0;
580 }
581
582 /************************************************************************/
583 /* */
584 /* Calculate the layout of a document tree such as a page header or */
585 /* footer. NOT called for the document body. */
586 /* */
587 /************************************************************************/
588
docLayoutDocumentTree(DocumentTree * tree,DocumentRectangle * drChanged,int page,int column,int y0Twips,const BufferItem * bodySectNode,const LayoutContext * lc,INIT_LAYOUT_EXTERNAL initLayoutExternal,int adjustDocument)589 int docLayoutDocumentTree( DocumentTree * tree,
590 DocumentRectangle * drChanged,
591 int page,
592 int column,
593 int y0Twips,
594 const BufferItem * bodySectNode,
595 const LayoutContext * lc,
596 INIT_LAYOUT_EXTERNAL initLayoutExternal,
597 int adjustDocument )
598 {
599 int rval= 0;
600
601 RecalculateFields rf;
602 LayoutJob lj;
603 BlockFrame bf;
604
605 LayoutPosition lpHere;
606
607 int oldY1= tree->dtY1UsedTwips;
608
609 docLayoutInitBlockFrame( &bf );
610 docInitRecalculateFields( &rf );
611 docInitLayoutJob( &lj );
612
613 if ( page == tree->dtPageFormattedFor &&
614 column == tree->dtColumnFormattedFor )
615 { goto ready; }
616
617 rf.rfDocument= lc->lcDocument;
618 rf.rfCloseObject= lc->lcCloseObject;
619 rf.rfUpdateFlags=
620 FIELDdoDOC_FORMATTED|FIELDdoDOC_COMPLETE|FIELDdoPAGE_NUMBER;
621 rf.rfFieldsUpdated= 0;
622 rf.rfBodySectNode= bodySectNode;
623
624 if ( docRecalculateTextLevelFieldsInDocumentTree( &rf, tree,
625 bodySectNode, page ) )
626 { LDEB(page); return -1; }
627
628 lpHere.lpPage= page;
629 lpHere.lpColumn= column;
630 lpHere.lpPageYTwips= y0Twips;
631 lpHere.lpAtTopOfColumn= 1; /* not really */
632
633 lj.ljBodySectNode= bodySectNode;
634
635 lj.ljChangedRectanglePixels= drChanged;
636 lj.ljContext= *lc;
637 /*
638 lj.ljChangedNode= lc->lcDocument->bdBody.dtRoot;
639 */
640 lj.ljChangedNode= tree->dtRoot;
641
642 if ( initLayoutExternal &&
643 (*initLayoutExternal)( &lj, tree, page, column ) )
644 { LDEB(1); rval= -1; goto ready; }
645
646 if ( docLayoutGetInitialFrame( &bf, &lj, &lpHere, tree->dtRoot ) )
647 { LDEB(1); return -1; }
648
649 docLayoutAdjustFrame( &bf, tree->dtRoot );
650
651 if ( docLayoutNodeImplementation( &lpHere, &lpHere,
652 tree->dtRoot, &bf, &lj ) )
653 { LDEB(1); rval= -1; goto ready; }
654
655 tree->dtPageFormattedFor= page;
656 tree->dtColumnFormattedFor= column;
657 tree->dtY0UsedTwips= y0Twips;
658 tree->dtY1UsedTwips= lpHere.lpPageYTwips;
659
660 if ( adjustDocument &&
661 tree->dtY0UsedTwips != oldY1 )
662 {
663 const DocumentGeometry * dgSect= &(bodySectNode->biSectDocumentGeometry);
664 if ( docIsHeaderType( tree->dtRoot->biTreeType ) )
665 {
666 docPlaceHeader( tree, dgSect );
667 }
668
669 if ( docIsFooterType( tree->dtRoot->biTreeType ) )
670 {
671 docPlaceFooter( tree, dgSect );
672 }
673
674 if ( docAdjustLayoutToChangedTree( &lpHere, tree->dtRoot, &lj ) )
675 { LDEB(1); return -1; }
676 }
677
678 ready:
679
680 docCleanLayoutJob( &lj );
681
682 return rval;
683 }
684
685