1 /************************************************************************/
2 /* */
3 /* Geometry administration for 'DocumentTrees' I.E. headers/footers */
4 /* and foonotes/endnotes. */
5 /* */
6 /************************************************************************/
7
8 # include "docLayoutConfig.h"
9
10 # include <appDebugon.h>
11
12 # include <docBuf.h>
13 # include <docDebug.h>
14 # include <docTextLine.h>
15 # include <docTreeNode.h>
16 # include <docNodeTree.h>
17 # include "docSelectLayout.h"
18
19 /************************************************************************/
20 /* */
21 /* Go to the top/bottom of a certain page. */
22 /* */
23 /* 1) Sections that start on an odd/even page may skip a page. */
24 /* */
25 /************************************************************************/
26
docParaGetFirstInColumn(DocumentPosition * dp,int * pLineTop,int * pPartTop,BufferItem * paraBi,int lineUpto,int page,int column)27 static int docParaGetFirstInColumn(
28 DocumentPosition * dp,
29 int * pLineTop,
30 int * pPartTop,
31 BufferItem * paraBi,
32 int lineUpto,
33 int page,
34 int column )
35 {
36 int i;
37 const TextLine * tl= paraBi->biParaLines;
38
39 for ( i= 0; i < lineUpto; tl++, i++ )
40 {
41 if ( tl->tlTopPosition.lpPage >= page )
42 {
43 if ( tl->tlTopPosition.lpPage > page )
44 { break; }
45 if ( tl->tlTopPosition.lpColumn >= column )
46 { break; }
47 }
48 }
49
50 if ( paraBi->biParaLineCount > 0 && i >= paraBi->biParaLineCount )
51 {
52 tl= paraBi->biParaLines+ paraBi->biParaLineCount- 1;
53
54 if ( tl->tlFlags & TLflagBLOCKBREAK )
55 {
56 BufferItem * nextBi= docNextParagraph( paraBi );
57
58 if ( nextBi && nextBi->biParaLineCount > 0 )
59 { i= 0; paraBi= nextBi; tl= paraBi->biParaLines; }
60 }
61 }
62
63 if ( i >= paraBi->biParaLineCount ||
64 tl->tlTopPosition.lpPage != page ||
65 tl->tlTopPosition.lpColumn != column )
66 {
67 SDEB(docTreeTypeStr(paraBi->biTreeType));
68 LLDEB(page,column);
69 LDEB(paraBi->biBelowPosition.lpPage);
70 LDEB(paraBi->biBelowPosition.lpColumn);
71 /*docListNode(0,paraBi);*/
72 LDEB(docNumberOfParagraph(paraBi));
73 LLDEB(i,paraBi->biParaLineCount);
74 return -1;
75 }
76
77 dp->dpNode= paraBi;
78 dp->dpStroff= tl->tlStroff;
79
80 *pLineTop= tl- paraBi->biParaLines;
81 *pPartTop= tl->tlFirstParticule;
82
83 return 0;
84 }
85
docGetFirstInColumnForNode(DocumentPosition * dp,int * pLineTop,int * pPartTop,BufferItem * node,int page,int column)86 int docGetFirstInColumnForNode(
87 DocumentPosition * dp,
88 int * pLineTop,
89 int * pPartTop,
90 BufferItem * node,
91 int page,
92 int column )
93 {
94 int i;
95
96 while( node && node->biLevel != DOClevPARA )
97 {
98 /* 1 */
99 if ( node->biTopPosition.lpPage > page )
100 {
101 /* LLDEB(node->biTopPosition.lpPage,page); */
102 return 1;
103 }
104 if ( node->biBelowPosition.lpPage < page )
105 {
106 /* LLDEB(node->biTopPosition.lpPage,page); */
107 return 1;
108 }
109
110 for ( i= 0; i < node->biChildCount; i++ )
111 {
112 if ( node->biChildren[i]->biBelowPosition.lpPage >= page )
113 {
114 if ( node->biChildren[i]->biBelowPosition.lpPage > page )
115 { break; }
116 if ( node->biChildren[i]->biBelowPosition.lpColumn >= column )
117 { break; }
118 }
119 }
120
121 if ( i >= node->biChildCount )
122 {
123 /* NO! is possible e.g. when endnotes continue beyond the
124 last page with body content.
125 for ( i= 0; i < node->biChildCount; i++ )
126 { LLDEB(i,node->biChildren[i]->biBelowPosition.lpPage); }
127 LLLDEB(node->biTopPosition.lpPage,node->biBelowPosition.lpPage,page);
128 return -1;
129 */
130 return 1;
131 }
132
133 node= node->biChildren[i];
134 }
135
136 if ( ! node || node->biLevel != DOClevPARA )
137 { XDEB(node); return -1; }
138
139 return docParaGetFirstInColumn( dp, pLineTop, pPartTop,
140 node, node->biParaLineCount, page, column );
141 }
142
docGetTopOfColumn(DocumentPosition * dp,int * pLineTop,int * pPartTop,BufferDocument * bd,int page,int column)143 int docGetTopOfColumn( DocumentPosition * dp,
144 int * pLineTop,
145 int * pPartTop,
146 BufferDocument * bd,
147 int page,
148 int column )
149 {
150 return docGetFirstInColumnForNode( dp, pLineTop, pPartTop,
151 bd->bdBody.dtRoot, page, column );
152 }
153
docGetLastInColumnForNode(DocumentPosition * dp,int * pLineBot,int * pPartBot,BufferItem * nodeIn,int page,int column)154 int docGetLastInColumnForNode( DocumentPosition * dp,
155 int * pLineBot,
156 int * pPartBot,
157 BufferItem * nodeIn,
158 int page,
159 int column )
160 {
161 int i;
162 const TextLine * tl;
163 BufferItem * node= nodeIn;
164
165 while( node && node->biLevel != DOClevPARA )
166 {
167 if ( node->biTopPosition.lpPage > page )
168 { /*LLDEB(node->biBelowPosition.lpPage,page);*/ return 1; }
169 if ( node->biBelowPosition.lpPage < page )
170 { /*LLDEB(node->biBelowPosition.lpPage,page);*/ return 1; }
171
172 for ( i= node->biChildCount- 1; i >= 0; i-- )
173 {
174 if ( node->biChildren[i]->biTopPosition.lpPage <= page )
175 {
176 if ( node->biChildren[i]->biTopPosition.lpPage < page )
177 { break; }
178 if ( node->biChildren[i]->biTopPosition.lpColumn <= column )
179 { break; }
180 }
181 }
182
183 if ( i < 0 )
184 {
185 /*
186 for ( i= 0; i < node->biChildCount; i++ )
187 { LLDEB(i,node->biChildren[i]->biTopPosition.lpPage); }
188 LLLDEB(node->biTopPosition.lpPage,node->biBelowPosition.lpPage,page);
189 */
190 return 1;
191 }
192
193 node= node->biChildren[i];
194 }
195
196 if ( ! node || node->biLevel != DOClevPARA )
197 { XDEB(node); return -1; }
198
199 tl= node->biParaLines+ node->biParaLineCount- 1;
200 for ( i= node->biParaLineCount- 1; i >= 0; tl--, i-- )
201 {
202 if ( tl->tlTopPosition.lpPage <= page )
203 {
204 if ( tl->tlTopPosition.lpPage < page )
205 { break; }
206 if ( tl->tlTopPosition.lpColumn <= column )
207 { break; }
208 }
209 }
210
211 if ( i < 0 ||
212 tl->tlTopPosition.lpPage != page ||
213 tl->tlTopPosition.lpColumn != column )
214 {
215 SSDEB(docTreeTypeStr(node->biTreeType),docLevelStr(node->biLevel));
216 LLDEB(page,column);
217 LDEB(node->biBelowPosition.lpPage);
218 LDEB(node->biBelowPosition.lpColumn);
219 /*docListNode(0,nodeIn,0);*/
220 LDEB(docNumberOfParagraph(node));
221 LLDEB(i,node->biParaLineCount);
222 return -1;
223 }
224
225 dp->dpNode= node;
226 dp->dpStroff= tl->tlStroff+ tl->tlStrlen;
227
228 *pLineBot= tl- node->biParaLines;
229 *pPartBot= tl->tlFirstParticule+ tl->tlParticuleCount- 1;
230
231 return 0;
232 }
233
docGetBottomOfColumn(DocumentPosition * dp,int * pPartBot,BufferDocument * bd,int page,int column)234 int docGetBottomOfColumn(
235 DocumentPosition * dp,
236 int * pPartBot,
237 BufferDocument * bd,
238 int page,
239 int column )
240 {
241 int lineBot;
242
243 return docGetLastInColumnForNode( dp, &lineBot, pPartBot,
244 bd->bdBody.dtRoot, page, column );
245 }
246
247