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

Annotation of /psiconv/trunk/lib/psiconv/gen_rtf.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9 - (hide annotations)
Tue Oct 5 15:33:38 1999 UTC (24 years, 6 months ago) by frodo
File MIME type: text/plain
File size: 17157 byte(s)
(Frodo) Perhaps even slightly functional RTF generator

Most stubs are in, and it should even do something. The generated code is
not validated yet, so it will probably not work. Still many things to do.

1 frodo 5 /*
2     * gen_rtf.c - Part of psiconv, a PSION 5 file formats converter
3     * Copyright (c) 1999 Andrew Johnson <anjohnson@iee.org>
4     * Portions Copyright (c) 1999 Frodo Looijaard <frodol@dds.nl>
5     *
6     * This program is free software; you can redistribute it and/or modify
7     * it under the terms of the GNU General Public License as published by
8     * the Free Software Foundation; either version 2 of the License, or
9     * (at your option) any later version.
10     *
11     * This program is distributed in the hope that it will be useful,
12     * but WITHOUT ANY WARRANTY; without even the implied warranty of
13     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     * GNU General Public License for more details.
15     *
16     * You should have received a copy of the GNU General Public License
17     * along with this program; if not, write to the Free Software
18     * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19     */
20    
21     #include "config.h"
22     #include <stdio.h>
23     #include <string.h>
24     #include "data.h"
25     #include "list.h"
26     #include "gen.h"
27    
28    
29     /*
30     * Various string tables for RTF settings
31     */
32    
33     /* Character conversion table */
34     /* TO BE ADJUSTED FOR RTF! */
35     static const char *char_table[0x100] = {
36     /* 0x00 */ "", "", "", "", "", "", "\n", "\n",
37     /* 0x08 */ "\n", "\t", "", "", "", "", "", "",
38     /* 0x10 */ " ", "", "", "", "", "", "", "",
39     /* 0x18 */ "", "", "", "", "", "", "", "",
40     /* 0x20 */ " ", "!", "\"", "#", "$", "%", "&", "'",
41     /* 0x28 */ "(", ")", "*", "+", ",", "-", ".", "/",
42     /* 0x30 */ "0", "1", "2", "3", "4", "5", "6", "7",
43     /* 0x38 */ "8", "9", ":", ";", "<", "=", ">", "?",
44     /* 0x40 */ "@", "A", "B", "C", "D", "E", "F", "G",
45     /* 0x48 */ "H", "I", "J", "K", "L", "M", "N", "O",
46     /* 0x50 */ "P", "Q", "R", "S", "T", "U", "V", "W",
47     /* 0x58 */ "X", "Y", "Z", "[", "\\", "]", "^", "_",
48     /* 0x60 */ "`", "a", "b", "c", "d", "e", "f", "g",
49     /* 0x68 */ "h", "i", "j", "k", "l", "m", "n", "o",
50     /* 0x70 */ "p", "q", "r", "s", "t", "u", "v", "w",
51     /* 0x78 */ "x", "y", "z", "{", "|", "}", "~", "",
52     /* 0x80 */ "", "", ",", "f", ",,", "...", "+", "#",
53     /* 0x88 */ "^", "\176/oo","S", "<", "OE", "", "", "",
54     /* 0x90 */ "", "`", "'", "``", "''", "*", "-", "--",
55     /* 0x98 */ "~", "(TM)", "s", ">", "oe", "", "", "Y",
56     /* 0xa0 */ "\xa0", "\xa1", "\xa2", "\xa3", "\xa4", "\xa5", "\xa6", "\xa7",
57     /* 0xa8 */ "\xa8", "\xa9", "\xaa", "\xab", "\xac", "\xad", "\xae", "\xaf",
58     /* 0xb0 */ "\xb0", "\xb1", "\xb2", "\xb3", "\xb4", "\xb5", "\xb6", "\xb7",
59     /* 0xb8 */ "\xb8", "\xb9", "\xba", "\xbb", "\xbc", "\xbd", "\xbe", "\xbf",
60     /* 0xc0 */ "\xc0", "\xc1", "\xc2", "\xc3", "\xc4", "\xc5", "\xc6", "\xc7",
61     /* 0xc8 */ "\xc8", "\xc9", "\xca", "\xcb", "\xcc", "\xcd", "\xce", "\xcf",
62     /* 0xd0 */ "\xd0", "\xd1", "\xd2", "\xd3", "\xd4", "\xd5", "\xd6", "\xd7",
63     /* 0xd8 */ "\xd8", "\xd9", "\xda", "\xdb", "\xdc", "\xdd", "\xde", "\xdf",
64     /* 0xe0 */ "\xe0", "\xe1", "\xe2", "\xe3", "\xe4", "\xe5", "\xe6", "\xe7",
65     /* 0xe8 */ "\xe8", "\xe9", "\xea", "\xeb", "\xec", "\xed", "\xee", "\xef",
66     /* 0xf0 */ "\xf0", "\xf1", "\xf2", "\xf3", "\xf4", "\xf5", "\xf6", "\xf7",
67     /* 0xf8 */ "\xf8", "\xf9", "\xfa", "\xfb", "\xfc", "\xfd", "\xfe", "\xff",
68     };
69    
70    
71 frodo 9
72 frodo 5 static void fput_text(FILE * of, const char *text, int length) {
73     int j;
74    
75     for (j = 0; j < length; j++) {
76     fputs(char_table[(unsigned char) (text[j])], of);
77     }
78     }
79    
80 frodo 9 static int length_to_twips(psiconv_length_t len)
81 frodo 5 {
82 frodo 9 return 1440.0 / 2.54 * len;
83     }
84    
85     static int lookup_color(psiconv_list colors,psiconv_color color)
86     {
87 frodo 6 int i;
88     psiconv_color comp;
89 frodo 9 for (i = 0; i < psiconv_list_length(colors); i ++) {
90     comp = * (psiconv_color *) psiconv_list_get(colors,i);
91     if ((comp->red == color->red) && (comp->green == color->green) &&
92     (comp->blue == color->blue))
93     return i;
94 frodo 6 }
95 frodo 9 return -1;
96 frodo 5 }
97    
98 frodo 9 static void add_color(psiconv_list colors, psiconv_color color)
99 frodo 6 {
100 frodo 9 if (color)
101     if (lookup_color(colors,color) < 0)
102     psiconv_list_add(colors,&color);
103     }
104    
105     static int lookup_font(psiconv_list fonts,psiconv_font font)
106     {
107 frodo 6 int i;
108     psiconv_font comp;
109 frodo 9 for (i = 0; i < psiconv_list_length(fonts); i ++) {
110     comp = *(psiconv_font *) psiconv_list_get(fonts,i);
111     if ((comp->screenfont == font->screenfont) &&
112     ! strcmp(comp->name,font->name))
113     return i;
114 frodo 6 }
115 frodo 9 return -1;
116 frodo 6 }
117    
118 frodo 9 static void add_font(psiconv_list fonts, psiconv_font font)
119     {
120     if (font)
121     if (lookup_font(fonts,font) < 0)
122     psiconv_list_add(fonts,&font);
123     }
124    
125 frodo 6 static void scan_border(psiconv_list colors,psiconv_list fonts,
126     psiconv_border sec)
127     {
128     if (sec) {
129     add_color(colors,sec->color);
130     }
131     }
132    
133     static void scan_bullet(psiconv_list colors,psiconv_list fonts,
134     psiconv_bullet sec)
135     {
136     if (sec) {
137     add_color(colors,sec->color);
138     add_font(fonts,sec->font);
139     }
140     }
141    
142     static void scan_paragraph_layout(psiconv_list colors,psiconv_list fonts,
143     psiconv_paragraph_layout sec)
144     {
145     if (sec) {
146     add_color(colors,sec->back_color);
147     scan_bullet(colors,fonts,sec->bullet);
148     scan_border(colors,fonts,sec->left_border);
149     scan_border(colors,fonts,sec->right_border);
150     scan_border(colors,fonts,sec->top_border);
151     scan_border(colors,fonts,sec->bottom_border);
152     }
153     }
154    
155     static void scan_character_layout(psiconv_list colors,psiconv_list fonts,
156     psiconv_character_layout sec)
157     {
158     if (sec) {
159     add_color(colors,sec->color);
160     add_color(colors,sec->back_color);
161     add_font(fonts,sec->font);
162     }
163     }
164    
165     static void scan_in_line_layout(psiconv_list colors,psiconv_list fonts,
166     psiconv_in_line_layout sec)
167     {
168     if (sec) {
169     scan_character_layout(colors,fonts,sec->layout);
170     }
171     }
172    
173     static void scan_in_line_layouts(psiconv_list colors,psiconv_list fonts,
174     psiconv_in_line_layouts sec)
175     {
176     int i;
177     psiconv_in_line_layout layout;
178     if (sec) {
179     for (i = 0; i < psiconv_list_length(sec); i++) {
180     layout = psiconv_list_get(sec,i);
181     scan_in_line_layout(colors,fonts,layout);
182     }
183     }
184     }
185    
186     static void scan_paragraph(psiconv_list colors,psiconv_list fonts,
187     psiconv_paragraph sec)
188     {
189     if (sec) {
190     scan_paragraph_layout(colors,fonts,sec->base_paragraph);
191     scan_character_layout(colors,fonts,sec->base_character);
192     scan_in_line_layouts(colors,fonts,sec->in_lines);
193     }
194     }
195    
196     static void scan_text_and_layout(psiconv_list colors,psiconv_list fonts,
197     psiconv_text_and_layout sec)
198     {
199     int i;
200     psiconv_paragraph para;
201     if (sec) {
202     for (i = 0; i < psiconv_list_length(sec); i++) {
203     para = psiconv_list_get(sec,i);
204     scan_paragraph(colors,fonts,para);
205     }
206     }
207     }
208    
209     static void scan_texted_section(psiconv_list colors,psiconv_list fonts,
210     psiconv_texted_section sec)
211     {
212     if (sec) {
213     scan_text_and_layout(colors,fonts,sec->paragraphs);
214     }
215     }
216    
217     static void scan_page_header(psiconv_list colors,psiconv_list fonts,
218     psiconv_page_header sec)
219     {
220     if (sec) {
221     scan_paragraph_layout(colors,fonts,sec->base_paragraph_layout);
222     scan_character_layout(colors,fonts,sec->base_character_layout);
223     scan_texted_section(colors,fonts,sec->text);
224     }
225     }
226    
227     static void scan_page_layout_section(psiconv_list colors,psiconv_list fonts,
228     psiconv_page_layout_section sec)
229     {
230     if (sec) {
231     scan_page_header(colors,fonts,sec->header);
232     scan_page_header(colors,fonts,sec->footer);
233     }
234     }
235    
236     static void scan_word_style(psiconv_list colors,psiconv_list fonts,
237     psiconv_word_style sec)
238     {
239     if (sec) {
240     scan_character_layout(colors,fonts,sec->character);
241     scan_paragraph_layout(colors,fonts,sec->paragraph);
242     }
243     }
244    
245     static void scan_word_style_list(psiconv_list colors,psiconv_list fonts,
246     psiconv_word_style_list sec)
247     {
248     int i;
249     psiconv_word_style style;
250     if (sec) {
251     for (i = 0; i < psiconv_list_length(sec); i++) {
252     style = psiconv_list_get(sec,i);
253     scan_word_style(colors,fonts,style);
254     }
255     }
256     }
257    
258     static void scan_word_styles_section(psiconv_list colors,psiconv_list fonts,
259     psiconv_word_styles_section sec)
260     {
261     if (sec) {
262     scan_word_style(colors,fonts,sec->normal);
263     scan_word_style_list(colors,fonts,sec->styles);
264     }
265     }
266    
267    
268     static void scan_word_f(psiconv_list colors,psiconv_list fonts,
269     psiconv_word_f sec)
270     {
271     if (sec) {
272     scan_page_layout_section(colors,fonts,sec->page_sec);
273     scan_text_and_layout(colors,fonts,sec->paragraphs);
274     scan_word_styles_section(colors,fonts,sec->styles_sec);
275     }
276     }
277    
278     static void scan_texted_f(psiconv_list colors,psiconv_list fonts,
279     psiconv_texted_f sec)
280     {
281     if (sec) {
282     scan_page_layout_section(colors,fonts,sec->page_sec);
283     scan_texted_section(colors,fonts,sec->texted_sec);
284     }
285     }
286    
287 frodo 9 static void gen_font_table(FILE *of,psiconv_list fonts)
288 frodo 6 {
289     int i;
290     psiconv_font *font;
291    
292     fprintf(of,"{\\fonttbl");
293     for (i = 0; i < psiconv_list_length(fonts); i++) {
294     font = psiconv_list_get(fonts,i);
295     fprintf(of,"{\\f%d",i);
296     if ((*font)->screenfont == 1)
297     fprintf(of,"\\fswiss");
298     else if ((*font)->screenfont == 2)
299     fprintf(of,"\\fmodern");
300     else if ((*font)->screenfont == 3)
301     fprintf(of,"\\froman");
302     else
303     fprintf(of,"\\fnil");
304     fprintf(of,"\\cpg1252\\f%s;}",(*font)->name);
305     }
306     fprintf(of,"}\n");
307     }
308    
309 frodo 9 static void gen_color_table(FILE *of, psiconv_list colors)
310 frodo 6 {
311     int i;
312     psiconv_color *color;
313    
314     fprintf(of,"{\\colortbl");
315     for (i = 0; i < psiconv_list_length(colors); i++) {
316     color = psiconv_list_get(colors,i);
317     fprintf(of,"\\red%d\\green%d\\blue%d;",(*color)->red,
318     (*color)->green, (*color)->blue);
319     }
320     fprintf(of,"}\n");
321     }
322    
323 frodo 9 /* This is not necessarily the same as returned by basic_character_layout_status
324     This one is specific for the base point of RTF */
325     static psiconv_character_layout
326     gen_base_char(psiconv_list colors, psiconv_list fonts)
327     {
328     struct psiconv_color white = { 0,0,0 };
329     struct psiconv_color black = { 0xff,0xff,0xff };
330     struct psiconv_font font = { strdup(""),-1 }; /* Pseudo - not added! */
331    
332     struct psiconv_character_layout base_char_struct =
333     {
334     &black, /* color */
335     &white, /* back_color */
336     13.0, /* font_size */
337     psiconv_bool_false, /* italic */
338     psiconv_bool_false, /* bold */
339     psiconv_normalscript, /* super_sub */
340     psiconv_bool_false, /* underline */
341     psiconv_bool_false, /* strike_out */
342     &font, /* font */
343     };
344    
345     add_color(colors,&white);
346     add_color(colors,&black);
347    
348     return psiconv_clone_character_layout(&base_char_struct);
349     }
350    
351     void diff_char(FILE *of,psiconv_list colors, psiconv_list fonts,
352     const psiconv_character_layout old,
353     const psiconv_character_layout new)
354     {
355     if ((old->font->screenfont != new->font->screenfont) ||
356     strcmp(old->font->name,new->font->name))
357     fprintf(of,"\\f%d",lookup_font(fonts,new->font));
358     if (old->font_size != new->font_size)
359     fprintf(of,"\\fs%d",(int) (new->font_size * 2));
360     if (old->super_sub != new->super_sub) {
361     if (new->super_sub == psiconv_normalscript)
362     fprintf(of,"\\nosupersub");
363     else if (new->super_sub == psiconv_superscript)
364     fprintf(of,"\\super");
365     else if (new->super_sub == psiconv_subscript)
366     fprintf(of,"\\sub");
367     }
368     if (old->bold != new->bold)
369     fprintf(of,"\\b%s",new->bold?"":"0");
370     if (old->italic != new->italic)
371     fprintf(of,"\\i%s",new->italic?"":"0");
372     if (old->underline != new->underline)
373     fprintf(of,"\\ul%s",new->underline?"":"0");
374     if (old->strike_out != new->strike_out)
375     fprintf(of,"\\strike%s",new->strike_out?"":"0");
376     if ((old->color->red != new->color->red) ||
377     (old->color->green != new->color->green) ||
378     (old->color->blue != new->color->blue))
379     fprintf(of,"\\cf%d",lookup_color(colors,new->color));
380     if ((old->back_color->red != new->back_color->red) ||
381     (old->back_color->green != new->back_color->green) ||
382     (old->back_color->blue != new->back_color->blue))
383     fprintf(of,"\\cb%d",lookup_color(colors,new->back_color));
384     }
385    
386    
387     /* Note: this generates also some character formatting; Psion Word and
388     RTF do not agree on what is paragraph-level formatting and what is
389     character-level formatting. The character-level formatting is put
390     at the end. This should work out. */
391     static void gen_paragraph_codes(FILE *of, psiconv_list colors,
392     psiconv_list fonts,
393     psiconv_paragraph_layout para)
394     {
395     if (para->indent_first != 0.0)
396     fprintf(of,"\\fl%d",length_to_twips( para->indent_first));
397     if (para->indent_left != 0.0)
398     fprintf(of,"\\ll%d",length_to_twips(para->indent_left));
399     if (para->indent_right != 0.0)
400     fprintf(of,"\\rl%d",length_to_twips(para->indent_right));
401     if (para->justify_hor != psiconv_justify_left) {
402     if (para->justify_hor == psiconv_justify_right)
403     fprintf(of,"\\qr");
404     else if (para->justify_hor == psiconv_justify_centre)
405     fprintf(of,"\\qc");
406     else if (para->justify_hor == psiconv_justify_full)
407     fprintf(of,"\\qj");
408     /*
409     else if (para->justify_hor == psiconv_justify_left)
410     fprintf(of,"\\ql");
411     */
412     }
413     if (para->interline != 0.0)
414     fprintf(of,"\\sl%d",(para->interline_exact?-1:1) *
415     length_to_twips(para->interline));
416     if (para->top_space != 0.0)
417     fprintf(of,"\\sb%d",length_to_twips(para->top_space));
418     if (para->bottom_space != 0.0)
419     fprintf(of,"\\sa%d",length_to_twips(para->bottom_space));
420     if (para->on_one_page)
421     fprintf(of,"\\keep");
422     if (para->together_with)
423     fprintf(of,"\\keepn");
424     if (!para->on_next_page)
425     fprintf(of,"pagebb");
426     if (!para->no_widow_protection)
427     fprintf(of,"\\nowidctlpar");
428     }
429    
430    
431     static void gen_para(FILE *of, psiconv_list colors, psiconv_list fonts,
432     psiconv_paragraph para)
433     {
434     psiconv_character_layout cur_char,base_char;
435     psiconv_in_line_layout inl;
436     int loc,i,j;
437    
438     fprintf(of,"\\par\\pard");
439     gen_paragraph_codes(of,colors,fonts,para->base_paragraph);
440    
441     base_char = gen_base_char(colors,fonts);
442     cur_char = base_char;
443    
444     if (psiconv_list_length(para->in_lines) == 0) {
445     diff_char(of,colors,fonts,cur_char,para->base_character);
446     cur_char = para->base_character;
447     }
448     loc = 0;
449    
450     for (i = 0; i < psiconv_list_length(para->in_lines); i++) {
451     inl = psiconv_list_get(para->in_lines,i);
452     diff_char(of,colors,fonts,cur_char,inl->layout);
453     cur_char = inl->layout;
454     for (j = loc; j < inl->length + loc; j ++) {
455     fputs(char_table[(unsigned char) (para->text[j])],of);
456     }
457     loc = j;
458     }
459    
460     if (loc < strlen(para->text)) {
461     diff_char(of,colors,fonts,cur_char,para->base_character);
462     cur_char = para->base_character;
463     for (j = loc; j < strlen(para->text); j ++) {
464     fputs(char_table[(unsigned char) (para->text[j])],of);
465     }
466     }
467    
468     psiconv_free_character_layout(base_char);
469     }
470    
471     static void gen_text(FILE *of, psiconv_list colors, psiconv_list fonts,
472     psiconv_text_and_layout paragraphs)
473     {
474     int i;
475     psiconv_paragraph para;
476     fprintf(of,"\\sect");
477     for (i = 0; i < psiconv_list_length(paragraphs); i++) {
478     para = psiconv_list_get(paragraphs,i);
479     gen_para(of,colors,fonts,para);
480     }
481     }
482    
483 frodo 6 static void psiconv_gen_rtf_word(FILE * of, psiconv_word_f wf)
484     {
485     psiconv_list fonts;
486     psiconv_list colors;
487    
488     fonts = psiconv_list_new(sizeof(psiconv_font));
489     colors = psiconv_list_new(sizeof(psiconv_color));
490     scan_word_f(colors,fonts,wf);
491    
492     fputs("{\\rtf1\\ansi\n",of);
493     gen_font_table(of,fonts);
494     gen_color_table(of,colors);
495 frodo 9 gen_text(of,colors,fonts,wf->paragraphs);
496 frodo 6 fputs("}\n",of);
497    
498     psiconv_list_free(fonts);
499     psiconv_list_free(colors);
500    
501     }
502    
503 frodo 5 static void psiconv_gen_rtf_texted(FILE * of, psiconv_texted_f tf)
504     {
505 frodo 6 psiconv_list fonts;
506     psiconv_list colors;
507    
508     fonts = psiconv_list_new(sizeof(psiconv_font));
509     colors = psiconv_list_new(sizeof(psiconv_color));
510     scan_texted_f(colors,fonts,tf);
511    
512     fputs("{\\rtf1\\ansi\n",of);
513     gen_font_table(of,fonts);
514     gen_color_table(of,colors);
515 frodo 9 gen_text(of,colors,fonts,tf->texted_sec->paragraphs);
516 frodo 6 fputs("}\n",of);
517    
518     psiconv_list_free(fonts);
519     psiconv_list_free(colors);
520 frodo 5 }
521    
522     void psiconv_gen_rtf(FILE * of, psiconv_file file)
523     {
524     if (file->type == psiconv_word_file)
525     psiconv_gen_rtf_word(of,(psiconv_word_f) file->file);
526     else if (file->type == psiconv_texted_file)
527     psiconv_gen_rtf_texted(of,(psiconv_texted_f) file->file);
528     else
529     return;
530     }
531    

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