give a name to each link
[swftools.git] / lib / devices / file.c
1 /* gfxdevice_file.cc
2
3    Part of the swftools package.
4
5    Copyright (c) 2005 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 #ifndef WIN32
24 #include <unistd.h>
25 #endif
26 #include <string.h>
27 #include <memory.h>
28 #include "../gfxdevice.h"
29
30 typedef struct _internal {
31     char*filename;
32     FILE*fi;
33 } internal_t;
34
35 int file_setparameter(struct _gfxdevice*dev, const char*key, const char*value)
36 {
37     internal_t*i = (internal_t*)dev->internal;
38     fprintf(i->fi, "setparameter %s=%s\n", key, value);
39     return 1;
40 }
41
42 void file_startpage(struct _gfxdevice*dev, int width, int height)
43 {
44     internal_t*i = (internal_t*)dev->internal;
45     fprintf(i->fi, "startpage %d %d\n", width, height);
46 }
47
48 static void dumpline(FILE*fi, gfxline_t*line)
49 {
50     while(line) {
51         if(line->type == gfx_moveTo) {
52             fprintf(fi, "\tmoveTo %f %f\n", line->x, line->y);
53         } else if(line->type == gfx_lineTo) {
54             fprintf(fi, "\tlineTo %f %f\n", line->x, line->y);
55         } else if(line->type == gfx_splineTo) {
56             fprintf(fi, "\tsplineTo %f %f %f %f\n", line->sx, line->sy, line->x, line->y);
57         }
58         line = line->next;
59     }
60 }
61
62 void file_startclip(struct _gfxdevice*dev, gfxline_t*line)
63 {
64     internal_t*i = (internal_t*)dev->internal;
65     fprintf(i->fi, "startclip\n");
66     dumpline(i->fi, line);
67 }
68
69 void file_endclip(struct _gfxdevice*dev)
70 {
71     internal_t*i = (internal_t*)dev->internal;
72     fprintf(i->fi, "endclip\n");
73 }
74
75 void file_stroke(struct _gfxdevice*dev, gfxline_t*line, gfxcoord_t width, gfxcolor_t*color, gfx_capType cap_style, gfx_joinType joint_style, gfxcoord_t miterLimit)
76 {
77     internal_t*i = (internal_t*)dev->internal;
78     char* jointTypes[] = {"joinMiter", "joinRound", "joinBevel"};
79     char* capTypes[] = {"capButt", "capRound", "capSquare"};
80
81     fprintf(i->fi, "stroke %f %f %s %s %02x%02x%02x%02x\n", width, miterLimit, capTypes[cap_style], jointTypes[joint_style],
82                 color->r, color->g, color->b, color->a
83             );
84     dumpline(i->fi, line);
85 }
86
87 void file_fill(struct _gfxdevice*dev, gfxline_t*line, gfxcolor_t*color)
88 {
89     internal_t*i = (internal_t*)dev->internal;
90     fprintf(i->fi, "fill %02x%02x%02x%02x\n", color->r, color->g, color->b, color->a);
91     dumpline(i->fi, line);
92 }
93
94 void file_fillbitmap(struct _gfxdevice*dev, gfxline_t*line, gfximage_t*img, gfxmatrix_t*matrix, gfxcxform_t*cxform)
95 {
96     internal_t*i = (internal_t*)dev->internal;
97     fprintf(i->fi, "fillbitmap\n");
98     dumpline(i->fi, line);
99 }
100
101 void file_fillgradient(struct _gfxdevice*dev, gfxline_t*line, gfxgradient_t*gradient, gfxgradienttype_t type, gfxmatrix_t*matrix)
102 {
103     internal_t*i = (internal_t*)dev->internal;
104     fprintf(i->fi, "fillgradient\n");
105     dumpline(i->fi, line);
106 }
107
108 void file_addfont(struct _gfxdevice*dev, gfxfont_t*font)
109 {
110     internal_t*i = (internal_t*)dev->internal;
111 }
112
113 void file_drawchar(struct _gfxdevice*dev, gfxfont_t*font, int glyph, gfxcolor_t*color, gfxmatrix_t*matrix)
114 {
115     internal_t*i = (internal_t*)dev->internal;
116 }
117
118 void file_drawlink(struct _gfxdevice*dev, gfxline_t*line, const char*action)
119 {
120     internal_t*i = (internal_t*)dev->internal;
121     fprintf(i->fi, "drawlink %s\n", action);
122     dumpline(i->fi, line);
123 }
124
125 void file_endpage(struct _gfxdevice*dev)
126 {
127     internal_t*i = (internal_t*)dev->internal;
128     fprintf(i->fi, "endpage\n");
129 }
130
131 typedef struct gfxresult_internal
132 {
133     FILE*fi;
134     char*filename;
135 } gfxresult_internal_t;
136     
137 void fileresult_destroy(struct _gfxresult*gfx)
138 {
139     gfxresult_internal_t*i = (gfxresult_internal_t*)gfx->internal;
140     unlink(i->filename);
141     free(i->filename);i->filename = 0;
142 }
143
144 int fileresult_save(struct _gfxresult*gfx, const char*filename)
145 {
146     gfxresult_internal_t*i = (gfxresult_internal_t*)gfx->internal;
147     FILE*fi,*fo;
148     fi = fopen(i->filename, "rb");
149     if(!fi) {
150         perror(i->filename);
151         return 0;
152     }
153     fo = fopen(filename, "wb");
154     if(!fo) {
155         perror(filename);
156         return 0;
157     }
158
159     char buf[4096];
160     while(!feof(fi)) {
161         int l = fread(buf, 1, 4096, fi);
162         if(l>0) {
163             fwrite(buf, 1, l, fo);
164         } else {
165             break;
166         }
167     }
168
169     fclose(fi);
170     fclose(fo);
171     return 0;
172 }
173
174 void* fileresult_get(struct _gfxresult*gfx, const char*name)
175 {
176     return 0; 
177 }
178
179 gfxresult_t* file_finish(struct _gfxdevice*dev)
180 {
181     internal_t*i = (internal_t*)dev->internal;
182     char*filename = strdup(i->filename);
183     gfxresult_t*result = (gfxresult_t*)malloc(sizeof(gfxresult_t));
184     fclose(i->fi);
185     i->fi = 0;
186     if(i->filename) {
187         free(i->filename);
188         i->filename = 0;
189     }
190     free(dev->internal);
191     dev->internal = 0;
192
193     memset(result, 0, sizeof(gfxresult_t));
194     result->save = fileresult_save;
195     result->get = fileresult_get;
196     result->destroy = fileresult_destroy;
197     result->internal = malloc(sizeof(gfxresult_internal_t));
198     ((gfxresult_internal_t*)result->internal)->filename = filename;
199
200     return result;
201 }
202
203 void gfxdevice_file_init(gfxdevice_t*dev, char*filename)
204 {
205     internal_t*i = (internal_t*)malloc(sizeof(internal_t));
206     memset(dev, 0, sizeof(gfxdevice_t));
207
208     dev->name = "file";
209
210     dev->internal = i;
211
212     dev->setparameter = file_setparameter;
213     dev->startpage = file_startpage;
214     dev->startclip = file_startclip;
215     dev->endclip = file_endclip;
216     dev->stroke = file_stroke;
217     dev->fill = file_fill;
218     dev->fillbitmap = file_fillbitmap;
219     dev->fillgradient = file_fillgradient;
220     dev->addfont = file_addfont;
221     dev->drawchar = file_drawchar;
222     dev->drawlink = file_drawlink;
223     dev->endpage = file_endpage;
224     dev->finish = file_finish;
225
226     i->fi = fopen(filename, "wb");
227     i->filename = strdup(filename);
228     if(!i->fi) {
229         fprintf(stderr, "Couldn't open file %s\n", filename);
230         exit(1);
231     }
232 }
233