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