1 /* wvWare
2  * Copyright (C) Caolan McNamara, Dom Lachowicz, and others
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17  * 02111-1307, USA.
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23 
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include "wv.h"
28 
29 #include "wvinternal.h"
30 
31 static PAPX_FKP wvPAPX_FKP_previous;
32 static U32 wvPAPX_pn_previous = 0;
33 static CHPX_FKP wvCHPX_FKP_previous;
34 static U32 wvCHPX_pn_previous = 0;
35 
36 
37 void
external_wvReleasePAPX_FKP(void)38 external_wvReleasePAPX_FKP (void)
39 {
40         if (wvPAPX_pn_previous != 0)
41         {
42                 wvPAPX_pn_previous = 0;
43         }
44 }
45 
46 void
external_wvReleaseCHPX_FKP(void)47 external_wvReleaseCHPX_FKP (void)
48 {
49         if (wvCHPX_pn_previous != 0)
50         {
51                 wvCHPX_pn_previous = 0;
52         }
53 }
54 
55 void
internal_wvReleasePAPX_FKP(PAPX_FKP * fkp)56 internal_wvReleasePAPX_FKP (PAPX_FKP * fkp)
57 {
58     int i;
59     wvFree (fkp->rgfc);
60     fkp->rgfc = NULL;
61     wvFree (fkp->rgbx);
62     fkp->rgbx = NULL;
63     for (i = 0; i < fkp->crun; i++)
64 	wvReleasePAPX (&(fkp->grppapx[i]));
65     fkp->crun = 0;
66     wvFree (fkp->grppapx);
67     fkp->grppapx = NULL;
68 }
69 
70 /*
71 At offset
72 511 is a 1-byte count named crun, which is a count of paragraphs in PAPX
73 FKPs. Beginning at offset 0 of the FKP is an array of crun+1 FCs, named
74 rgfc, which records the beginning and limit FCs of crun paragraphs.
75 
76 immediately following the fkp.rgfc is an array of 13 byte
77 entries called BXs. This array called the rgbx is in 1-to-1 correspondence
78 with the rgfc. The first byte of the ith BX entry contains a single byte
79 field which gives the word offset of the PAPX that belongs to the paragraph
80 whose beginning in FC space is rgfc[i] and whose limit is rgfc[i+1] in FC
81 space. The last 12 bytes of the ith BX entry contain a PHE structure that
82 stores the current paragraph height of the paragraph whose beginning in FC
83 space is rgfc[i] and whose limit is rgfc[i+1] in FC space.
84 */
85 
86 /*
87 The first byte of each BX is the word offset of the PAPX recorded for
88 the paragraph corresponding to this BX. .. If the byte stored is 0,
89 this represents a 1 line paragraph 15 pixels high with Normal style
90 (stc == 0) whose column width is 7980 dxas. The last 12 bytes of
91 the BX is a PHE structure which stores the current paragraph height
92 for the paragraph corresponding to the BX. If a plcfphe has an entry
93 that maps to the FC for this paragraph, that entry's PHE overrides the PHE
94 stored in the FKP.11*fkp.crun+4 unused space. As new runs/paragraphs
95 are recorded in the FKP, unused space is reduced by 17 if CHPX/PAPX
96 is already recorded and is reduced by 17+sizeof(PAPX) if property is not
97 already recorded.
98 */
99 
100 void
wvGetPAPX_FKP(wvVersion ver,PAPX_FKP * fkp,U32 pn,wvStream * fd)101 wvGetPAPX_FKP (wvVersion ver, PAPX_FKP * fkp, U32 pn, wvStream * fd)
102 {
103     int i;
104     U8 page[WV_PAGESIZE];
105     U16 pos = 0;
106     /*size_t bytes_read; */
107 
108     /* brian.ewins@bt.com */
109     /* there seem to be a lot of repeat calls... */
110     /* pn=0 is safe because thats the index block, not a PAPX_FKP */
111     if (pn != 0 && pn == wvPAPX_pn_previous)
112       {
113 	  memcpy (fkp, &wvPAPX_FKP_previous, sizeof (PAPX_FKP));
114 	  return;
115       }
116 
117     wvTrace (
118 	     ("seeking to %x to get crun\n",
119 	      pn * WV_PAGESIZE + (WV_PAGESIZE - 1)));
120     wvStream_goto (fd, pn * WV_PAGESIZE);
121     /*bytes_read= */ wvStream_read (page, WV_PAGESIZE, 1, fd);
122     fkp->crun = (U8) page[WV_PAGESIZE - 1];
123     fkp->rgfc = (U32 *) wvMalloc (sizeof (U32) * (fkp->crun + 1));
124     fkp->rgbx = (BX *) wvMalloc (sizeof (BX) * (fkp->crun));
125     fkp->grppapx = (PAPX *) wvMalloc (sizeof (PAPX) * (fkp->crun));
126     for (i = 0; i < fkp->crun + 1; i++)
127       {
128 	  fkp->rgfc[i] = bread_32ubit (&(page[pos]), &pos);
129 	  wvTrace (("rgfc is %x\n", fkp->rgfc[i]));
130       }
131 
132     for (i = 0; i < fkp->crun; i++)
133       {
134 	  if (ver == WORD8)
135 	      wvGetBX (&fkp->rgbx[i], page, &pos);
136 	  else
137 	      wvGetBX6 (&fkp->rgbx[i], page, &pos);
138       }
139 
140     for (i = 0; i < fkp->crun; i++)
141       {
142 	  if (fkp->rgbx[i].offset == 0)
143 	    {
144 		wvTrace (("i is %d, using clear papx\n", i));
145 		wvInitPAPX (&(fkp->grppapx[i]));
146 	    }
147 	  else
148 	    {
149 		wvTrace (
150 			 ("papx index i is %d, offset is %x\n", i,
151 			  pn * WV_PAGESIZE + fkp->rgbx[i].offset * 2));
152 		pos = fkp->rgbx[i].offset * 2;
153 		wvGetPAPX (ver, &(fkp->grppapx[i]), page, &pos);
154 	    }
155       }
156     if (wvPAPX_pn_previous != 0)
157 	internal_wvReleasePAPX_FKP (&wvPAPX_FKP_previous);
158     memcpy (&wvPAPX_FKP_previous, fkp, sizeof (PAPX_FKP));
159     wvPAPX_pn_previous = pn;
160 }
161 
162 /*
163 Using the FC, search the FCs FKP for the largest FC less than the character's FC,
164     call it fcTest.
165 */
166 U32
wvSearchNextLargestFCPAPX_FKP(PAPX_FKP * fkp,U32 currentfc)167 wvSearchNextLargestFCPAPX_FKP (PAPX_FKP * fkp, U32 currentfc)
168 {
169     U32 i = 0;
170     U8 until = fkp->crun + 1;
171     U32 fcTest = 0;
172 
173 
174     while (i < until)
175       {
176 	  wvTrace (("searching fkp %x %x\n", currentfc, fkp->rgfc[i]));
177 	  if ((wvNormFC (fkp->rgfc[i], NULL) < currentfc)
178 	      && (wvNormFC (fkp->rgfc[i], NULL) > fcTest))
179 	      fcTest = wvNormFC (fkp->rgfc[i], NULL);
180 	  else if (wvNormFC (fkp->rgfc[i], NULL) == currentfc)
181 	      fcTest = currentfc + 1;
182 	  i++;
183       }
184 
185     /*for the first paragraph return the current pos as the beginning */
186     /*
187        if (fcTest == 0)
188        fcTest = currentfc+1;
189      */
190 
191     return (fcTest);
192 }
193 
194 U32
wvSearchNextLargestFCCHPX_FKP(CHPX_FKP * fkp,U32 currentfc)195 wvSearchNextLargestFCCHPX_FKP (CHPX_FKP * fkp, U32 currentfc)
196 {
197     U32 i = 0;
198     U8 until = fkp->crun + 1;
199     U32 fcTest = 0;
200 
201 
202     while (i < until)
203       {
204 	  wvTrace (("searching fkp %x %x\n", currentfc, fkp->rgfc[i]));
205 	  if ((wvNormFC (fkp->rgfc[i], NULL) <= currentfc)
206 	      && (wvNormFC (fkp->rgfc[i], NULL) > fcTest))
207 	      fcTest = wvNormFC (fkp->rgfc[i], NULL);
208 	  i++;
209       }
210 
211     /*for the first paragraph return the current pos as the beginning */
212     /*
213        if (fcTest == 0)
214        fcTest = currentfc+1;
215      */
216 
217     return (fcTest);
218 }
219 
220 /*
221 Using the FC of the character, first search the FKP that describes the
222 character to find the smallest FC in the rgfc that is larger than the character
223 FC.
224 */
225 U32
wvSearchNextSmallestFCPAPX_FKP(PAPX_FKP * fkp,U32 currentfc)226 wvSearchNextSmallestFCPAPX_FKP (PAPX_FKP * fkp, U32 currentfc)
227 {
228     U32 i = 0;
229     U32 fcTest = 0xffffffffL;
230     U8 until = fkp->crun + 1;
231 
232     while (i < until)
233       {
234 	  wvTrace (
235 		   ("Smallest %x, %x %x\n", currentfc,
236 		    wvNormFC (fkp->rgfc[i], NULL), wvNormFC (fkp->rgfc[i],
237 							     NULL)));
238 	  if ((wvNormFC (fkp->rgfc[i], NULL) > currentfc)
239 	      && (wvNormFC (fkp->rgfc[i], NULL) < fcTest))
240 	      fcTest = wvNormFC (fkp->rgfc[i], NULL);
241 	  i++;
242       }
243     return (fcTest);
244 }
245 
246 void
wvReleasePAPX_FKP(PAPX_FKP * fkp)247 wvReleasePAPX_FKP (PAPX_FKP * fkp)
248 {
249     return;
250 }
251 
252 
253 void
wvInitPAPX_FKP(PAPX_FKP * fkp)254 wvInitPAPX_FKP (PAPX_FKP * fkp)
255 {
256     fkp->rgfc = NULL;
257     fkp->rgbx = NULL;
258     fkp->crun = 0;
259     fkp->grppapx = NULL;
260 }
261 
262 int
wvGetIndexFCInFKP_PAPX(PAPX_FKP * fkp,U32 currentfc)263 wvGetIndexFCInFKP_PAPX (PAPX_FKP * fkp, U32 currentfc)
264 {
265     U32 i = 1;			/*was 0, there is something slightly out of sync in the system */
266     U8 until = fkp->crun + 1;
267 
268     while (i < until)
269       {
270 	  wvTrace (
271 		   ("current fc is %x, %x, %x\n", currentfc,
272 		    wvNormFC (fkp->rgfc[i], NULL), fkp->rgfc[i]));
273 	  if (wvNormFC (fkp->rgfc[i], NULL) == currentfc)
274 	      return (i);
275 	  i++;
276       }
277     /*
278        basically read
279        Algorithm to determine paragraph properties for a paragraph &
280        Formatted Disk Page for PAPXs, somehow the currentfc sent in was wrong
281        or my understanding is !
282      */
283     wvTrace (("Shite, fix me %x %x\n", currentfc, fkp->rgfc[0]));
284     /*return 1 to make things continue on their merry way */
285     return (1);
286 }
287 
288 void
internal_wvReleaseCHPX_FKP(CHPX_FKP * fkp)289 internal_wvReleaseCHPX_FKP (CHPX_FKP * fkp)
290 {
291     int i;
292     wvTrace (("chpx fkp b freeed\n"));
293     wvFree (fkp->rgfc);
294     fkp->rgfc = NULL;
295     wvFree (fkp->rgb);
296     fkp->rgb = NULL;
297     for (i = 0; i < fkp->crun; i++)
298 	wvReleaseCHPX (&(fkp->grpchpx[i]));
299     fkp->crun = 0;
300     wvFree (fkp->grpchpx);
301     fkp->grpchpx = NULL;
302     wvTrace (("chpx fkp e freeed\n"));
303 }
304 
305 
306 /* Character properties
307  * -basically just like PAPX FKPs above
308  * however, rather than an array of BX structs in rgbx,
309  * there is an array of bytes (giving the word offset to the CHPX) in rgb
310  * -JB
311  */
312 void
wvGetCHPX_FKP(wvVersion ver,CHPX_FKP * fkp,U32 pn,wvStream * fd)313 wvGetCHPX_FKP (wvVersion ver, CHPX_FKP * fkp, U32 pn, wvStream * fd)
314 {
315     int i;
316     U8 page[WV_PAGESIZE];
317     U16 pos = 0;
318     /*size_t bytes_read; */
319 
320     /* brian.ewins@bt.com */
321     /* there seem to be a lot of repeat calls... */
322     /* pn=0 is safe because thats the index block, not a CHPX_FKP */
323     if (pn != 0 && pn == wvCHPX_pn_previous)
324       {
325 	  memcpy (fkp, &wvCHPX_FKP_previous, sizeof (CHPX_FKP));
326 	  return;
327       }
328     wvStream_goto (fd, pn * WV_PAGESIZE);
329     /*bytes_read= */ wvStream_read (page, WV_PAGESIZE, 1, fd);
330     fkp->crun = (U8) page[WV_PAGESIZE - 1];
331     wvTrace (("chpx fkp gone to %x\n", pn * WV_PAGESIZE + (WV_PAGESIZE - 1)));
332     wvTrace (("crun is %d\n", fkp->crun));
333     fkp->rgfc = (U32 *) wvMalloc (sizeof (U32) * (fkp->crun + 1));
334     fkp->rgb = (U8 *) wvMalloc (sizeof (U8) * (fkp->crun));
335     fkp->grpchpx = (CHPX *) wvMalloc (sizeof (CHPX) * (fkp->crun));
336     wvStream_goto (fd, pn * WV_PAGESIZE);
337     wvTrace (("offset is %x\n", pn * WV_PAGESIZE));
338     for (i = 0; i < fkp->crun + 1; i++)
339       {
340 	  fkp->rgfc[i] = bread_32ubit (&(page[pos]), &pos);
341 	  wvTrace (("rgfc is %x\n", fkp->rgfc[i]));
342       }
343 
344     for (i = 0; i < fkp->crun; i++)
345 	fkp->rgb[i] = bread_8ubit (&(page[pos]), &pos);
346 
347     for (i = 0; i < fkp->crun; i++)
348       {
349 	  if (fkp->rgb[i] == 0)
350 	    {
351 		wvTrace (("i is %d, using clear chpx\n", i));
352 		wvInitCHPX (&(fkp->grpchpx[i]));
353 	    }
354 	  else
355 	    {
356 		wvTrace (
357 			 ("chpx index i is %d, offset is %x\n", i,
358 			  (pn * WV_PAGESIZE) + (fkp->rgb[i] * 2)));
359 		pos = fkp->rgb[i] * 2;
360 		wvGetCHPX (ver, &(fkp->grpchpx[i]), page, &pos);
361 	    }
362       }
363     if (wvCHPX_pn_previous != 0)
364 	internal_wvReleaseCHPX_FKP (&wvCHPX_FKP_previous);
365     memcpy (&wvCHPX_FKP_previous, fkp, sizeof (CHPX_FKP));
366     wvCHPX_pn_previous = pn;
367 }
368 
369 void
wvReleaseCHPX_FKP(CHPX_FKP * fkp)370 wvReleaseCHPX_FKP (CHPX_FKP * fkp)
371 {
372     return;
373 }
374 
375 
376 void
wvInitCHPX_FKP(CHPX_FKP * fkp)377 wvInitCHPX_FKP (CHPX_FKP * fkp)
378 {
379     fkp->rgfc = NULL;
380     fkp->rgb = NULL;
381     fkp->crun = 0;
382     fkp->grpchpx = NULL;
383 }
384