fixed return value of setparameter
[swftools.git] / lib / devices / text.c
1 /* text.c
2
3    Part of the swftools package.
4
5    Copyright (c) 2006 Matthias Kramm <kramm@quiss.org> 
6  
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
20
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <stdarg.h>
24 #include <unistd.h>
25 #include <memory.h>
26 #include "../types.h"
27 #include "../mem.h"
28 #include "../gfxdevice.h"
29 #include "../gfxtools.h"
30 #include "../utf8.h"
31
32 typedef struct _textpage {
33     char*text;
34     int textsize;
35     int textpos;
36     struct _textpage*next;
37 } textpage_t;
38
39 typedef struct _internal {
40     textpage_t*first_page;
41     textpage_t*current_page;
42 } internal_t;
43
44 int text_setparameter(gfxdevice_t*dev, const char*key, const char*value)
45 {
46     internal_t*i = (internal_t*)dev->internal;
47     return 0;
48 }
49 void text_startpage(gfxdevice_t*dev, int width, int height)
50 {
51     internal_t*i = (internal_t*)dev->internal;
52     if(i->first_page) {
53         i->first_page = i->current_page = (textpage_t*)malloc(sizeof(textpage_t));
54     } else {
55         i->current_page->next = (textpage_t*)malloc(sizeof(textpage_t));
56         i->current_page = i->current_page->next;
57     }
58     i->current_page->textsize = 4096;
59     i->current_page->text = malloc(i->current_page->textsize);
60 }
61 void text_startclip(gfxdevice_t*dev, gfxline_t*line)
62 {
63     internal_t*i = (internal_t*)dev->internal;
64 }
65 void text_endclip(gfxdevice_t*dev)
66 {
67     internal_t*i = (internal_t*)dev->internal;
68 }
69 void text_stroke(gfxdevice_t*dev, gfxline_t*line, gfxcoord_t width, gfxcolor_t*color, gfx_capType cap_style, gfx_joinType joint_style, gfxcoord_t miterLimit)
70 {
71     internal_t*i = (internal_t*)dev->internal;
72 }
73 void text_fill(gfxdevice_t*dev, gfxline_t*line, gfxcolor_t*color)
74 {
75     internal_t*i = (internal_t*)dev->internal;
76 }
77 void text_fillbitmap(gfxdevice_t*dev, gfxline_t*line, gfximage_t*img, gfxmatrix_t*matrix, gfxcxform_t*cxform)
78 {
79     internal_t*i = (internal_t*)dev->internal;
80 }
81 void text_fillgradient(gfxdevice_t*dev, gfxline_t*line, gfxgradient_t*gradient, gfxgradienttype_t type, gfxmatrix_t*matrix)
82 {
83     internal_t*i = (internal_t*)dev->internal;
84 }
85 void text_addfont(gfxdevice_t*dev, gfxfont_t*font) {}
86 void text_drawchar(gfxdevice_t*dev, gfxfont_t*font, int glyphnr, gfxcolor_t*color, gfxmatrix_t*matrix)
87 {
88     internal_t*i = (internal_t*)dev->internal;
89
90     if(i->current_page->textpos + 10 > i->current_page->textsize) {
91         i->current_page->textsize += 4096;
92         i->current_page->text = realloc(i->current_page->text, i->current_page->textsize);
93     }
94
95     gfxglyph_t*glyph = &font->glyphs[glyphnr];
96     writeUTF8(glyph->unicode, &i->current_page->text[i->current_page->textpos]);
97     i->current_page->textpos += strlen(&i->current_page->text[i->current_page->textpos]);
98     return;
99 }
100
101 void text_drawlink(gfxdevice_t*dev, gfxline_t*line, char*action)
102 {
103     internal_t*i = (internal_t*)dev->internal;
104 }
105
106 void text_endpage(gfxdevice_t*dev)
107 {
108     internal_t*i = (internal_t*)dev->internal;
109 }
110
111 void text_result_write(gfxresult_t*r, int filedesc)
112 {
113     textpage_t*i= (textpage_t*)r->internal;
114 }
115 int text_result_save(gfxresult_t*r, char*filename)
116 {
117     textpage_t*i= (textpage_t*)r->internal;
118     if(!i) {
119         return 0; // no pages drawn
120     }
121     FILE*fi = fopen(filename, "wb");
122     if(!fi)
123         return 0;
124     while(i) {
125         fwrite(i->text, i->textpos, 1, fi);
126         i = i->next;
127     }
128     fclose(fi);
129     return 1;
130 }
131 void*text_result_get(gfxresult_t*r, char*name)
132 {
133     textpage_t*i= (textpage_t*)r->internal;
134     if(!strcmp(name,"text")) {
135         textpage_t*j = i;
136         int len = 0;
137         while(j) {
138             len += i->textpos;
139             j = j->next;
140         }
141         char*text = malloc(len);
142         int pos = 0;
143         j = i;
144         while(j) {
145             memcpy(&text[pos], i->text, i->textpos);
146             pos += i->textpos;
147             j = j->next;
148         }
149         text[pos] = 0;
150         return text;
151     } else if(!strncmp(name,"page",4)) {
152         int pagenr = atoi(&name[4]);
153         if(pagenr<0)
154             pagenr=0;
155         while(pagenr>0) {
156             i = i->next;
157             if(!i)
158                 return 0;
159         }
160         i->text[i->textpos] = 0;
161         return strdup(i->text);
162     }
163     return 0;
164 }
165 void text_result_destroy(gfxresult_t*r)
166 {
167     textpage_t*i= (textpage_t*)r->internal;
168     r->internal = 0;
169     while(i) {
170         textpage_t*next = i->next;
171         free(i->text);i->text = 0;
172         free(i);
173         i = next;
174     }
175     free(r);
176 }
177
178 gfxresult_t* text_finish(struct _gfxdevice*dev)
179 {
180     internal_t*i = (internal_t*)dev->internal;
181     
182     gfxresult_t* res = (gfxresult_t*)rfx_calloc(sizeof(gfxresult_t));
183     
184     res->internal = i->first_page;i->first_page = 0;i->current_page=0;
185     res->write = text_result_write;
186     res->save = text_result_save;
187     res->get = text_result_get;
188     res->destroy = text_result_destroy;
189
190     free(dev->internal); dev->internal = 0; i = 0;
191
192     return res;
193 }
194
195
196
197 void gfxdevice_text_init(gfxdevice_t*dev, gfxdevice_t*out)
198 {
199     internal_t*i = (internal_t*)rfx_calloc(sizeof(internal_t));
200     memset(dev, 0, sizeof(gfxdevice_t));
201
202     dev->name = "text";
203
204     dev->internal = i;
205
206     dev->setparameter = text_setparameter;
207     dev->startpage = text_startpage;
208     dev->startclip = text_startclip;
209     dev->endclip = text_endclip;
210     dev->stroke = text_stroke;
211     dev->fill = text_fill;
212     dev->fillbitmap = text_fillbitmap;
213     dev->fillgradient = text_fillgradient;
214     dev->addfont = text_addfont;
215     dev->drawchar = text_drawchar;
216     dev->drawlink = text_drawlink;
217     dev->endpage = text_endpage;
218     dev->finish = text_finish;
219 }
220