1#include "mupdf/fitz.h"
2
3typedef struct fz_trace_device_s
4{
5 fz_device super;
6 fz_output *out;
7 int depth;
8} fz_trace_device;
9
10static void fz_trace_indent(fz_context *ctx, fz_output *out, int depth)
11{
12 while (depth-- > 0)
13 fz_write_string(ctx, out, " ");
14}
15
16static void
17fz_trace_matrix(fz_context *ctx, fz_output *out, fz_matrix ctm)
18{
19 fz_write_printf(ctx, out, " transform=\"%g %g %g %g %g %g\"", ctm.a, ctm.b, ctm.c, ctm.d, ctm.e, ctm.f);
20}
21
22static void
23fz_trace_color(fz_context *ctx, fz_output *out, fz_colorspace *colorspace, const float *color, float alpha)
24{
25 int i, n;
26 if (colorspace)
27 {
28 n = fz_colorspace_n(ctx, colorspace);
29 fz_write_printf(ctx, out, " colorspace=\"%s\" color=\"", fz_colorspace_name(ctx, colorspace));
30 for (i = 0; i < n; i++)
31 fz_write_printf(ctx, out, "%s%g", i == 0 ? "" : " ", color[i]);
32 fz_write_printf(ctx, out, "\"");
33 }
34 if (alpha < 1)
35 fz_write_printf(ctx, out, " alpha=\"%g\"", alpha);
36}
37
38static int
39isxmlmeta(int c)
40{
41 return c < 32 || c >= 128 || c == '&' || c == '<' || c == '>' || c == '\'' || c == '"';
42}
43
44static void
45fz_trace_text_span(fz_context *ctx, fz_output *out, fz_text_span *span, int depth)
46{
47 int i;
48 fz_trace_indent(ctx, out, depth);
49 fz_write_printf(ctx, out, "<span font=\"%s\" wmode=\"%d\" bidi=\"%d\"", fz_font_name(ctx, span->font), span->wmode, span->bidi_level);
50 fz_write_printf(ctx, out, " trm=\"%g %g %g %g\">\n", span->trm.a, span->trm.b, span->trm.c, span->trm.d);
51 for (i = 0; i < span->len; i++)
52 {
53 char name[32];
54
55 fz_trace_indent(ctx, out, depth+1);
56 if (span->items[i].ucs == -1)
57 fz_write_printf(ctx, out, "<g unicode=\"-1\"");
58 else if (!isxmlmeta(span->items[i].ucs))
59 fz_write_printf(ctx, out, "<g unicode=\"%c\"", span->items[i].ucs);
60 else
61 fz_write_printf(ctx, out, "<g unicode=\"U+%04x\"", span->items[i].ucs);
62
63 if (span->items[i].gid >= 0)
64 {
65 fz_get_glyph_name(ctx, span->font, span->items[i].gid, name, sizeof name);
66 fz_write_printf(ctx, out, " glyph=\"%s\"", name);
67 }
68 else
69 fz_write_printf(ctx, out, " glyph=\"-1\"");
70
71 fz_write_printf(ctx, out, " x=\"%g\" y=\"%g\" />\n", span->items[i].x, span->items[i].y);
72 }
73 fz_trace_indent(ctx, out, depth);
74 fz_write_printf(ctx, out, "</span>\n");
75}
76
77static void
78fz_trace_text(fz_context *ctx, fz_output *out, const fz_text *text, int depth)
79{
80 fz_text_span *span;
81 for (span = text->head; span; span = span->next)
82 fz_trace_text_span(ctx, out, span, depth);
83}
84
85static void
86trace_moveto(fz_context *ctx, void *dev_, float x, float y)
87{
88 fz_trace_device *dev = (fz_trace_device*)dev_;
89 fz_output *out = dev->out;
90 fz_trace_indent(ctx, out, dev->depth);
91 fz_write_printf(ctx, out, "<moveto x=\"%g\" y=\"%g\"/>\n", x, y);
92}
93
94static void
95trace_lineto(fz_context *ctx, void *dev_, float x, float y)
96{
97 fz_trace_device *dev = (fz_trace_device*)dev_;
98 fz_output *out = dev->out;
99 fz_trace_indent(ctx, out, dev->depth);
100 fz_write_printf(ctx, out, "<lineto x=\"%g\" y=\"%g\"/>\n", x, y);
101}
102
103static void
104trace_curveto(fz_context *ctx, void *dev_, float x1, float y1, float x2, float y2, float x3, float y3)
105{
106 fz_trace_device *dev = (fz_trace_device*)dev_;
107 fz_output *out = dev->out;
108 fz_trace_indent(ctx, out, dev->depth);
109 fz_write_printf(ctx, out, "<curveto x1=\"%g\" y1=\"%g\" x2=\"%g\" y2=\"%g\" x3=\"%g\" y3=\"%g\"/>\n", x1, y1, x2, y2, x3, y3);
110}
111
112static void
113trace_close(fz_context *ctx, void *dev_)
114{
115 fz_trace_device *dev = (fz_trace_device*)dev_;
116 fz_output *out = dev->out;
117 fz_trace_indent(ctx, out, dev->depth);
118 fz_write_printf(ctx, out, "<closepath/>\n");
119}
120
121static const fz_path_walker trace_path_walker =
122{
123 trace_moveto,
124 trace_lineto,
125 trace_curveto,
126 trace_close
127};
128
129static void
130fz_trace_path(fz_context *ctx, fz_trace_device *dev, const fz_path *path)
131{
132 dev->depth++;
133 fz_walk_path(ctx, path, &trace_path_walker, dev);
134 dev->depth--;
135}
136
137static void
138fz_trace_fill_path(fz_context *ctx, fz_device *dev_, const fz_path *path, int even_odd, fz_matrix ctm,
139 fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params)
140{
141 fz_trace_device *dev = (fz_trace_device*)dev_;
142 fz_output *out = dev->out;
143 fz_trace_indent(ctx, out, dev->depth);
144 fz_write_printf(ctx, out, "<fill_path");
145 if (even_odd)
146 fz_write_printf(ctx, out, " winding=\"eofill\"");
147 else
148 fz_write_printf(ctx, out, " winding=\"nonzero\"");
149 fz_trace_color(ctx, out, colorspace, color, alpha);
150 fz_trace_matrix(ctx, out, ctm);
151 fz_write_printf(ctx, out, ">\n");
152 fz_trace_path(ctx, dev, path);
153 fz_trace_indent(ctx, out, dev->depth);
154 fz_write_printf(ctx, out, "</fill_path>\n");
155}
156
157static void
158fz_trace_stroke_path(fz_context *ctx, fz_device *dev_, const fz_path *path, const fz_stroke_state *stroke, fz_matrix ctm,
159 fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params)
160{
161 fz_trace_device *dev = (fz_trace_device*)dev_;
162 fz_output *out = dev->out;
163 int i;
164
165 fz_trace_indent(ctx, out, dev->depth);
166 fz_write_printf(ctx, out, "<stroke_path");
167 fz_write_printf(ctx, out, " linewidth=\"%g\"", stroke->linewidth);
168 fz_write_printf(ctx, out, " miterlimit=\"%g\"", stroke->miterlimit);
169 fz_write_printf(ctx, out, " linecap=\"%d,%d,%d\"", stroke->start_cap, stroke->dash_cap, stroke->end_cap);
170 fz_write_printf(ctx, out, " linejoin=\"%d\"", stroke->linejoin);
171
172 if (stroke->dash_len)
173 {
174 fz_write_printf(ctx, out, " dash_phase=\"%g\" dash=\"", stroke->dash_phase);
175 for (i = 0; i < stroke->dash_len; i++)
176 fz_write_printf(ctx, out, "%s%g", i > 0 ? " " : "", stroke->dash_list[i]);
177 fz_write_printf(ctx, out, "\"");
178 }
179
180 fz_trace_color(ctx, out, colorspace, color, alpha);
181 fz_trace_matrix(ctx, out, ctm);
182 fz_write_printf(ctx, out, ">\n");
183
184 fz_trace_path(ctx, dev, path);
185
186 fz_trace_indent(ctx, out, dev->depth);
187 fz_write_printf(ctx, out, "</stroke_path>\n");
188}
189
190static void
191fz_trace_clip_path(fz_context *ctx, fz_device *dev_, const fz_path *path, int even_odd, fz_matrix ctm, fz_rect scissor)
192{
193 fz_trace_device *dev = (fz_trace_device*)dev_;
194 fz_output *out = dev->out;
195 fz_trace_indent(ctx, out, dev->depth);
196 fz_write_printf(ctx, out, "<clip_path");
197 if (even_odd)
198 fz_write_printf(ctx, out, " winding=\"eofill\"");
199 else
200 fz_write_printf(ctx, out, " winding=\"nonzero\"");
201 fz_trace_matrix(ctx, out, ctm);
202 fz_write_printf(ctx, out, ">\n");
203 fz_trace_path(ctx, dev, path);
204 fz_trace_indent(ctx, out, dev->depth);
205 fz_write_printf(ctx, out, "</clip_path>\n");
206 dev->depth++;
207}
208
209static void
210fz_trace_clip_stroke_path(fz_context *ctx, fz_device *dev_, const fz_path *path, const fz_stroke_state *stroke, fz_matrix ctm, fz_rect scissor)
211{
212 fz_trace_device *dev = (fz_trace_device*)dev_;
213 fz_output *out = dev->out;
214 fz_trace_indent(ctx, out, dev->depth);
215 fz_write_printf(ctx, out, "<clip_stroke_path");
216 fz_trace_matrix(ctx, out, ctm);
217 fz_write_printf(ctx, out, ">\n");
218 fz_trace_path(ctx, dev, path);
219 fz_trace_indent(ctx, out, dev->depth);
220 fz_write_printf(ctx, out, "</clip_stroke_path>\n");
221 dev->depth++;
222}
223
224static void
225fz_trace_fill_text(fz_context *ctx, fz_device *dev_, const fz_text *text, fz_matrix ctm,
226 fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params)
227{
228 fz_trace_device *dev = (fz_trace_device*)dev_;
229 fz_output *out = dev->out;
230 fz_trace_indent(ctx, out, dev->depth);
231 fz_write_printf(ctx, out, "<fill_text");
232 fz_trace_color(ctx, out, colorspace, color, alpha);
233 fz_trace_matrix(ctx, out, ctm);
234 fz_write_printf(ctx, out, ">\n");
235 fz_trace_text(ctx, out, text, dev->depth+1);
236 fz_trace_indent(ctx, out, dev->depth);
237 fz_write_printf(ctx, out, "</fill_text>\n");
238}
239
240static void
241fz_trace_stroke_text(fz_context *ctx, fz_device *dev_, const fz_text *text, const fz_stroke_state *stroke, fz_matrix ctm,
242 fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params)
243{
244 fz_trace_device *dev = (fz_trace_device*)dev_;
245 fz_output *out = dev->out;
246 fz_trace_indent(ctx, out, dev->depth);
247 fz_write_printf(ctx, out, "<stroke_text");
248 fz_trace_color(ctx, out, colorspace, color, alpha);
249 fz_trace_matrix(ctx, out, ctm);
250 fz_write_printf(ctx, out, ">\n");
251 fz_trace_text(ctx, out, text, dev->depth+1);
252 fz_trace_indent(ctx, out, dev->depth);
253 fz_write_printf(ctx, out, "</stroke_text>\n");
254}
255
256static void
257fz_trace_clip_text(fz_context *ctx, fz_device *dev_, const fz_text *text, fz_matrix ctm, fz_rect scissor)
258{
259 fz_trace_device *dev = (fz_trace_device*)dev_;
260 fz_output *out = dev->out;
261 fz_trace_indent(ctx, out, dev->depth);
262 fz_write_printf(ctx, out, "<clip_text");
263 fz_trace_matrix(ctx, out, ctm);
264 fz_write_printf(ctx, out, ">\n");
265 fz_trace_text(ctx, out, text, dev->depth+1);
266 fz_trace_indent(ctx, out, dev->depth);
267 fz_write_printf(ctx, out, "</clip_text>\n");
268 dev->depth++;
269}
270
271static void
272fz_trace_clip_stroke_text(fz_context *ctx, fz_device *dev_, const fz_text *text, const fz_stroke_state *stroke, fz_matrix ctm, fz_rect scissor)
273{
274 fz_trace_device *dev = (fz_trace_device*)dev_;
275 fz_output *out = dev->out;
276 fz_trace_indent(ctx, out, dev->depth);
277 fz_write_printf(ctx, out, "<clip_stroke_text");
278 fz_trace_matrix(ctx, out, ctm);
279 fz_write_printf(ctx, out, ">\n");
280 fz_trace_text(ctx, out, text, dev->depth+1);
281 fz_trace_indent(ctx, out, dev->depth);
282 fz_write_printf(ctx, out, "</clip_stroke_text>\n");
283 dev->depth++;
284}
285
286static void
287fz_trace_ignore_text(fz_context *ctx, fz_device *dev_, const fz_text *text, fz_matrix ctm)
288{
289 fz_trace_device *dev = (fz_trace_device*)dev_;
290 fz_output *out = dev->out;
291 fz_trace_indent(ctx, out, dev->depth);
292 fz_write_printf(ctx, out, "<ignore_text");
293 fz_trace_matrix(ctx, out, ctm);
294 fz_write_printf(ctx, out, ">\n");
295 fz_trace_text(ctx, out, text, dev->depth+1);
296 fz_trace_indent(ctx, out, dev->depth);
297 fz_write_printf(ctx, out, "</ignore_text>\n");
298}
299
300static void
301fz_trace_fill_image(fz_context *ctx, fz_device *dev_, fz_image *image, fz_matrix ctm, float alpha, fz_color_params color_params)
302{
303 fz_trace_device *dev = (fz_trace_device*)dev_;
304 fz_output *out = dev->out;
305 fz_trace_indent(ctx, out, dev->depth);
306 fz_write_printf(ctx, out, "<fill_image alpha=\"%g\"", alpha);
307 if (image->colorspace)
308 fz_write_printf(ctx, out, " colorspace=\"%s\"", fz_colorspace_name(ctx, image->colorspace));
309 fz_trace_matrix(ctx, out, ctm);
310 fz_write_printf(ctx, out, " width=\"%d\" height=\"%d\"", image->w, image->h);
311 fz_write_printf(ctx, out, "/>\n");
312}
313
314static void
315fz_trace_fill_shade(fz_context *ctx, fz_device *dev_, fz_shade *shade, fz_matrix ctm, float alpha, fz_color_params color_params)
316{
317 fz_trace_device *dev = (fz_trace_device*)dev_;
318 fz_output *out = dev->out;
319 fz_trace_indent(ctx, out, dev->depth);
320 fz_write_printf(ctx, out, "<fill_shade alpha=\"%g\"", alpha);
321 fz_trace_matrix(ctx, out, ctm);
322 fz_write_printf(ctx, out, " pattern_matrix=\"%g %g %g %g %g %g\"",
323 shade->matrix.a,
324 shade->matrix.b,
325 shade->matrix.c,
326 shade->matrix.d,
327 shade->matrix.e,
328 shade->matrix.f);
329 fz_write_printf(ctx, out, " colorspace=\"%s\"", fz_colorspace_name(ctx, shade->colorspace));
330 // TODO: use_background and background
331 // TODO: use_function and function
332 switch (shade->type)
333 {
334 case FZ_FUNCTION_BASED:
335 fz_write_printf(ctx, out, " type=\"function\"");
336 fz_write_printf(ctx, out, " function_matrix=\"%g %g %g %g %g %g\"",
337 shade->u.f.matrix.a,
338 shade->u.f.matrix.b,
339 shade->u.f.matrix.c,
340 shade->u.f.matrix.d,
341 shade->u.f.matrix.e,
342 shade->u.f.matrix.f);
343 fz_write_printf(ctx, out, " domain=\"%g %g %g %g\"",
344 shade->u.f.domain[0][0],
345 shade->u.f.domain[0][1],
346 shade->u.f.domain[1][0],
347 shade->u.f.domain[1][1]);
348 fz_write_printf(ctx, out, " samples=\"%d %d\"",
349 shade->u.f.xdivs,
350 shade->u.f.ydivs);
351 fz_write_printf(ctx, out, "/>\n");
352 break;
353 case FZ_LINEAR:
354 fz_write_printf(ctx, out, " type=\"linear\"");
355 fz_write_printf(ctx, out, " extend=\"%d %d\"",
356 shade->u.l_or_r.extend[0],
357 shade->u.l_or_r.extend[1]);
358 fz_write_printf(ctx, out, " start=\"%g %g\"",
359 shade->u.l_or_r.coords[0][0],
360 shade->u.l_or_r.coords[0][1]);
361 fz_write_printf(ctx, out, " end=\"%g %g\"",
362 shade->u.l_or_r.coords[1][0],
363 shade->u.l_or_r.coords[1][1]);
364 fz_write_printf(ctx, out, "/>\n");
365 break;
366 case FZ_RADIAL:
367 fz_write_printf(ctx, out, " type=\"radial\"");
368 fz_write_printf(ctx, out, " extend=\"%d %d\"",
369 shade->u.l_or_r.extend[0],
370 shade->u.l_or_r.extend[1]);
371 fz_write_printf(ctx, out, " inner=\"%g %g %g\"",
372 shade->u.l_or_r.coords[0][0],
373 shade->u.l_or_r.coords[0][1],
374 shade->u.l_or_r.coords[0][2]);
375 fz_write_printf(ctx, out, " outer=\"%g %g %g\"",
376 shade->u.l_or_r.coords[1][0],
377 shade->u.l_or_r.coords[1][1],
378 shade->u.l_or_r.coords[1][2]);
379 fz_write_printf(ctx, out, "/>\n");
380 break;
381 default:
382 fz_write_printf(ctx, out, " type=\"mesh\"/>\n");
383 break;
384 }
385}
386
387static void
388fz_trace_fill_image_mask(fz_context *ctx, fz_device *dev_, fz_image *image, fz_matrix ctm,
389 fz_colorspace *colorspace, const float *color, float alpha, fz_color_params color_params)
390{
391 fz_trace_device *dev = (fz_trace_device*)dev_;
392 fz_output *out = dev->out;
393 fz_trace_indent(ctx, out, dev->depth);
394 fz_write_printf(ctx, out, "<fill_image_mask");
395 fz_trace_matrix(ctx, out, ctm);
396 fz_trace_color(ctx, out, colorspace, color, alpha);
397 fz_write_printf(ctx, out, " width=\"%d\" height=\"%d\"", image->w, image->h);
398 fz_write_printf(ctx, out, "/>\n");
399}
400
401static void
402fz_trace_clip_image_mask(fz_context *ctx, fz_device *dev_, fz_image *image, fz_matrix ctm, fz_rect scissor)
403{
404 fz_trace_device *dev = (fz_trace_device*)dev_;
405 fz_output *out = dev->out;
406 fz_trace_indent(ctx, out, dev->depth);
407 fz_write_printf(ctx, out, "<clip_image_mask");
408 fz_trace_matrix(ctx, out, ctm);
409 fz_write_printf(ctx, out, " width=\"%d\" height=\"%d\"", image->w, image->h);
410 fz_write_printf(ctx, out, "/>\n");
411 dev->depth++;
412}
413
414static void
415fz_trace_pop_clip(fz_context *ctx, fz_device *dev_)
416{
417 fz_trace_device *dev = (fz_trace_device*)dev_;
418 fz_output *out = dev->out;
419 dev->depth--;
420 fz_trace_indent(ctx, out, dev->depth);
421 fz_write_printf(ctx, out, "<pop_clip/>\n");
422}
423
424static void
425fz_trace_begin_mask(fz_context *ctx, fz_device *dev_, fz_rect bbox, int luminosity, fz_colorspace *colorspace, const float *color, fz_color_params color_params)
426{
427 fz_trace_device *dev = (fz_trace_device*)dev_;
428 fz_output *out = dev->out;
429 fz_trace_indent(ctx, out, dev->depth);
430 fz_write_printf(ctx, out, "<clip_mask bbox=\"%g %g %g %g\" s=\"%s\"",
431 bbox.x0, bbox.y0, bbox.x1, bbox.y1,
432 luminosity ? "luminosity" : "alpha");
433 fz_write_printf(ctx, out, ">\n");
434 dev->depth++;
435}
436
437static void
438fz_trace_end_mask(fz_context *ctx, fz_device *dev_)
439{
440 fz_trace_device *dev = (fz_trace_device*)dev_;
441 fz_output *out = dev->out;
442 dev->depth--;
443 fz_trace_indent(ctx, out, dev->depth);
444 fz_write_printf(ctx, out, "</clip_mask>\n");
445 dev->depth++;
446}
447
448static void
449fz_trace_begin_group(fz_context *ctx, fz_device *dev_, fz_rect bbox, fz_colorspace *cs, int isolated, int knockout, int blendmode, float alpha)
450{
451 fz_trace_device *dev = (fz_trace_device*)dev_;
452 fz_output *out = dev->out;
453 fz_trace_indent(ctx, out, dev->depth);
454 fz_write_printf(ctx, out, "<group bbox=\"%g %g %g %g\" isolated=\"%d\" knockout=\"%d\" blendmode=\"%s\" alpha=\"%g\">\n",
455 bbox.x0, bbox.y0, bbox.x1, bbox.y1,
456 isolated, knockout, fz_blendmode_name(blendmode), alpha);
457 dev->depth++;
458}
459
460static void
461fz_trace_end_group(fz_context *ctx, fz_device *dev_)
462{
463 fz_trace_device *dev = (fz_trace_device*)dev_;
464 fz_output *out = dev->out;
465 dev->depth--;
466 fz_trace_indent(ctx, out, dev->depth);
467 fz_write_printf(ctx, out, "</group>\n");
468}
469
470static int
471fz_trace_begin_tile(fz_context *ctx, fz_device *dev_, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm, int id)
472{
473 fz_trace_device *dev = (fz_trace_device*)dev_;
474 fz_output *out = dev->out;
475 fz_trace_indent(ctx, out, dev->depth);
476 fz_write_printf(ctx, out, "<tile id=\"%d\"", id);
477 fz_write_printf(ctx, out, " area=\"%g %g %g %g\"", area.x0, area.y0, area.x1, area.y1);
478 fz_write_printf(ctx, out, " view=\"%g %g %g %g\"", view.x0, view.y0, view.x1, view.y1);
479 fz_write_printf(ctx, out, " xstep=\"%g\" ystep=\"%g\"", xstep, ystep);
480 fz_trace_matrix(ctx, out, ctm);
481 fz_write_printf(ctx, out, ">\n");
482 dev->depth++;
483 return 0;
484}
485
486static void
487fz_trace_end_tile(fz_context *ctx, fz_device *dev_)
488{
489 fz_trace_device *dev = (fz_trace_device*)dev_;
490 fz_output *out = dev->out;
491 dev->depth--;
492 fz_trace_indent(ctx, out, dev->depth);
493 fz_write_printf(ctx, out, "</tile>\n");
494}
495
496static void
497fz_trace_begin_layer(fz_context *ctx, fz_device *dev_, const char *name)
498{
499 fz_trace_device *dev = (fz_trace_device*)dev_;
500 fz_output *out = dev->out;
501 fz_trace_indent(ctx, out, dev->depth);
502 fz_write_printf(ctx, out, "<layer name=\"%s\"/>\n", name);
503}
504
505static void
506fz_trace_end_layer(fz_context *ctx, fz_device *dev_)
507{
508 fz_trace_device *dev = (fz_trace_device*)dev_;
509 fz_output *out = dev->out;
510 fz_trace_indent(ctx, out, dev->depth);
511 fz_write_printf(ctx, out, "<end_layer/>\n");
512}
513
514static void
515fz_trace_render_flags(fz_context *ctx, fz_device *dev_, int set, int clear)
516{
517 fz_trace_device *dev = (fz_trace_device*)dev_;
518 fz_output *out = dev->out;
519 fz_trace_indent(ctx, out, dev->depth);
520 fz_write_printf(ctx, out, "<render_flags set=\"0x%x\" clear=\"0x%x\"/>\n", set, clear);
521}
522
523static void
524fz_trace_set_default_colorspaces(fz_context *ctx, fz_device *dev_, fz_default_colorspaces *dcs)
525{
526 fz_trace_device *dev = (fz_trace_device*)dev_;
527 fz_output *out = dev->out;
528 fz_trace_indent(ctx, out, dev->depth);
529 fz_write_printf(ctx, out, "<set_default_colorspaces");
530 fz_write_printf(ctx, out, " gray=\"%s\"", fz_colorspace_name(ctx, fz_default_gray(ctx, dcs)));
531 fz_write_printf(ctx, out, " rgb=\"%s\"", fz_colorspace_name(ctx, fz_default_rgb(ctx, dcs)));
532 fz_write_printf(ctx, out, " cmyk=\"%s\"", fz_colorspace_name(ctx, fz_default_cmyk(ctx, dcs)));
533 fz_write_printf(ctx, out, " oi=\"%s\"/>\n",fz_colorspace_name(ctx, fz_default_output_intent(ctx, dcs)));
534}
535
536/*
537 Create a device to print a debug trace of all device calls.
538*/
539fz_device *fz_new_trace_device(fz_context *ctx, fz_output *out)
540{
541 fz_trace_device *dev = fz_new_derived_device(ctx, fz_trace_device);
542
543 dev->super.fill_path = fz_trace_fill_path;
544 dev->super.stroke_path = fz_trace_stroke_path;
545 dev->super.clip_path = fz_trace_clip_path;
546 dev->super.clip_stroke_path = fz_trace_clip_stroke_path;
547
548 dev->super.fill_text = fz_trace_fill_text;
549 dev->super.stroke_text = fz_trace_stroke_text;
550 dev->super.clip_text = fz_trace_clip_text;
551 dev->super.clip_stroke_text = fz_trace_clip_stroke_text;
552 dev->super.ignore_text = fz_trace_ignore_text;
553
554 dev->super.fill_shade = fz_trace_fill_shade;
555 dev->super.fill_image = fz_trace_fill_image;
556 dev->super.fill_image_mask = fz_trace_fill_image_mask;
557 dev->super.clip_image_mask = fz_trace_clip_image_mask;
558
559 dev->super.pop_clip = fz_trace_pop_clip;
560
561 dev->super.begin_mask = fz_trace_begin_mask;
562 dev->super.end_mask = fz_trace_end_mask;
563 dev->super.begin_group = fz_trace_begin_group;
564 dev->super.end_group = fz_trace_end_group;
565
566 dev->super.begin_tile = fz_trace_begin_tile;
567 dev->super.end_tile = fz_trace_end_tile;
568
569 dev->super.begin_layer = fz_trace_begin_layer;
570 dev->super.end_layer = fz_trace_end_layer;
571
572 dev->super.render_flags = fz_trace_render_flags;
573 dev->super.set_default_colorspaces = fz_trace_set_default_colorspaces;
574
575 dev->out = out;
576
577 return (fz_device*)dev;
578}
579