/[public]/psiconv/trunk/lib/psiconv/parse_layout.c
ViewVC logotype

Contents of /psiconv/trunk/lib/psiconv/parse_layout.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2 - (show annotations)
Sun Oct 3 21:10:47 1999 UTC (24 years, 6 months ago) by frodo
File MIME type: text/plain
File size: 19727 byte(s)
Imported sources

1 /*
2 parse_layout.c - Part of psiconv, a PSION 5 file formats converter
3 Copyright (c) 1999 Frodo Looijaard <frodol@dds.nl>
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include "config.h"
21 #include <stdlib.h>
22 #include <math.h>
23
24 #include "data.h"
25 #include "parse_routines.h"
26
27 int psiconv_parse_color(const psiconv_buffer buf, int lev, psiconv_u32 off,
28 int *length, psiconv_color *result)
29 {
30 int res = 0;
31 int len = 0;
32
33 psiconv_progress(lev+1,off,"Going to parse color");
34 *result = malloc(sizeof(**result));
35
36 (*result)->red = psiconv_read_u8(buf,lev+2,off+len);
37 (*result)->green = psiconv_read_u8(buf,lev+2,off+len+1);
38 (*result)->blue = psiconv_read_u8(buf,lev+2,off+len+2);
39 len += 3;
40
41 psiconv_debug(lev+2,off,"Color: red %02x, green %02x, blue %02x",
42 (*result)->red, (*result)->green, (*result)->blue);
43 if (length)
44 *length = len;
45
46 psiconv_progress(lev+1,off+len-1,"End of color (total length: %08x)",len);
47 return res;
48 }
49
50
51
52 int psiconv_parse_font(const psiconv_buffer buf, int lev, psiconv_u32 off,
53 int *length, psiconv_font *result)
54 {
55 int res = 0;
56 int strlength,i;
57 char *str_copy;
58 int len;
59
60 psiconv_progress(lev+1,off,"Going to parse font");
61 *result = malloc(sizeof(**result));
62
63 strlength = psiconv_read_u8(buf,lev+2,off);
64 (*result)->name = malloc(strlength);
65 for (i = 0; i < strlength-1; i++)
66 (*result)->name[i] = psiconv_read_u8(buf,lev+2,off + 1 + i);
67 (*result)->name[strlength-1] = 0;
68 (*result)->screenfont = psiconv_read_u8(buf,lev+2,off + strlength);
69
70 str_copy = psiconv_make_printable((*result)->name);
71 psiconv_debug(lev+2,off+1,"Found font `%s', displayed with screen font %02x",
72 str_copy,(*result)->screenfont);
73 free(str_copy);
74 len = strlength + 1;
75 if (length)
76 *length = len;
77
78 psiconv_progress(lev+1,off + len - 1,"End of font (total length: %08x)",len);
79 return res;
80 }
81
82 int psiconv_parse_border(const psiconv_buffer buf,int lev,psiconv_u32 off,
83 int *length, psiconv_border *result)
84 {
85 int res = 0;
86 int len = 0;
87 psiconv_u32 temp;
88 int leng;
89
90 psiconv_progress(lev+1,off,"Going to parse border data");
91 *result = malloc(sizeof(**result));
92
93 psiconv_progress(lev+2,off+len,"Going to read border kind");
94 temp = psiconv_read_u8(buf,lev+2,off+len);
95 if (temp == 0x00)
96 (*result)->kind = psiconv_border_none;
97 else if (temp == 0x01)
98 (*result)->kind = psiconv_border_solid;
99 else if (temp == 0x02)
100 (*result)->kind = psiconv_border_double;
101 else if (temp == 0x03)
102 (*result)->kind = psiconv_border_dotted;
103 else if (temp == 0x04)
104 (*result)->kind = psiconv_border_striped;
105 else if (temp == 0x05)
106 (*result)->kind = psiconv_border_dotstripe;
107 else if (temp == 0x06)
108 (*result)->kind = psiconv_border_dotdotstripe;
109 else {
110 psiconv_warn(lev+2,off,"Unknown border kind (defaults to `none')");
111 (*result)->kind = psiconv_border_none;
112 res = -1;
113 }
114 psiconv_debug(lev+2,off+len,"Kind: %02x",temp);
115 len ++;
116
117 psiconv_progress(lev+2,off+len,"Going to read border thickness");
118 (*result)->thickness = psiconv_read_size(buf,lev+2,off+len,&leng);
119 if (((*result)->kind != psiconv_border_solid) &&
120 ((*result)->kind != psiconv_border_double) &&
121 ((*result)->thickness != 0.0) &&
122 (fabs((*result)->thickness - 1/20) >= 1/1000)) {
123 psiconv_warn(lev+2,off,
124 "Border thickness specified for unlikely border type");
125 res = -1;
126 }
127 psiconv_debug(lev+2,off+len,"Thickness: %f",(*result)->thickness);
128 len += leng;
129
130 psiconv_progress(lev+2,off+len,"Going to read the border color");
131 res |= psiconv_parse_color(buf,lev+2,off+len,&leng,&(*result)->color);
132 len += leng;
133
134 psiconv_progress(lev+2,off+len,"Going to read the final unknown byte "
135 "(0x01 expected)");
136 temp = psiconv_read_u8(buf,lev+2,off + len);
137 if (temp != 0x01) {
138 psiconv_warn(lev+2,off,"Unknown last byte in border specification");
139 psiconv_debug(lev+2,off+len, "Last byte: read %02x, expected %02x",
140 temp,0x01);
141 res = -1;
142 }
143 len ++;
144
145 if (length)
146 *length = len;
147
148 psiconv_progress(lev+1,off + len - 1,
149 "End of border (total length: %08x)",len);
150
151 return res;
152 }
153
154 int psiconv_parse_bullet(const psiconv_buffer buf,int lev,psiconv_u32 off,
155 int *length, psiconv_bullet *result)
156 {
157 int res = 0;
158 int len = 0;
159 int leng;
160 int bullet_length;
161
162 *result = malloc(sizeof(**result));
163 (*result)->on = psiconv_bool_true;
164
165 psiconv_progress(lev+1,off,"Going to parse bullet data");
166 psiconv_progress(lev+2,off+len,"Going to read bullet length");
167 bullet_length = psiconv_read_u8(buf,lev+2,off+len);
168 psiconv_debug(lev+2,off+len,"Length: %02x",bullet_length);
169 len ++;
170
171 psiconv_progress(lev+2,off+len,"Going to read bullet font size");
172 (*result)->font_size = psiconv_read_size(buf,lev+2,off+len, &leng);
173 len +=leng;
174
175 psiconv_progress(lev+2,off+len,"Going to read bullet character");
176 (*result)->character = psiconv_read_u8(buf,lev+2,off+len);
177 psiconv_debug(lev+2,off+len,"Character: %02x",(*result)->character);
178 len ++;
179
180 psiconv_progress(lev+2,off+len,"Going to read indent on/off");
181 res |= psiconv_parse_bool(buf,lev+2,off+len,&leng,&(*result)->indent);
182 psiconv_debug(lev+2,off+len,"Indent on: %02x",(*result)->indent);
183 len += leng;
184
185 psiconv_progress(lev+2,off+len,"Going to read bullet color");
186 res |= psiconv_parse_color(buf,lev+2,off+len,&leng,&(*result)->color);
187 len += leng;
188
189 psiconv_progress(lev+2,off+len,"Going to read bullet font");
190 res |= psiconv_parse_font(buf,lev+2,off+len,&leng,&(*result)->font);
191 len += leng;
192
193 if (len != bullet_length + 1) {
194 psiconv_warn(lev+2,off,"Bullet data structure length mismatch");
195 psiconv_debug(lev+2,off,"Length: specified %02x, found %02x",
196 bullet_length,len-1);
197 res = -1;
198 }
199
200 psiconv_progress(lev+1,off + len - 1,
201 "End of bullet data (total length: %08x)",len);
202
203 if (length)
204 *length = len;
205 return res;
206 }
207
208 int psiconv_parse_tab(const psiconv_buffer buf, int lev, psiconv_u32 off,
209 int *length, psiconv_tab *result)
210 {
211 int res = 0;
212 int len = 0;
213 int leng;
214 psiconv_u8 temp;
215
216 psiconv_progress(lev+1,off,"Going to parse tab");
217 *result = malloc(sizeof(**result));
218
219 psiconv_progress(lev+2,off,"Going to read tab location");
220 (*result)->location = psiconv_read_length(buf,lev+2,off+len,&leng);
221 len += leng;
222
223 psiconv_progress(lev+2,off+len,"Going to read the tab kind");
224 temp = psiconv_read_u8(buf,lev+2,off+len);
225 if (temp == 1)
226 (*result)->kind = psiconv_tab_left;
227 else if (temp == 2)
228 (*result)->kind = psiconv_tab_centre;
229 else if (temp == 3)
230 (*result)->kind = psiconv_tab_right;
231 else {
232 res = -1;
233 psiconv_warn(lev+2,off+len,"Unknown tab kind argument");
234 psiconv_debug(lev+2,off+len,"Kind found: %02x (defaulted to left tab)",
235 temp);
236 (*result)->kind = psiconv_tab_left;
237 }
238 psiconv_debug(lev+2,off+len,"Kind: %02x",temp);
239 len ++;
240
241 if (length)
242 *length = len;
243
244 psiconv_progress(lev+1,off+len-1,"End of tab (total length: %08x)",len);
245 return res;
246
247 }
248
249 int psiconv_parse_paragraph_layout_list(const psiconv_buffer buf, int lev,
250 psiconv_u32 off, int *length,
251 psiconv_paragraph_layout result)
252 {
253 int res=0;
254 int len=0;
255 int list_length,leng,nr;
256 psiconv_u8 id;
257 psiconv_u32 temp;
258 psiconv_tab tab;
259
260 psiconv_progress(lev+1,off,"Going to read paragraph layout list");
261
262 psiconv_progress(lev+2,off,"Going to read the list length");
263 list_length = psiconv_read_u32(buf,lev+2,off + len);
264 psiconv_debug(lev+2,off,"Length in bytes: %08x",list_length);
265 len += 4;
266
267 nr = 0;
268 while(len - 4 < list_length) {
269 psiconv_progress(lev+2,off+len,"Going to read element %d",nr);
270 psiconv_progress(lev+3,off+len,"Going to read the element id");
271 id = psiconv_read_u8(buf,lev+2,off+len);
272 psiconv_debug(lev+3,off+len,"Id: %02x",id);
273 len ++;
274 switch(id) {
275 case 0x01:
276 psiconv_progress(lev+3,off+len,"Going to read background color");
277 psiconv_free_color(result->back_color);
278 res |= psiconv_parse_color(buf,lev+3,off+len,&leng,
279 &result->back_color);
280 len += leng;
281 break;
282 case 0x02:
283 psiconv_progress(lev+3,off+len ,"Going to read indent left");
284 result->indent_left = psiconv_read_length(buf,lev+3,off+len,&leng);
285 len += leng;
286 break;
287 case 0x03:
288 psiconv_progress(lev+3,off+len,"Going to read indent right");
289 result->indent_right = psiconv_read_length(buf,lev+2,off+len,&leng);
290 len += leng;
291 break;
292 case 0x04:
293 psiconv_progress(lev+3,off+len,"Going to read indent left first line");
294 result->indent_first = psiconv_read_length(buf,lev+2,off+len, &leng);
295 len += leng;
296 break;
297 case 0x05:
298 psiconv_progress(lev+3,off+len,"Going to read horizontal justify");
299 temp = psiconv_read_u8(buf,lev+3,off+len);
300 if (temp == 0x00)
301 result->justify_hor = psiconv_justify_left;
302 else if (temp == 0x01)
303 result->justify_hor = psiconv_justify_centre;
304 else if (temp == 0x02)
305 result->justify_hor = psiconv_justify_right;
306 else if (temp == 0x03)
307 result->justify_hor = psiconv_justify_full;
308 else {
309 res = -1;
310 psiconv_warn(lev+3,off+len, "Unknown horizontal justify argument "
311 "in paragraph layout codes list");
312 }
313 psiconv_debug(lev+3,off+len,"Justify: %02x",temp);
314 len ++;
315 break;
316 case 0x06:
317 psiconv_progress(lev+3,off+len,"Going to read vertical justify");
318 temp = psiconv_read_u8(buf,lev+3,off+len);
319 if (temp == 0x00)
320 result->justify_ver = psiconv_justify_top;
321 else if (temp == 0x01)
322 result->justify_ver = psiconv_justify_middle;
323 else if (temp == 0x02)
324 result->justify_ver = psiconv_justify_bottom;
325 else {
326 res = -1;
327 psiconv_warn(lev+3,off+len, "Unknown vertical justify argument "
328 "in paragraph layout codes list");
329 }
330 psiconv_debug(lev+3,off+len,"Justify: %02x",temp);
331 len ++;
332 case 0x07:
333 psiconv_progress(lev+3,off+len,"Going to read interline distance");
334 result->interline = psiconv_read_size(buf,lev+3,off+len,&leng);
335 len += leng;
336 break;
337 case 0x08:
338 psiconv_progress(lev+3,off+len,"Going to read interline exact");
339 res |= psiconv_parse_bool(buf,lev+3,off+len,&leng,
340 &result->interline_exact);
341 len += leng;
342 break;
343 case 0x09:
344 psiconv_progress(lev+3,off+len,"Going to read top space");
345 result->top_space = psiconv_read_size(buf,lev+3,off+len,&leng);
346 len += leng;
347 break;
348 case 0x0a:
349 psiconv_progress(lev+3,off+len,"Going to read bottom space");
350 result->bottom_space = psiconv_read_size(buf,lev+3,off+len,&leng);
351 len += leng;
352 break;
353 case 0x0b:
354 psiconv_progress(lev+3,off+len,"Going to read on one page");
355 res |= psiconv_parse_bool(buf,lev+3,off+len,&leng,
356 &result->on_one_page);
357 len += leng;
358 break;
359 case 0x0c:
360 psiconv_progress(lev+3,off+len,"Going to read together with");
361 res |= psiconv_parse_bool(buf,lev+3,off+len,&leng,
362 &result->together_with);
363 len += leng;
364 break;
365 case 0x0d:
366 psiconv_progress(lev+3,off+len,"Going to read on next page");
367 res |= psiconv_parse_bool(buf,lev+3,off+len,&leng,
368 &result->on_next_page);
369 len += leng;
370 break;
371 case 0x0e:
372 psiconv_progress(lev+3,off+len,"Going to read no widow protection");
373 res |= psiconv_parse_bool(buf,lev+3,off+len,&leng,
374 &result->no_widow_protection);
375 len += leng;
376 break;
377 case 0x10:
378 psiconv_progress(lev+3,off+len,"Going to read border distance to text");
379 result->border_distance = psiconv_read_length(buf,lev+3,
380 off+len,&leng);
381 len += leng;
382 break;
383 case 0x11:
384 psiconv_progress(lev+3,off+len,"Going to read top border");
385 psiconv_free_border(result->top_border);
386 res |= psiconv_parse_border(buf,lev+3,off+len,&leng,
387 &result->top_border);
388 len += leng;
389 break;
390 case 0x12:
391 psiconv_progress(lev+3,off+len,"Going to read bottom border");
392 psiconv_free_border(result->bottom_border);
393 res |= psiconv_parse_border(buf,lev+3,off+len,&leng,
394 &result->bottom_border);
395 len += leng;
396 break;
397 case 0x13:
398 psiconv_progress(lev+3,off+len,"Going to read left border");
399 psiconv_free_border(result->left_border);
400 res |= psiconv_parse_border(buf,lev+3,off+len,&leng,
401 &result->left_border);
402 len += leng;
403 break;
404 case 0x14:
405 psiconv_progress(lev+3,off+len,"Going to read right border");
406 psiconv_free_border(result->right_border);
407 res |= psiconv_parse_border(buf,lev+3,off+len,&leng,
408 &result->right_border);
409 len += leng;
410 break;
411 case 0x15:
412 psiconv_progress(lev+3,off+len,"Going to read bullet");
413 psiconv_free_bullet(result->bullet);
414 res |= psiconv_parse_bullet(buf,lev+3,off+len,&leng,
415 &result->bullet);
416 len += leng;
417 break;
418 case 0x16:
419 psiconv_progress(lev+3,off+len,"Going to read standard tabs");
420 result->tabs->normal = psiconv_read_length(buf,lev+3,off+len,&leng);
421 len += leng;
422 break;
423 case 0x17:
424 psiconv_progress(lev+3,off+len,"Going to read extra tab");
425 res |= psiconv_parse_tab(buf,lev+3,off+len,&leng,&tab);
426 psiconv_list_add(result->tabs->extras,tab);
427 len += leng;
428 break;
429 default:
430 psiconv_warn(lev+3,off+len,
431 "Unknown code in paragraph layout codes list");
432 psiconv_debug(lev+3,off+len,"Code: %02x",id);
433 len ++;
434 res = -1;
435 break;
436 }
437 nr ++;
438 }
439
440 if (len - 4 != list_length) {
441 psiconv_warn(lev+2,off+len,
442 "Read past end of paragraph layout codes list. I probably lost track"
443 "somewhere!");
444 psiconv_debug(lev+2,off+len,"Read %d characters instead of %d",
445 len-4,list_length);
446 }
447
448 len = list_length + 4;
449
450 psiconv_progress(lev+1,off+len,
451 "End of paragraph layout list (total length: %08x)",len);
452
453 if (length)
454 *length = len;
455 return res;
456 }
457
458 int psiconv_parse_character_layout_list(const psiconv_buffer buf, int lev,
459 psiconv_u32 off, int *length,
460 psiconv_character_layout result)
461 {
462 int res=0;
463 int len=0;
464 int list_length,leng,nr;
465 psiconv_u8 id;
466 psiconv_u32 temp;
467
468 psiconv_progress(lev+1,off,"Going to read character layout codes");
469
470 psiconv_progress(lev+2,off,"Going to read the list length");
471 list_length = psiconv_read_u32(buf,lev+2,off + len);
472 psiconv_debug(lev+2,off,"Length in bytes: %08x",list_length);
473 len += 4;
474
475 nr = 0;
476 while(len-4 < list_length) {
477 psiconv_progress(lev+2,off+len,"Going to read element %d",nr);
478 psiconv_progress(lev+3,off+len,"Going to read the element id");
479 id = psiconv_read_u8(buf,lev+2,off+len);
480 psiconv_debug(lev+3,off+len,"Id: %02x",id);
481 len ++;
482 switch(id) {
483 case 0x19:
484 psiconv_progress(lev+3,off+len,"Going to read text color");
485 psiconv_free_color(result->color);
486 res |= psiconv_parse_color(buf,lev+3,off+len, &leng,&result->color);
487 len += leng;
488 break;
489 case 0x1a:
490 psiconv_progress(lev+3,off+len,"Going to read background color (?)");
491 psiconv_free_color(result->back_color);
492 res |= psiconv_parse_color(buf,lev+2,off+len, &leng,
493 &result->back_color);
494 len += leng;
495 break;
496 case 0x1c:
497 psiconv_progress(lev+3,off+len,"Going to read font size");
498 result->font_size = psiconv_read_size(buf,lev+3,off+len,&leng);
499 len += leng;
500 break;
501 case 0x1d:
502 psiconv_progress(lev+3,off+len,"Going to read italic");
503 res |= psiconv_parse_bool(buf,lev+3,off+len,&leng,&result->italic);
504 len += leng;
505 break;
506 case 0x1e:
507 psiconv_progress(lev+3,off+len,"Going to read bold");
508 res |= psiconv_parse_bool(buf,lev+3,off+len,&leng,&result->bold);
509 len += leng;
510 break;
511 case 0x1f:
512 psiconv_progress(lev+3,off+len,"Going to read super_sub");
513 temp = psiconv_read_u8(buf,lev+3,off+len);
514 if (temp == 0x00)
515 result->super_sub = psiconv_normalscript;
516 else if (temp == 0x01)
517 result->super_sub = psiconv_superscript;
518 else if (temp == 0x02)
519 result->super_sub = psiconv_subscript;
520 else {
521 psiconv_warn(lev+3,off+len,
522 "Unknown super_sub argument in character layout codes list");
523 res = -1;
524 }
525 psiconv_debug(lev+3,off+len,"Super_sub: %02x",temp);
526 len ++;
527 break;
528 case 0x20:
529 psiconv_progress(lev+3,off+len,"Going to read underline");
530 res |= psiconv_parse_bool(buf,lev+3,off+len,&leng,&result->underline);
531 len += leng;
532 break;
533 case 0x21:
534 psiconv_progress(lev+3,off+len,"Going to read strike_out");
535 res |= psiconv_parse_bool(buf,lev+3,off+len,&leng,&result->strike_out);
536 len += leng;
537 break;
538 case 0x22:
539 psiconv_progress(lev+3,off+len,"Going to read font");
540 psiconv_free_font(result->font);
541 res |= psiconv_parse_font(buf,lev+3,off+len, &leng, &result->font);
542 len += leng;
543 break;
544 default:
545 psiconv_warn(lev+3,off+len,"Unknown code in character layout list");
546 psiconv_debug(lev+3,off+len,"Code: %02x",id);
547 len ++;
548 res = -1;
549 break;
550 }
551 nr ++;
552 }
553
554 if (len - 4 != list_length) {
555 psiconv_warn(lev+2,off+len,
556 "Read past end of character layout codes list. I probably lost track"
557 "somewhere!");
558 psiconv_debug(lev+2,off+len,"Read %d characters instead of %d",
559 len-4,list_length);
560 }
561
562 len = list_length + 4;
563
564 psiconv_progress(lev+1,off+len,
565 "End of character layout list (total length: %08x)",len);
566
567 if (length)
568 *length = len;
569 return res;
570 }

frodo@frodo.looijaard.name
ViewVC Help
Powered by ViewVC 1.1.26