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