1 /************************************************************************/
2 /* */
3 /* Paragraph Layout related administration. */
4 /* */
5 /************************************************************************/
6
7 # include "docLayoutConfig.h"
8
9 # include <stddef.h>
10 # include <stdlib.h>
11
12 # include <psFontMetrics.h>
13 # include <docPageGrid.h>
14 # include "docLayout.h"
15 # include "docLayoutObject.h"
16 # include "docParagraphLayout.h"
17 # include "docRowLayout.h"
18 # include <docTreeType.h>
19 # include <docTreeNode.h>
20 # include <docNodeTree.h>
21 # include <docDebug.h>
22 # include <docTextParticule.h>
23 # include <docPropertiesAdmin.h>
24
25 # include <appDebugon.h>
26
27 /************************************************************************/
28
docGetParaTopBorder(BorderProperties * bpTop,int * pNrAbove,int * pFillBefore,const BufferDocument * bd,const BufferItem * paraNode,const BufferItem * cellNode)29 static int docGetParaTopBorder( BorderProperties * bpTop,
30 int * pNrAbove,
31 int * pFillBefore,
32 const BufferDocument * bd,
33 const BufferItem * paraNode,
34 const BufferItem * cellNode )
35 {
36 int rval= 0;
37 const BufferItem * prevNode= (const BufferItem *)0;
38
39 if ( paraNode->biNumberInParent > 0 )
40 { prevNode= cellNode->biChildren[paraNode->biNumberInParent- 1]; }
41
42 /* 5 */
43 if ( docBorderNumberIsBorder( bd, paraNode->biParaTopBorderNumber ) )
44 {
45 if ( ! prevNode ||
46 prevNode->biParaFrameNumber != paraNode->biParaFrameNumber ||
47 prevNode->biParaTopBorderNumber !=
48 paraNode->biParaTopBorderNumber )
49 {
50 docGetBorderPropertiesByNumber( bpTop, bd,
51 paraNode->biParaTopBorderNumber );
52
53 *pNrAbove= paraNode->biParaTopBorderNumber;
54 rval= 1;
55 }
56
57 if ( prevNode &&
58 prevNode->biParaFrameNumber ==
59 paraNode->biParaFrameNumber &&
60 prevNode->biParaBottomBorderNumber ==
61 paraNode->biParaBottomBorderNumber )
62 { *pFillBefore= 1; }
63 }
64
65 if ( prevNode &&
66 docShadingNumberIsShading( bd, paraNode->biParaShadingNumber ) &&
67 docShadingNumberIsShading( bd, prevNode->biParaShadingNumber ) )
68 { *pFillBefore= 1; }
69
70 return rval;
71 }
72
docGetParaBottomBorder(BorderProperties * bpBottom,int * pNrBelow,int * pFillAfter,const BufferDocument * bd,const BufferItem * paraNode,const BufferItem * cellNode)73 static int docGetParaBottomBorder( BorderProperties * bpBottom,
74 int * pNrBelow,
75 int * pFillAfter,
76 const BufferDocument * bd,
77 const BufferItem * paraNode,
78 const BufferItem * cellNode )
79 {
80 int rval= 0;
81 const BufferItem * nextNode= (const BufferItem *)0;
82
83 if ( paraNode->biNumberInParent < cellNode->biChildCount- 1 )
84 { nextNode= cellNode->biChildren[paraNode->biNumberInParent+ 1]; }
85
86 if ( docBorderNumberIsBorder( bd, paraNode->biParaBottomBorderNumber ) )
87 {
88 if ( ! nextNode ||
89 nextNode->biParaFrameNumber != paraNode->biParaFrameNumber ||
90 nextNode->biParaBottomBorderNumber !=
91 paraNode->biParaBottomBorderNumber )
92 {
93 docGetBorderPropertiesByNumber( bpBottom, bd,
94 paraNode->biParaBottomBorderNumber );
95
96 *pNrBelow= paraNode->biParaBottomBorderNumber;
97 rval= 1;
98 }
99
100 if ( nextNode &&
101 nextNode->biParaFrameNumber == paraNode->biParaFrameNumber &&
102 nextNode->biParaBottomBorderNumber ==
103 paraNode->biParaBottomBorderNumber )
104 { *pFillAfter= 1; }
105 }
106
107 if ( nextNode &&
108 docShadingNumberIsShading( bd, paraNode->biParaShadingNumber ) &&
109 docShadingNumberIsShading( bd, nextNode->biParaShadingNumber ) )
110 { *pFillAfter= 1; }
111
112 return rval;
113 }
114
115 /************************************************************************/
116 /* */
117 /* Calculate the height of a series of lines in a paragraph. */
118 /* */
119 /* 1) The first paragraph in a cell must accomodate space for the */
120 /* top border of the cells of the row and the cell padding. */
121 /* 2) Allocate space for the fattest top border in the row. */
122 /* 3) Allocate space for the row padding. */
123 /* 4) Allocate space for the cell padding. */
124 /* 5) Allocate space for the paragraph top border. */
125 /* */
126 /************************************************************************/
127
docLayoutCalculateParaTopInset(const BufferDocument * bd,BufferItem * paraNode)128 void docLayoutCalculateParaTopInset(
129 const BufferDocument * bd,
130 BufferItem * paraNode )
131 {
132 int topInset= 0;
133 int nrAbove= -1;
134 BorderProperties bpTop;
135 const BufferItem * cellNode= paraNode->biParent;
136
137 int cellMargin= 0;
138 int fillBefore= 0;
139
140 topInset= paraNode->biParaSpaceBeforeTwips;
141
142 /* 1 */
143 if ( paraNode->biParaTableNesting > 0 &&
144 paraNode->biNumberInParent == 0 )
145 {
146 const BufferItem * rowNode= cellNode->biParent;
147
148 const RowProperties * rp= &(rowNode->biRowProperties);
149 const CellProperties * cp= rp->rpCells+ cellNode->biNumberInParent;
150
151 if ( ! docIsRowNode( rowNode ) )
152 { LDEB(1); cp= (const CellProperties *)0; }
153
154 /* 2 */
155 cellMargin += rowNode->biRowTopInset;
156
157 /* 3 */
158 switch( rp->rpTopCellPaddingUnit )
159 {
160 case TRautoNONE:
161 break;
162
163 case TRautoTWIPS:
164 cellMargin= rp->rpTopCellPadding;
165 break;
166
167 default:
168 LDEB(rp->rpTopCellPaddingUnit);
169 break;
170 }
171
172 /* 4 */
173 if ( cp ) switch( cp->cpTopPaddingUnit )
174 {
175 case TRautoNONE:
176 break;
177
178 case TRautoTWIPS:
179 cellMargin= cp->cpTopPadding;
180 break;
181
182 default:
183 LDEB(cp->cpTopPaddingUnit);
184 break;
185 }
186 }
187
188 if ( paraNode->biParaTableNesting == 0 &&
189 paraNode->biNumberInParent == 0 &&
190 cellNode->biNumberInParent == 0 )
191 {
192 const BufferItem * rowNode= cellNode->biParent;
193
194 topInset += rowNode->biRowTopInset;
195 }
196
197 /* 5 */
198 if ( docGetParaTopBorder( &bpTop, &nrAbove, &fillBefore,
199 bd, paraNode, cellNode ) )
200 { docAddBorderToInset( &topInset, &bpTop ); }
201
202 paraNode->biParaTopInset= cellMargin+ topInset;
203 paraNode->biParaBorderNrAbove= nrAbove;
204
205 return;
206 }
207
docLayoutCalculateParaBottomInset(const BufferDocument * bd,BufferItem * paraNode)208 void docLayoutCalculateParaBottomInset(
209 const BufferDocument * bd,
210 BufferItem * paraNode )
211 {
212 int bottomInset= 0;
213 int nrBelow= -1;
214 BorderProperties bpBottom;
215 const BufferItem * cellNode= paraNode->biParent;
216 const BufferItem * rowNode= cellNode->biParent;
217
218 int cellMargin= 0;
219 int fillAfter= 0;
220
221 if ( paraNode->biParaTableNesting > 0 &&
222 cellNode->biNumberInParent <
223 rowNode->biRowProperties.rpCellCount &&
224 paraNode->biNumberInParent == cellNode->biChildCount- 1 )
225 {
226 const RowProperties * rp= &(rowNode->biRowProperties);
227 const CellProperties * cp= rp->rpCells+ cellNode->biNumberInParent;
228
229 switch( rp->rpBottomCellPaddingUnit )
230 {
231 case TRautoNONE:
232 break;
233
234 case TRautoTWIPS:
235 cellMargin= rp->rpBottomCellPadding;
236 break;
237
238 default:
239 LDEB(rp->rpBottomCellPaddingUnit);
240 break;
241 }
242
243 switch( cp->cpBottomPaddingUnit )
244 {
245 case TRautoNONE:
246 break;
247
248 case TRautoTWIPS:
249 cellMargin= cp->cpBottomPadding;
250 break;
251
252 default:
253 LDEB(cp->cpBottomPaddingUnit);
254 break;
255 }
256 }
257
258 if ( docGetParaBottomBorder( &bpBottom, &nrBelow, &fillAfter,
259 bd, paraNode, cellNode ) )
260 { docAddBorderToInset( &bottomInset, &bpBottom ); }
261
262 bottomInset += paraNode->biParaSpaceAfterTwips;
263
264 paraNode->biParaBottomInset= bottomInset+ cellMargin;
265 paraNode->biParaBorderNrBelow= nrBelow;
266
267 return;
268 }
269
270 /************************************************************************/
271 /* */
272 /* Determine the 'majority' font of a paragraph, and get the font */
273 /* extents for that font. */
274 /* */
275 /* 1) Note that subscript/superscript is NOT taken into account. */
276 /* */
277 /************************************************************************/
278
docLayoutParagraphLineExtents(int * pFontSizeTwips,const LayoutContext * lc,BufferItem * paraNode)279 int docLayoutParagraphLineExtents(
280 int * pFontSizeTwips,
281 const LayoutContext * lc,
282 BufferItem * paraNode )
283 {
284 BufferDocument * bd= lc->lcDocument;
285 const TextParticule * tp= paraNode->biParaParticules;
286
287 int sizeHalfPoints;
288 int y0= 0;
289 int y1= 0;
290
291 int box;
292 int part;
293
294 static int * counts;
295 int * fresh;
296
297 int found;
298 int foundCount;
299
300 DocumentPropertyLists * dpl= bd->bdPropertyLists;
301 const NumberedPropertiesList * tal= &(dpl->dplTextAttributeList);
302 int count= tal->nplPagedList.plItemCount;
303
304 fresh= (int *)realloc( counts, count* sizeof(int) );
305 if ( ! fresh )
306 { LXDEB(count,fresh); return -1; }
307 counts= fresh;
308
309 for ( box= 0; box < count; box++ )
310 { counts[box]= 0; }
311
312 for ( part= 0; part < paraNode->biParaParticuleCount; tp++, part++ )
313 {
314 if ( tp->tpKind != DOCkindSPAN &&
315 tp->tpKind != DOCkindTAB &&
316 tp->tpKind != DOCkindOBJECT )
317 { continue; }
318
319 if ( tp->tpTextAttrNr < 0 ||
320 tp->tpTextAttrNr >= count )
321 {
322 LLLDEB(part,tp->tpTextAttrNr,count);
323 docListNode(0,paraNode,0);
324 continue;
325 }
326
327 counts[tp->tpTextAttrNr] += tp->tpStrlen+ 1;
328 }
329
330 found= -1;
331 foundCount= 0;
332 for ( box= 0; box < count; box++ )
333 {
334 if ( counts[box] > foundCount )
335 { found= box; foundCount= counts[box]; }
336 }
337
338 if ( found >= 0 )
339 {
340 DocumentProperties * dp= &(bd->bdProperties);
341 DocumentFontList * dfl= dp->dpFontList;
342
343 TextAttribute ta;
344 const AfmFontInfo * afi;
345 const IndexSet * unicodesWanted;
346
347 const int vswap= 1;
348 DocumentRectangle drFontBBox;
349 DocumentRectangle drFontAscDesc;
350 int fontHigh;
351 int sizeTwips;
352
353 docGetTextAttributeByNumber( &ta, bd, found );
354
355 afi= (*lc->lcGetFontForAttribute)( &unicodesWanted,
356 &ta, dfl, lc->lcPostScriptFontList );
357 if ( ! afi )
358 { XDEB(afi); return -1; }
359
360 sizeHalfPoints= ta.taFontSizeHalfPoints;
361 sizeTwips= 10* sizeHalfPoints;
362
363 psFontBBox( &drFontBBox, &drFontAscDesc, sizeTwips, vswap, afi );
364
365 y0= drFontAscDesc.drY0;
366 y1= drFontAscDesc.drY1;
367
368 /*LINEDISTANCE: scale the position of the baseline based on the bbox */
369 fontHigh= drFontBBox.drY1- drFontBBox.drY0;
370 if ( fontHigh < 2 )
371 { LLDEB(ta.taFontSizeHalfPoints,fontHigh); fontHigh= 2; }
372 y0= ( drFontBBox.drY0* sizeTwips )/ fontHigh;
373 y1= ( drFontBBox.drY1* sizeTwips )/ fontHigh;
374 }
375 else{
376 /* LDEB(found); */
377 sizeHalfPoints= 24;
378 y0= -190;
379 y1= 50;
380 }
381
382 paraNode->biParaMajorityFontSize= sizeHalfPoints;
383 paraNode->biParaMajorityFontAscY0= y0;
384 paraNode->biParaMajorityFontDescY1= y1;
385
386 *pFontSizeTwips= 10* sizeHalfPoints;
387 return 0;
388 }
389
390 /************************************************************************/
391 /* */
392 /* Invalidate the layout of all paragraphs in the modified range. */
393 /* */
394 /************************************************************************/
395
docInvalidateParagraphLayout(BufferItem * paraNode)396 void docInvalidateParagraphLayout( BufferItem * paraNode )
397 {
398 paraNode->biParaLineCount= 0;
399
400 paraNode->biParaMajorityFontAscY0= 0;
401 paraNode->biParaMajorityFontDescY1= 0;
402 paraNode->biParaMajorityFontSize= 0;
403 }
404
docInvalidateNodeLayout(BufferItem * node)405 void docInvalidateNodeLayout( BufferItem * node )
406 {
407 if ( node->biLevel == DOClevPARA )
408 { docInvalidateParagraphLayout( node ); }
409 else{
410 int c;
411
412 for ( c= 0; c < node->biChildCount; c++ )
413 { docInvalidateNodeLayout( node->biChildren[c] ); }
414 }
415 }
416
417 /************************************************************************/
418 /* */
419 /* Calculate the top inset after a table. */
420 /* */
421 /* This routine is also used to calculate the inset that is used to */
422 /* accomodate space for the bottom border of the previous row. This */
423 /* inset is not used in real rows, but only in the immediate successor */
424 /* of a real row. */
425 /* */
426 /* 1) Reserve space for the bottom border of all cells. */
427 /* */
428 /************************************************************************/
429
docLayoutCalculateAfterRowTopInset(BufferItem * belowBi,const BufferDocument * bd)430 void docLayoutCalculateAfterRowTopInset( BufferItem * belowBi,
431 const BufferDocument * bd )
432 {
433 int col;
434 const BufferItem * rowNode;
435 const CellProperties * cp;
436
437 if ( belowBi->biNumberInParent == 0 )
438 { return; }
439
440 rowNode= belowBi->biParent->biChildren[belowBi->biNumberInParent- 1];
441 if ( ! docIsRowNode( rowNode ) )
442 { return; }
443
444 belowBi->biRowTopInset= 0;
445
446 /* 1 */
447 cp= rowNode->biRowCells;
448 for ( col= 0; col < rowNode->biChildCount; cp++, col++ )
449 {
450 const int atRowBottom= 1;
451 int useBelow= 0;
452 BorderProperties bpBottom;
453 int bottomNr;
454
455 if ( CELL_MERGED( cp ) )
456 { continue; }
457
458 docGetCellBottomBorder( &bpBottom, &bottomNr, &useBelow, bd, rowNode,
459 col, atRowBottom );
460
461 {
462 int rti= belowBi->biRowTopInset;
463 docStretchInsetForBorder( &rti, &bpBottom );
464 belowBi->biRowTopInset= rti;
465 }
466
467 }
468
469 return;
470 }
471
472 /************************************************************************/
473 /* */
474 /* Determine paragraph border and shading. */
475 /* */
476 /* Experimentation with MS-Word revealed that MS-Word includes the */
477 /* space before/after in the borders and shading between two */
478 /* paragraphs if either: */
479 /* a) Both have the same border. */
480 /* b) Both have a shading. */
481 /* */
482 /* 1) To avoid a trellis effect, we must fill the space above the, */
483 /* paragraph if the paragraph is part of a series of contiguous */
484 /* shaded paragraphs without a border between them. */
485 /* 2) To avoid a trellis effect, we must fill the space below the, */
486 /* paragraph if the paragraph is part of a series of contiguous */
487 /* shaded paragraphs without a border between them. */
488 /* */
489 /************************************************************************/
490
docGetParaOrnaments(BlockOrnaments * ornaments,DocumentRectangle * drOutside,DocumentRectangle * drInside,const DocumentRectangle * drParaIn,const BufferDocument * bd,const BufferItem * paraNode,int atParaTop,int atParaBottom)491 void docGetParaOrnaments(
492 BlockOrnaments * ornaments,
493 DocumentRectangle * drOutside,
494 DocumentRectangle * drInside,
495 const DocumentRectangle * drParaIn,
496 const BufferDocument * bd,
497 const BufferItem * paraNode,
498 int atParaTop,
499 int atParaBottom )
500 {
501 int thick;
502 int space;
503
504 int nrAbove= -1;
505 BorderProperties bpTop;
506 int nrBelow= -1;
507 BorderProperties bpBottom;
508
509 DocumentRectangle drPara= *drParaIn;
510
511 if ( atParaTop )
512 {
513 int fillBefore= 0;
514
515 docGetParaTopBorder( &bpTop, &nrAbove, &fillBefore,
516 bd, paraNode, paraNode->biParent );
517
518 /* 1 */
519 if ( fillBefore )
520 { drPara.drY0 -= paraNode->biParaSpaceBeforeTwips; }
521 }
522
523 if ( atParaBottom )
524 {
525 int fillAfter= 0;
526
527 docGetParaBottomBorder( &bpBottom, &nrBelow, &fillAfter,
528 bd, paraNode, paraNode->biParent );
529
530 /* 2 */
531 if ( fillAfter )
532 { drPara.drY1 += paraNode->biParaSpaceAfterTwips; }
533 }
534
535 *drOutside= drPara;
536 *drInside= drPara;
537
538 if ( paraNode->biParaShadingNumber != 0 )
539 {
540 docGetItemShadingByNumber( &(ornaments->boShading), bd,
541 paraNode->biParaShadingNumber );
542
543 PROPmaskADD( &(ornaments->boPropMask), ORNdrawSHADE );
544 }
545
546 docGetBorderPropertiesByNumber( &(ornaments->boLeftBorder), bd,
547 paraNode->biParaLeftBorderNumber );
548 docGetBorderPropertiesByNumber( &(ornaments->boRightBorder), bd,
549 paraNode->biParaRightBorderNumber );
550
551 if ( atParaTop && nrAbove >= 0 )
552 {
553 ornaments->boTopBorder= bpTop;
554 ornaments->boTopBorderNumber= nrAbove;
555
556 PROPmaskADD( &(ornaments->boPropMask), ORNdrawTOP_BORDER );
557
558 thick= docBorderThick( &space, &(ornaments->boTopBorder) );
559 /* No! The paragraph above covers the lower one like the
560 * tiles on a roof.
561 drOutside->drY0= drPara->drY0- space- thick;
562 drInside->drY0= drPara->drY0- space;
563 */
564 drOutside->drY0= drPara.drY0+ space;
565 drInside->drY0= drPara.drY0+ space+ thick;
566 }
567
568 if ( atParaBottom && nrBelow >= 0 )
569 {
570 ornaments->boBottomBorder= bpBottom;
571 ornaments->boBottomBorderNumber= nrBelow;
572
573 PROPmaskADD( &(ornaments->boPropMask), ORNdrawBOTTOM_BORDER );
574
575 thick= docBorderThick( &space, &(ornaments->boBottomBorder) );
576 drInside->drY1= drPara.drY1+ space;
577 drOutside->drY1= drPara.drY1+ space+ thick;
578 }
579
580 if ( paraNode->biParaLeftBorderNumber != 0 )
581 {
582 docGetBorderPropertiesByNumber( &(ornaments->boLeftBorder), bd,
583 paraNode->biParaLeftBorderNumber );
584 ornaments->boLeftBorderNumber= paraNode->biParaLeftBorderNumber;
585
586 PROPmaskADD( &(ornaments->boPropMask), ORNdrawLEFT_BORDER );
587
588 thick= docBorderThick( &space, &(ornaments->boLeftBorder) );
589 drInside->drX0= drPara.drX0- space;
590 drOutside->drX0= drPara.drX0- space- thick;
591 }
592
593 if ( paraNode->biParaRightBorderNumber != 0 )
594 {
595 docGetBorderPropertiesByNumber( &(ornaments->boRightBorder), bd,
596 paraNode->biParaRightBorderNumber );
597 ornaments->boRightBorderNumber= paraNode->biParaRightBorderNumber;
598
599 PROPmaskADD( &(ornaments->boPropMask), ORNdrawRIGHT_BORDER );
600
601 thick= docBorderThick( &space, &(ornaments->boRightBorder) );
602 drInside->drX1= drPara.drX1+ space;
603 drOutside->drX1= drPara.drX1+ space+ thick;
604 }
605
606 return;
607 }
608
609 /************************************************************************/
610 /* */
611 /* Initialisation for paragraph layout. */
612 /* */
613 /* 1) Scale objects if necessary. If a scale was chenged, cause the */
614 /* lines in the paragraph to be reformatted. There is no need to */
615 /* completely invalidate the layout: Font related information is */
616 /* unaffected. */
617 /* 2) Calculate global line extent properties if necessary. */
618 /* */
619 /************************************************************************/
620
docStartParagraphLayout(const ParagraphFrame * pf,const BlockFrame * bf,BufferItem * paraNode,const LayoutContext * lc)621 static int docStartParagraphLayout(
622 const ParagraphFrame * pf,
623 const BlockFrame * bf,
624 BufferItem * paraNode,
625 const LayoutContext * lc )
626 {
627 int part;
628 const TextParticule * tp;
629 int fontSize= 0;
630 int pageHigh;
631
632 pageHigh= bf->bfPageGeometry.dgPageHighTwips-
633 bf->bfPageGeometry.dgTopMarginTwips-
634 bf->bfPageGeometry.dgBottomMarginTwips;
635
636 /* 1 */
637 tp= paraNode->biParaParticules;
638 for ( part= 0; part < paraNode->biParaParticuleCount; tp++, part++ )
639 {
640 InsertedObject * io;
641 int fixed= 0;
642 int changed= 0;
643
644 if ( tp->tpKind != DOCkindOBJECT )
645 { continue; }
646
647 io= docGetObject( lc->lcDocument, tp->tpObjectNumber );
648 if ( ! io )
649 { LPDEB(tp->tpObjectNumber,io); continue; }
650
651 if ( docCheckObjectLayout( &fixed, io ) )
652 { LDEB(part); continue; }
653
654 docLayoutScaleObjectToFitParagraphFrame( &changed,
655 io, pageHigh, &(pf->pfParaContentRect) );
656
657 if ( fixed || changed )
658 {
659 if ( lc->lcCloseObject )
660 { (*lc->lcCloseObject)( lc->lcDocument, tp ); }
661
662 paraNode->biParaLineCount= 0;
663 }
664 }
665
666 /* 2 */
667 if ( paraNode->biParaMajorityFontSize == 0 &&
668 docLayoutParagraphLineExtents( &fontSize, lc, paraNode ) )
669 { LDEB(1); return -1; }
670
671 docLayoutCalculateParaTopInset( lc->lcDocument, paraNode );
672 docLayoutCalculateParaBottomInset( lc->lcDocument, paraNode );
673
674 return 0;
675 }
676
677 /************************************************************************/
678 /* */
679 /* Initialize the formatting of a paragraph by determining its frame */
680 /* */
681 /************************************************************************/
682
docLayoutStartParagraph(const LayoutJob * lj,int * pStopCode,BufferItem * paraNode,const BlockFrame * bf,ParagraphLayoutPosition * plp)683 int docLayoutStartParagraph( const LayoutJob * lj,
684 int * pStopCode,
685 BufferItem * paraNode,
686 const BlockFrame * bf,
687 ParagraphLayoutPosition * plp )
688 {
689 const LayoutContext * lc= &(lj->ljContext);
690 const BufferItem * sectBi= paraNode;
691
692 sectBi= docGetSectNode( paraNode );
693 if ( ! sectBi )
694 { XDEB(sectBi); return -1; }
695
696 # if 0
697 /**
698 * MS-Word does not do this
699 */
700 if ( paraNode->biParaListOverride > 0 &&
701 docAdaptParagraphToListLevel( &indentChanged, paraNode, bd ) )
702 { LDEB(1); }
703 # endif
704
705 /* 1 */
706 if ( paraNode->biTreeType == DOCinBODY &&
707 paraNode->biParaTableNesting == 0 &&
708 paraNode->biParaBreakKind != DOCibkNONE &&
709 ! plp->plpPos.lpAtTopOfColumn )
710 {
711 switch( paraNode->biParaBreakKind )
712 {
713 case DOCibkCOL:
714 *pStopCode= FORMATstopCOLUMN_BREAK;
715 break;
716 case DOCibkPAGE:
717 *pStopCode= FORMATstopPAGE_BREAK;
718 break;
719
720 default:
721 LDEB(paraNode->biParaBreakKind); return -1;
722 }
723
724 return 0;
725 }
726
727 docParagraphFrameTwips( &(plp->plpParagraphFrame), bf, paraNode );
728
729 if ( docStartParagraphLayout( &(plp->plpParagraphFrame),
730 bf, paraNode, lc ) )
731 { LDEB(1); return -1; }
732
733 if ( lj->ljStartScreenParagraph &&
734 (*lj->ljStartScreenParagraph)( paraNode,
735 &(plp->plpParagraphFrame), lc ) )
736 { LDEB(1); return -1; }
737
738 *pStopCode= FORMATstopREADY;
739 return 0;
740 }
741
742