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