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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 351 - (show annotations)
Wed Oct 22 19:53:40 2014 UTC (5 years, 3 months ago) by frodo
File MIME type: text/plain
File size: 18511 byte(s)
(Frodo) Update copyright year in all source files

1 /*
2 generate_layout.c - Part of psiconv, a PSION 5 file formats converter
3 Copyright (c) 2000-2014 Frodo Looijaard <frodo@frodo.looijaard.name>
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 "compat.h"
22
23 #include <string.h>
24
25 #include "generate_routines.h"
26 #include "error.h"
27
28 #ifdef DMALLOC
29 #include <dmalloc.h>
30 #endif
31
32
33 int psiconv_write_color(const psiconv_config config, psiconv_buffer buf,
34 int lev, const psiconv_color value)
35 {
36 int res;
37
38 psiconv_progress(config,lev,0,"Writing color");
39
40 if (!value) {
41 psiconv_error(config,lev,0,"Null color");
42 res = -PSICONV_E_GENERATE;
43 goto ERROR;
44 }
45 if ((res = psiconv_write_u8(config,buf,lev+1,value->red)))
46 goto ERROR;
47 if ((res = psiconv_write_u8(config,buf,lev+1,value->green)))
48 goto ERROR;
49 if ((res = psiconv_write_u8(config,buf,lev+1,value->blue)))
50 goto ERROR;
51 psiconv_progress(config,lev,0,"End of color");
52 return 0;
53
54 ERROR:
55 psiconv_error(config,lev,0,"Writing of color failed");
56 return res;
57 }
58
59 int psiconv_write_font(const psiconv_config config, psiconv_buffer buf,
60 int lev, const psiconv_font value)
61 {
62 int res,len;
63
64 psiconv_progress(config,lev,0,"Writing font");
65 if (!value) {
66 psiconv_error(config,0,psiconv_buffer_length(buf),"Null font");
67 res = -PSICONV_E_GENERATE;
68 goto ERROR;
69 }
70 len = psiconv_unicode_strlen(value->name);
71 if ((res = psiconv_write_u8(config,buf,lev+1,len+1)))
72 goto ERROR;
73 if ((res = psiconv_write_charlist(config,buf,lev+1,value->name)))
74 goto ERROR;
75 if ((res = psiconv_write_u8(config,buf,lev+1,value->screenfont)))
76 goto ERROR;
77 psiconv_progress(config,lev,0,"End of font");
78 return 0;
79
80 ERROR:
81 psiconv_error(config,lev,0,"Writing of font failed");
82 return res;
83 }
84
85 int psiconv_write_border(const psiconv_config config, psiconv_buffer buf,int lev, const psiconv_border value)
86 {
87 int res;
88
89 psiconv_progress(config,lev,0,"Writing border");
90
91 if (!value) {
92 psiconv_error(config,lev,0,"Null border");
93 res = -PSICONV_E_GENERATE;
94 goto ERROR;
95 }
96 if (value->kind > psiconv_border_dotdotdashed)
97 psiconv_warn(config,lev,0,
98 "Unknown border kind (%d); assuming none",value->kind);
99 if ((res =psiconv_write_u8(config,buf,lev+1,
100 value->kind == psiconv_border_none?0:
101 value->kind == psiconv_border_solid?1:
102 value->kind == psiconv_border_double?2:
103 value->kind == psiconv_border_dotted?3:
104 value->kind == psiconv_border_dashed?4:
105 value->kind == psiconv_border_dotdashed?5:
106 value->kind == psiconv_border_dotdotdashed?6:
107 0)))
108 goto ERROR;
109 if ((res = psiconv_write_size(config,buf,lev+1,
110 (value->kind == psiconv_border_solid) ||
111 (value->kind == psiconv_border_double) ?
112 value->thickness:1.0/20.0)))
113 goto ERROR;
114 if ((res = psiconv_write_color(config,buf,lev+1,value->color)))
115 goto ERROR;
116 /* Unknown byte */
117 if ((res = psiconv_write_u8(config,buf,lev+1,1)))
118 goto ERROR;
119 psiconv_progress(config,lev,0,"End of border");
120 return 0;
121
122 ERROR:
123 psiconv_error(config,lev,0,"Writing of border failed");
124 return res;
125 }
126
127 int psiconv_write_bullet(const psiconv_config config, psiconv_buffer buf,int lev, const psiconv_bullet value)
128 {
129 int res;
130 psiconv_buffer extra_buf;
131
132 psiconv_progress(config,lev,0,"Writing bullet");
133
134 if (!value) {
135 psiconv_error(config,0,psiconv_buffer_length(buf),"Null bullet");
136 res = -PSICONV_E_GENERATE;
137 goto ERROR1;
138 }
139
140 if (!(extra_buf = psiconv_buffer_new())) {
141 psiconv_error(config,lev+1,0,"Out of memory error");
142 res = -PSICONV_E_NOMEM;
143 goto ERROR1;
144 }
145 if ((res = psiconv_write_size(config,extra_buf,lev+1,value->font_size)))
146 goto ERROR2;
147 if ((res = psiconv_unicode_write_char(config,extra_buf,lev+1,
148 value->character)))
149 goto ERROR2;
150 if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->indent)))
151 goto ERROR2;
152 if ((res = psiconv_write_color(config,extra_buf,lev+1,value->color)))
153 goto ERROR2;
154 if ((res = psiconv_write_font(config,extra_buf,lev+1,value->font)))
155 goto ERROR2;
156
157 if ((res = psiconv_write_u8(config,buf,lev+1,psiconv_buffer_length(extra_buf))))
158 goto ERROR2;
159 if ((res = psiconv_buffer_concat(buf,extra_buf))) {
160 psiconv_error(config,lev+1,0,"Out of memory error");
161 goto ERROR2;
162 }
163
164 ERROR2:
165 psiconv_buffer_free(extra_buf);
166 ERROR1:
167 if (res)
168 psiconv_error(config,lev,0,"Writing of bullet failed");
169 else
170 psiconv_progress(config,lev,0,"End of bullet");
171 return res;
172 }
173
174 int psiconv_write_tab(const psiconv_config config, psiconv_buffer buf,int lev, psiconv_tab value)
175 {
176 int res;
177
178 psiconv_progress(config,lev,0,"Writing tab");
179
180 if (!value) {
181 psiconv_error(config,lev,0,"Null tab");
182 res = -PSICONV_E_GENERATE;
183 goto ERROR;
184 }
185 if ((res = psiconv_write_length(config,buf,lev+1,value->location)))
186 goto ERROR;
187 if ((value->kind != psiconv_tab_left) &&
188 (value->kind != psiconv_tab_right) &&
189 (value->kind != psiconv_tab_centre))
190 psiconv_warn(config,lev,0,
191 "Unknown tab kind (%d); assuming left",value->kind);
192 if ((res = psiconv_write_u8(config,buf,lev+1,
193 value->kind == psiconv_tab_right?2:
194 value->kind == psiconv_tab_centre?3:1)))
195 goto ERROR;
196 psiconv_progress(config,lev,0,"End of tab");
197 return 0;
198 ERROR:
199 psiconv_error(config,lev,0,"Writing of tab failed");
200 return res;
201 }
202
203 int psiconv_write_paragraph_layout_list(const psiconv_config config,
204 psiconv_buffer buf,int lev,
205 psiconv_paragraph_layout value,
206 psiconv_paragraph_layout base)
207 {
208 int res,i;
209 psiconv_buffer extra_buf;
210 psiconv_tab tab;
211
212 psiconv_progress(config,lev,0,"Writing paragraph layout list");
213
214 if (!value) {
215 psiconv_error(config,lev,0,"Null paragraph layout list");
216 res = -PSICONV_E_GENERATE;
217 goto ERROR1;
218 }
219 if (!(extra_buf = psiconv_buffer_new())) {
220 res = -PSICONV_E_NOMEM;
221 goto ERROR1;
222 }
223
224 if (!base || psiconv_compare_color(base->back_color,value->back_color)) {
225 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x01)))
226 goto ERROR2;
227 if ((res = psiconv_write_color(config,extra_buf,lev+1,value->back_color)))
228 goto ERROR2;
229 }
230
231 if (!base || (value->indent_left != base->indent_left)) {
232 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x02)))
233 goto ERROR2;
234 if ((res = psiconv_write_length(config,extra_buf,lev+1,value->indent_left)))
235 goto ERROR2;
236 }
237
238 if (!base || (value->indent_right != base->indent_right)) {
239 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x03)))
240 goto ERROR2;
241 if ((res = psiconv_write_length(config,extra_buf,lev+1,value->indent_right)))
242 goto ERROR2;
243 }
244
245 if (!base || (value->indent_first != base->indent_first)) {
246 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x04)))
247 goto ERROR2;
248 if ((res = psiconv_write_length(config,extra_buf,lev+1,value->indent_first)))
249 goto ERROR2;
250 }
251
252 if (!base || (value->justify_hor != base->justify_hor)) {
253 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x05)))
254 goto ERROR2;
255 if ((value->justify_hor < psiconv_justify_left) ||
256 (value->justify_hor > psiconv_justify_full))
257 psiconv_warn(config,lev,0,
258 "Unknown horizontal justify (%d); assuming left",
259 value->justify_hor);
260 if ((res = psiconv_write_u8(config,extra_buf,lev+1,
261 value->justify_hor == psiconv_justify_centre?1:
262 value->justify_hor == psiconv_justify_right?2:
263 value->justify_hor == psiconv_justify_full?3:0)))
264 goto ERROR2;
265 }
266
267 if (!base || (value->justify_ver != base->justify_ver)) {
268 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x06)))
269 goto ERROR2;
270 if ((value->justify_ver < psiconv_justify_top) ||
271 (value->justify_ver > psiconv_justify_bottom))
272 psiconv_warn(config,0,psiconv_buffer_length(buf),
273 "Unknown vertical justify (%d); assuming top",
274 value->justify_ver);
275 if ((res = psiconv_write_u8(config,extra_buf,lev+1,
276 value->justify_ver == psiconv_justify_middle?1:
277 value->justify_ver == psiconv_justify_bottom?2:0)))
278 goto ERROR2;
279 }
280
281 if (!base || (value->linespacing != base->linespacing)) {
282 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x07)))
283 goto ERROR2;
284 if ((res = psiconv_write_size(config,extra_buf,lev+1,value->linespacing)))
285 goto ERROR2;
286 }
287
288 if (!base || (value->linespacing_exact != base->linespacing_exact)) {
289 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x08)))
290 goto ERROR2;
291 if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->linespacing_exact)))
292 goto ERROR2;
293 }
294
295 if (!base || (value->space_above != base->space_above)) {
296 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x09)))
297 goto ERROR2;
298 if ((res = psiconv_write_size(config,extra_buf,lev+1,value->space_above)))
299 goto ERROR2;
300 }
301
302 if (!base || (value->space_below != base->space_below)) {
303 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x0a)))
304 goto ERROR2;
305 if ((res = psiconv_write_size(config,extra_buf,lev+1,value->space_below)))
306 goto ERROR2;
307 }
308
309 if (!base || (value->keep_together != base->keep_together)) {
310 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x0b)))
311 goto ERROR2;
312 if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->keep_together)))
313 goto ERROR2;
314 }
315
316 if (!base || (value->keep_with_next != base->keep_with_next)) {
317 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x0c)))
318 goto ERROR2;
319 if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->keep_with_next)))
320 goto ERROR2;
321 }
322
323 if (!base || (value->on_next_page != base->on_next_page)) {
324 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x0d)))
325 goto ERROR2;
326 if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->on_next_page)))
327 goto ERROR2;
328 }
329
330 if (!base || (value->no_widow_protection != base->no_widow_protection)) {
331 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x0e)))
332 goto ERROR2;
333 if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->no_widow_protection)))
334 goto ERROR2;
335 }
336
337 if (!base || (value->wrap_to_fit_cell != base->wrap_to_fit_cell)) {
338 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x0f)))
339 goto ERROR2;
340 if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->wrap_to_fit_cell)))
341 goto ERROR2;
342 }
343
344 if (!base || (value->border_distance != base->border_distance)) {
345 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x10)))
346 goto ERROR2;
347 if ((res = psiconv_write_length(config,extra_buf,lev+1,value->border_distance)))
348 goto ERROR2;
349 }
350
351 if (!base || psiconv_compare_border(value->top_border,base->top_border)) {
352 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x11)))
353 goto ERROR2;
354 if ((res = psiconv_write_border(config,extra_buf,lev+1,value->top_border)))
355 goto ERROR2;
356 }
357
358 if (!base || psiconv_compare_border(value->bottom_border,
359 base->bottom_border)) {
360 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x12)))
361 goto ERROR2;
362 if ((res = psiconv_write_border(config,extra_buf,lev+1,value->bottom_border)))
363 goto ERROR2;
364 }
365
366 if (!base || psiconv_compare_border(value->left_border,
367 base->left_border)) {
368 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x13)))
369 goto ERROR2;
370 if ((res = psiconv_write_border(config,extra_buf,lev+1,value->left_border)))
371 goto ERROR2;
372 }
373
374 if (!base || psiconv_compare_border(value->right_border,
375 base->right_border)) {
376 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x14)))
377 goto ERROR2;
378 if ((res = psiconv_write_border(config,extra_buf,lev+1,value->right_border)))
379 goto ERROR2;
380 }
381
382 if (!base || psiconv_compare_bullet(value->bullet,
383 base->bullet)) {
384 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x15)))
385 goto ERROR2;
386 if ((res = psiconv_write_bullet(config,extra_buf,lev+1,value->bullet)))
387 goto ERROR2;
388 }
389
390 if (!value->tabs || !value->tabs->extras) {
391 psiconv_error(config,0,psiconv_buffer_length(buf),"Null tabs");
392 res = -PSICONV_E_GENERATE;
393 goto ERROR2;
394 }
395
396 /* It is not entirely clear how tabs are inherited. For now, I assume
397 if there is any difference at all, we will have to generate both
398 the normal tab-interval, and all specific tabs */
399 if (!base || psiconv_compare_all_tabs(value->tabs,base->tabs)) {
400 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x16)))
401 goto ERROR2;
402 if ((res = psiconv_write_length(config,extra_buf,lev+1,value->tabs->normal)))
403 goto ERROR2;
404 for (i = 0; i < psiconv_list_length(value->tabs->extras); i++) {
405 if (!(tab = psiconv_list_get(value->tabs->extras,i))) {
406 psiconv_error(config,lev+1,0,"Data structure corruption");
407 res = -PSICONV_E_NOMEM;
408 goto ERROR2;
409 }
410 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x17)))
411 goto ERROR2;
412 if ((res = psiconv_write_tab(config,extra_buf,lev+1,tab)))
413 goto ERROR2;
414 }
415 }
416
417 if ((res = psiconv_write_u32(config,buf,lev+1,psiconv_buffer_length(extra_buf))))
418 goto ERROR2;
419
420 if ((res = psiconv_buffer_concat(buf,extra_buf))) {
421 psiconv_error(config,lev+1,0,"Out of memory error");
422 goto ERROR2;
423 }
424
425 ERROR2:
426 psiconv_buffer_free(extra_buf);
427 ERROR1:
428 if (res)
429 psiconv_error(config,lev,0,"Writing of paragraph layout list failed");
430 else
431 psiconv_progress(config,lev,0,"End of paragraph layout list");
432 return res;
433 }
434
435 int psiconv_write_character_layout_list(const psiconv_config config,
436 psiconv_buffer buf,int lev,
437 psiconv_character_layout value,
438 psiconv_character_layout base)
439 {
440 int res;
441 psiconv_buffer extra_buf;
442
443 psiconv_progress(config,lev,0,"Writing character layout list");
444
445 if (!value) {
446 psiconv_error(config,lev,0,"Null character layout list");
447 res = -PSICONV_E_GENERATE;
448 goto ERROR1;
449 }
450 if (!(extra_buf = psiconv_buffer_new())) {
451 res = -PSICONV_E_NOMEM;
452 goto ERROR1;
453 }
454
455 if (!base || psiconv_compare_color(base->color,value->color)) {
456 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x19)))
457 goto ERROR2;
458 if ((res = psiconv_write_color(config,extra_buf,lev+1,value->color)))
459 goto ERROR2;
460 }
461
462 if (!base || psiconv_compare_color(base->back_color,value->back_color)) {
463 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x1a)))
464 goto ERROR2;
465 if ((res = psiconv_write_color(config,extra_buf,lev+1,value->back_color)))
466 goto ERROR2;
467 }
468
469 if (!base || (value->font_size != base->font_size)) {
470 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x1c)))
471 goto ERROR2;
472 if ((res = psiconv_write_size(config,extra_buf,lev+1,value->font_size)))
473 goto ERROR2;
474 }
475
476 if (!base || (value->italic != base->italic)) {
477 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x1d)))
478 goto ERROR2;
479 if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->italic)))
480 goto ERROR2;
481 }
482
483 if (!base || (value->bold != base->bold)) {
484 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x1e)))
485 goto ERROR2;
486 if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->bold)))
487 goto ERROR2;
488 }
489
490 if (!base || (value->super_sub != base->super_sub)) {
491 if ((value->super_sub != psiconv_superscript) &&
492 (value->super_sub != psiconv_subscript) &&
493 (value->super_sub != psiconv_normalscript))
494 psiconv_warn(config,lev,0,"Unknown supersubscript (%d); assuming normal",
495 value->super_sub);
496 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x1f)))
497 goto ERROR2;
498 if ((res = psiconv_write_u8(config,extra_buf,lev+1,
499 value->super_sub == psiconv_superscript?1:
500 value->super_sub == psiconv_subscript?2:0)))
501 goto ERROR2;
502 }
503
504 if (!base || (value->underline != base->underline)) {
505 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x20)))
506 goto ERROR2;
507 if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->underline)))
508 goto ERROR2;
509 }
510
511 if (!base || (value->strikethrough != base->strikethrough)) {
512 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x21)))
513 goto ERROR2;
514 if ((res = psiconv_write_bool(config,extra_buf,lev+1,value->strikethrough)))
515 goto ERROR2;
516 }
517
518 if (!base || psiconv_compare_font(base->font,value->font)) {
519 if ((res = psiconv_write_u8(config,extra_buf,lev+1,0x22)))
520 goto ERROR2;
521 if ((res = psiconv_write_font(config,extra_buf,lev+1,value->font)))
522 goto ERROR2;
523 }
524
525 if ((res = psiconv_write_u32(config,buf,lev+1,psiconv_buffer_length(extra_buf))))
526 goto ERROR2;
527
528 res = psiconv_buffer_concat(buf,extra_buf);
529
530 ERROR2:
531 psiconv_buffer_free(extra_buf);
532 ERROR1:
533 if (res)
534 psiconv_error(config,lev,0,"Writing of character layout list failed");
535 else
536 psiconv_progress(config,lev,0,"End of character layout list");
537 return res;
538 }

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