6 #include "devices/record.h"
8 typedef struct _internal {
11 gfxdevice_t*final_out;
13 /* for two pass filters: */
17 gfxtwopassfilter_t*twopass;
20 static int filter_setparameter(gfxdevice_t*dev, const char*key, const char*value)
22 internal_t*i = (internal_t*)dev->internal;
23 return i->filter->setparameter(i->filter, key, value, i->out);
25 static void filter_startpage(gfxdevice_t*dev, int width, int height)
27 internal_t*i = (internal_t*)dev->internal;
28 i->filter->startpage(i->filter, width, height, i->out);
30 static void filter_startclip(gfxdevice_t*dev, gfxline_t*line)
32 internal_t*i = (internal_t*)dev->internal;
33 i->filter->startclip(i->filter, line, i->out);
35 static void filter_endclip(gfxdevice_t*dev)
37 internal_t*i = (internal_t*)dev->internal;
38 i->filter->endclip(i->filter, i->out);
40 static void filter_stroke(gfxdevice_t*dev, gfxline_t*line, gfxcoord_t width, gfxcolor_t*color, gfx_capType cap_style, gfx_joinType joint_style, gfxcoord_t miterLimit)
42 internal_t*i = (internal_t*)dev->internal;
43 i->filter->stroke(i->filter, line, width, color, cap_style, joint_style, miterLimit, i->out);
45 static void filter_fill(gfxdevice_t*dev, gfxline_t*line, gfxcolor_t*color)
47 internal_t*i = (internal_t*)dev->internal;
48 i->filter->fill(i->filter, line, color, i->out);
50 static void filter_fillbitmap(gfxdevice_t*dev, gfxline_t*line, gfximage_t*img, gfxmatrix_t*matrix, gfxcxform_t*cxform)
52 internal_t*i = (internal_t*)dev->internal;
53 i->filter->fillbitmap(i->filter, line, img, matrix, cxform, i->out);
55 static void filter_fillgradient(gfxdevice_t*dev, gfxline_t*line, gfxgradient_t*gradient, gfxgradienttype_t type, gfxmatrix_t*matrix)
57 internal_t*i = (internal_t*)dev->internal;
58 i->filter->fillgradient(i->filter, line, gradient, type, matrix, i->out);
60 static void filter_addfont(gfxdevice_t*dev, gfxfont_t*font)
62 internal_t*i = (internal_t*)dev->internal;
63 i->filter->addfont(i->filter, font, i->out);
65 static void filter_drawchar(gfxdevice_t*dev, gfxfont_t*font, int glyphnr, gfxcolor_t*color, gfxmatrix_t*matrix)
67 internal_t*i = (internal_t*)dev->internal;
68 i->filter->drawchar(i->filter, font, glyphnr, color, matrix, i->out);
70 static void filter_drawlink(gfxdevice_t*dev, gfxline_t*line, const char*action)
72 internal_t*i = (internal_t*)dev->internal;
73 i->filter->drawlink(i->filter, line, action, i->out);
75 static void filter_endpage(gfxdevice_t*dev)
77 internal_t*i = (internal_t*)dev->internal;
78 i->filter->endpage(i->filter, i->out);
80 static gfxresult_t* filter_finish(gfxdevice_t*dev)
82 internal_t*i = (internal_t*)dev->internal;
83 gfxresult_t*r = i->filter->finish(i->filter, i->out);
84 free(dev->internal);dev->internal=0;free(dev);
89 static int passthrough_setparameter(gfxdevice_t*dev, const char*key, const char*value)
91 internal_t*i = (internal_t*)dev->internal;
92 return i->out->setparameter(i->out, key, value);
94 static void passthrough_startpage(gfxdevice_t*dev, int width, int height)
96 internal_t*i = (internal_t*)dev->internal;
97 i->out->startpage(i->out, width, height);
99 static void passthrough_startclip(gfxdevice_t*dev, gfxline_t*line)
101 internal_t*i = (internal_t*)dev->internal;
102 i->out->startclip(i->out, line);
104 static void passthrough_endclip(gfxdevice_t*dev)
106 internal_t*i = (internal_t*)dev->internal;
107 i->out->endclip(i->out);
109 static void passthrough_stroke(gfxdevice_t*dev, gfxline_t*line, gfxcoord_t width, gfxcolor_t*color, gfx_capType cap_style, gfx_joinType joint_style, gfxcoord_t miterLimit)
111 internal_t*i = (internal_t*)dev->internal;
112 i->out->stroke(i->out, line, width, color, cap_style, joint_style, miterLimit);
114 static void passthrough_fill(gfxdevice_t*dev, gfxline_t*line, gfxcolor_t*color)
116 internal_t*i = (internal_t*)dev->internal;
117 i->out->fill(i->out, line, color);
119 static void passthrough_fillbitmap(gfxdevice_t*dev, gfxline_t*line, gfximage_t*img, gfxmatrix_t*matrix, gfxcxform_t*cxform)
121 internal_t*i = (internal_t*)dev->internal;
122 i->out->fillbitmap(i->out, line, img, matrix, cxform);
124 static void passthrough_fillgradient(gfxdevice_t*dev, gfxline_t*line, gfxgradient_t*gradient, gfxgradienttype_t type, gfxmatrix_t*matrix)
126 internal_t*i = (internal_t*)dev->internal;
127 i->out->fillgradient(i->out, line, gradient, type, matrix);
129 static void passthrough_addfont(gfxdevice_t*dev, gfxfont_t*font)
131 internal_t*i = (internal_t*)dev->internal;
132 i->out->addfont(i->out, font);
134 static void passthrough_drawchar(gfxdevice_t*dev, gfxfont_t*font, int glyphnr, gfxcolor_t*color, gfxmatrix_t*matrix)
136 internal_t*i = (internal_t*)dev->internal;
137 i->out->drawchar(i->out, font, glyphnr, color, matrix);
139 static void passthrough_drawlink(gfxdevice_t*dev, gfxline_t*line, const char*action)
141 internal_t*i = (internal_t*)dev->internal;
142 i->out->drawlink(i->out, line, action);
144 static void passthrough_endpage(gfxdevice_t*dev)
146 internal_t*i = (internal_t*)dev->internal;
147 i->out->endpage(i->out);
149 gfxresult_t* passthrough_finish(gfxdevice_t*dev)
151 internal_t*i = (internal_t*)dev->internal;
152 gfxdevice_t*out = i->out;
153 free(dev->internal);dev->internal=0;free(dev);
154 return out->finish(out);
157 int discard_setparameter(gfxdevice_t*dev, const char*key, const char*value)
161 static void discard_startpage(gfxdevice_t*dev, int width, int height)
164 static void discard_startclip(gfxdevice_t*dev, gfxline_t*line)
167 static void discard_endclip(gfxdevice_t*dev)
170 static void discard_stroke(gfxdevice_t*dev, gfxline_t*line, gfxcoord_t width, gfxcolor_t*color, gfx_capType cap_style, gfx_joinType joint_style, gfxcoord_t miterLimit)
173 static void discard_fill(gfxdevice_t*dev, gfxline_t*line, gfxcolor_t*color)
176 static void discard_fillbitmap(gfxdevice_t*dev, gfxline_t*line, gfximage_t*img, gfxmatrix_t*matrix, gfxcxform_t*cxform)
179 static void discard_fillgradient(gfxdevice_t*dev, gfxline_t*line, gfxgradient_t*gradient, gfxgradienttype_t type, gfxmatrix_t*matrix)
182 static void discard_addfont(gfxdevice_t*dev, gfxfont_t*font)
185 static void discard_drawchar(gfxdevice_t*dev, gfxfont_t*font, int glyphnr, gfxcolor_t*color, gfxmatrix_t*matrix)
188 static void discard_drawlink(gfxdevice_t*dev, gfxline_t*line, const char*action)
191 static void discard_endpage(gfxdevice_t*dev)
194 static gfxresult_t* discard_finish(gfxdevice_t*dev)
199 gfxdevice_t*gfxfilter_apply(gfxfilter_t*filter, gfxdevice_t*out)
201 internal_t*i = (internal_t*)rfx_calloc(sizeof(internal_t));
202 gfxdevice_t*dev = (gfxdevice_t*)rfx_calloc(sizeof(gfxdevice_t));
209 dev->name = filter->name?filter->name:"filter";
210 dev->setparameter = filter->setparameter?filter_setparameter:passthrough_setparameter;
211 dev->startpage = filter->startpage?filter_startpage:passthrough_startpage;
212 dev->startclip = filter->startclip?filter_startclip:passthrough_startclip;
213 dev->endclip = filter->endclip?filter_endclip:passthrough_endclip;
214 dev->stroke = filter->stroke?filter_stroke:passthrough_stroke;
215 dev->fill = filter->fill?filter_fill:passthrough_fill;
216 dev->fillbitmap = filter->fillbitmap?filter_fillbitmap:passthrough_fillbitmap;
217 dev->fillgradient = filter->fillgradient?filter_fillgradient:passthrough_fillgradient;
218 dev->addfont = filter->addfont?filter_addfont:passthrough_addfont;
219 dev->drawchar = filter->drawchar?filter_drawchar:passthrough_drawchar;
220 dev->drawlink = filter->drawlink?filter_drawlink:passthrough_drawlink;
221 dev->endpage = filter->endpage?filter_endpage:passthrough_endpage;
222 dev->finish = filter->finish?filter_finish:passthrough_finish;
226 static void setup_twopass(gfxdevice_t*, gfxfilter_t*filter, char passthrough);
228 static gfxresult_t* twopass_finish(gfxdevice_t*dev)
230 internal_t*i = (internal_t*)dev->internal;
232 assert(!strcmp(i->out->name, "record"));
235 if(i->filter->finish) {
236 r = i->filter->finish(i->filter, i->out);
238 r = i->out->finish(i->out);
241 if(i->pass == i->num_passes) {
242 /* this output device was not a record device, so we don't have
243 to do anything here (like cleanup) */
247 /* switch to next pass filter */
248 i->filter = &i->twopass->pass2;
250 if(i->pass == i->num_passes-1) {
251 /* we don't record in the final pass- we just stream out to the
252 next output device */
253 i->out = i->final_out;
255 // this only happens for 3 passes or more
256 assert(i->num_passes>2);
257 gfxdevice_record_init(&i->record, /*use tempfile*/1);
262 gfxresult_record_replay(r, i->out);
263 r = i->out->finish(i->out);
268 gfxdevice_t*gfxtwopassfilter_apply(gfxtwopassfilter_t*twopass, gfxdevice_t*out)
270 internal_t*i = (internal_t*)rfx_calloc(sizeof(internal_t));
271 gfxdevice_t*dev = (gfxdevice_t*)rfx_calloc(sizeof(gfxdevice_t));
273 gfxdevice_record_init(&i->record, /*use tempfile*/1);
277 i->filter = &twopass->pass1;
278 i->twopass = twopass;
282 dev->setparameter = i->filter->setparameter?filter_setparameter:passthrough_setparameter;
283 dev->startpage = i->filter->startpage?filter_startpage:passthrough_startpage;
284 dev->startclip = i->filter->startclip?filter_startclip:passthrough_startclip;
285 dev->endclip = i->filter->endclip?filter_endclip:passthrough_endclip;
286 dev->stroke = i->filter->stroke?filter_stroke:passthrough_stroke;
287 dev->fill = i->filter->fill?filter_fill:passthrough_fill;
288 dev->fillbitmap = i->filter->fillbitmap?filter_fillbitmap:passthrough_fillbitmap;
289 dev->fillgradient = i->filter->fillgradient?filter_fillgradient:passthrough_fillgradient;
290 dev->addfont = i->filter->addfont?filter_addfont:passthrough_addfont;
291 dev->drawchar = i->filter->drawchar?filter_drawchar:passthrough_drawchar;
292 dev->drawlink = i->filter->drawlink?filter_drawlink:passthrough_drawlink;
293 dev->endpage = i->filter->endpage?filter_endpage:passthrough_endpage;
294 dev->finish = twopass_finish;
297 dev->name = i->filter->name?i->filter->name:"filter";
298 dev->finish = twopass_finish;