1 /************************************************************************/
2 /* */
3 /* Layout of a document. */
4 /* */
5 /************************************************************************/
6
7 # include "docLayoutConfig.h"
8
9 # include <stddef.h>
10
11 # include <docBuf.h>
12 # include "docLayout.h"
13 # include <docPageGrid.h>
14 # include <docTreeType.h>
15 # include <docTreeNode.h>
16 # include <docNodeTree.h>
17
18 # include <appDebugon.h>
19
docLayoutBlockFrame(BlockFrame * bf,BufferItem * node,const LayoutJob * lj,int page,int column)20 void docLayoutBlockFrame( BlockFrame * bf,
21 BufferItem * node,
22 const LayoutJob * lj,
23 int page,
24 int column )
25 {
26 const LayoutContext * lc= &(lj->ljContext);
27 BufferDocument * bd= lc->lcDocument;
28
29 docBlockFrameTwips( bf, node, bd, page, column );
30
31 if ( page == lj->ljBalancePage )
32 {
33 bf->bfContentRect.drY1= lj->ljBalanceY1;
34 bf->bfFlowRect.drY1= lj->ljBalanceY1;
35 }
36
37 return;
38 }
39
40 /************************************************************************/
41 /* */
42 /* Continue to lay out the text on a subsequent page. */
43 /* */
44 /* 1) Continuous sections wrap to the same position as where they */
45 /* started on the page. */
46 /* */
47 /************************************************************************/
48
docLayoutColumnTop(LayoutPosition * lpTop,BlockFrame * bf,BufferItem * bodySectNode,const LayoutJob * lj)49 void docLayoutColumnTop( LayoutPosition * lpTop,
50 BlockFrame * bf,
51 BufferItem * bodySectNode,
52 const LayoutJob * lj )
53 {
54 if ( bodySectNode->biTreeType != DOCinBODY )
55 { SDEB(docTreeTypeStr(bodySectNode->biTreeType)); }
56
57 /* Can actually happen while formatting endnotes
58 if ( lj->ljBodySectNode != bodySectNode )
59 { XXDEB(lj->ljBodySectNode,bodySectNode); }
60 */
61
62 docLayoutBlockFrame( bf, bodySectNode, lj, lpTop->lpPage, lpTop->lpColumn );
63
64 lpTop->lpPageYTwips= bf->bfContentRect.drY0;
65 lpTop->lpAtTopOfColumn= 1;
66
67 /* 1 */
68 if ( DOC_SECTnodeBELOW_PREVIOUS( bodySectNode ) &&
69 lpTop->lpPage == bodySectNode->biTopPosition.lpPage &&
70 bodySectNode->biSectColumnCount > 1 &&
71 lpTop->lpColumn > 0 )
72 {
73 lpTop->lpPageYTwips= bodySectNode->biTopPosition.lpPageYTwips;
74 /* NO: we are at the top for this section lpTop->lpAtTopOfColumn= 0; */
75 }
76
77 return;
78 }
79
80 /************************************************************************/
81 /* */
82 /* Skip to the next column. Without newspaper style columns, that is */
83 /* the next page. */
84 /* */
85 /************************************************************************/
86
docLayoutToNextColumn(LayoutPosition * lpTop,BlockFrame * bf,BufferItem * node,const LayoutJob * lj)87 void docLayoutToNextColumn( LayoutPosition * lpTop,
88 BlockFrame * bf,
89 BufferItem * node,
90 const LayoutJob * lj )
91 {
92 const LayoutContext * lc= &(lj->ljContext);
93 const BufferDocument * bd= lc->lcDocument;
94 BufferItem * bodyNode= bd->bdBody.dtRoot;
95 BufferItem * bodySectNode;
96
97 node= docGetSectNode( node );
98 if ( ! node )
99 { XDEB(node); return; }
100
101 switch( node->biTreeType )
102 {
103 SelectionScope * ss;
104 int extTo;
105
106 case DOCinBODY:
107 bodySectNode= node;
108 break;
109
110 case DOCinAFTNSEP:
111 extTo= bodyNode->biChildCount- 1;
112 bodySectNode= bodyNode->biChildren[extTo];
113 break;
114
115 default:
116 ss= &(node->biSectSelectionScope);
117 extTo= ss->ssOwnerSectNr;
118 if ( extTo < 0 )
119 {
120 SLDEB(docTreeTypeStr(node->biTreeType),extTo);
121 return;
122 }
123 bodySectNode= bodyNode->biChildren[extTo];
124 break;
125 }
126
127 lpTop->lpColumn++;
128 if ( lpTop->lpColumn >= bodySectNode->biSectColumnCount )
129 { lpTop->lpPage++; lpTop->lpColumn= 0; }
130
131 if ( lj->ljBodySectNode != bodySectNode &&
132 node->biTreeType != DOCinENDNOTE )
133 {
134 XXDEB(lj->ljBodySectNode,bodySectNode);
135 SDEB(docTreeTypeStr(node->biTreeType));
136 }
137
138 docLayoutColumnTop( lpTop, bf, bodySectNode, lj );
139
140 return;
141 }
142
143 /************************************************************************/
144 /* */
145 /* Adjust geometry to position paragraphs in a text frame. */
146 /* */
147 /************************************************************************/
148
docLayoutFinishFrame(const FrameProperties * fp,BlockFrame * bfTextFrame,const BlockFrame * bfFlow,const LayoutJob * lj,const ParagraphLayoutPosition * plpFlow,BufferItem * cellBi,int paraFrom,int paraUpto)149 void docLayoutFinishFrame( const FrameProperties * fp,
150 BlockFrame * bfTextFrame,
151 const BlockFrame * bfFlow,
152 const LayoutJob * lj,
153 const ParagraphLayoutPosition * plpFlow,
154 BufferItem * cellBi,
155 int paraFrom,
156 int paraUpto )
157 {
158 BufferItem * paraBi0= cellBi->biChildren[paraFrom];
159 BufferItem * paraBi1= cellBi->biChildren[paraUpto- 1];
160
161 int y0= bfTextFrame->bfContentRect.drY0;
162 int y1= paraBi1->biBelowPosition.lpPageYTwips;
163
164 int frameHeight;
165 BlockFrame bfRedo;
166
167 if ( ! DOCisFRAME( fp ) )
168 { LDEB(1); return; }
169
170 if ( fp->fpHighTwips < 0 )
171 {
172 y1= y0- fp->fpHighTwips;
173
174 /*
175 if ( paraBi1->biBelowPosition.lpPageYTwips > y1 )
176 { LLDEB(paraBi1->biBelowPosition.lpPageYTwips,y1); }
177 */
178 }
179
180 if ( fp->fpHighTwips > 0 )
181 { y1= y0+ fp->fpHighTwips; }
182
183 if ( paraBi1->biBelowPosition.lpPageYTwips < y1 )
184 { paraBi1->biBelowPosition.lpPageYTwips= y1; }
185
186 frameHeight= y1- y0;
187 docLayoutInitBlockFrame( &bfRedo );
188 docLayoutSetTextFrame( &bfRedo, &(plpFlow->plpPos),
189 bfFlow, fp, frameHeight );
190
191 if ( bfRedo.bfContentRect.drY0 !=
192 bfTextFrame->bfContentRect.drY0 )
193 {
194 int yBelow;
195 LayoutPosition lpTop= paraBi0->biTopPosition;
196
197 lpTop.lpPageYTwips= bfRedo.bfContentRect.drY0;
198
199 yBelow= bfRedo.bfContentRect.drY0+ frameHeight;
200
201 docRedoParaStripLayout( lj, bfTextFrame, &lpTop,
202 cellBi, paraFrom, paraUpto );
203
204 paraBi1->biBelowPosition.lpPageYTwips= yBelow;
205 }
206
207 return;
208 }
209
210