1#include "mupdf/fitz.h"
2
3#include <limits.h>
4
5#ifndef PATH_MAX
6#define PATH_MAX 4096
7#endif
8
9typedef struct fz_svg_writer_s fz_svg_writer;
10
11struct fz_svg_writer_s
12{
13 fz_document_writer super;
14 char *path;
15 int count;
16 fz_output *out;
17 int text_format;
18 int reuse_images;
19 int id;
20};
21
22const char *fz_svg_write_options_usage =
23 "SVG output options:\n"
24 "\ttext=text: Emit text as <text> elements (inaccurate fonts).\n"
25 "\ttext=path: Emit text as <path> elements (accurate fonts).\n"
26 "\tno-reuse-images: Do not reuse images using <symbol> definitions.\n"
27 "\n"
28 ;
29
30static fz_device *
31svg_begin_page(fz_context *ctx, fz_document_writer *wri_, fz_rect mediabox)
32{
33 fz_svg_writer *wri = (fz_svg_writer*)wri_;
34 char path[PATH_MAX];
35
36 float w = mediabox.x1 - mediabox.x0;
37 float h = mediabox.y1 - mediabox.y0;
38
39 wri->count += 1;
40
41 fz_format_output_path(ctx, path, sizeof path, wri->path, wri->count);
42 wri->out = fz_new_output_with_path(ctx, path, 0);
43 return fz_new_svg_device_with_id(ctx, wri->out, w, h, wri->text_format, wri->reuse_images, &wri->id);
44}
45
46static void
47svg_end_page(fz_context *ctx, fz_document_writer *wri_, fz_device *dev)
48{
49 fz_svg_writer *wri = (fz_svg_writer*)wri_;
50
51 fz_try(ctx)
52 {
53 fz_close_device(ctx, dev);
54 fz_close_output(ctx, wri->out);
55 }
56 fz_always(ctx)
57 {
58 fz_drop_device(ctx, dev);
59 fz_drop_output(ctx, wri->out);
60 wri->out = NULL;
61 }
62 fz_catch(ctx)
63 fz_rethrow(ctx);
64}
65
66static void
67svg_drop_writer(fz_context *ctx, fz_document_writer *wri_)
68{
69 fz_svg_writer *wri = (fz_svg_writer*)wri_;
70 fz_drop_output(ctx, wri->out);
71 fz_free(ctx, wri->path);
72}
73
74fz_document_writer *
75fz_new_svg_writer(fz_context *ctx, const char *path, const char *args)
76{
77 const char *val;
78 fz_svg_writer *wri = fz_new_derived_document_writer(ctx, fz_svg_writer, svg_begin_page, svg_end_page, NULL, svg_drop_writer);
79
80 wri->text_format = FZ_SVG_TEXT_AS_PATH;
81 wri->reuse_images = 1;
82
83 fz_try(ctx)
84 {
85 if (fz_has_option(ctx, args, "text", &val))
86 {
87 if (fz_option_eq(val, "text"))
88 wri->text_format = FZ_SVG_TEXT_AS_TEXT;
89 else if (fz_option_eq(val, "path"))
90 wri->text_format = FZ_SVG_TEXT_AS_PATH;
91 }
92 if (fz_has_option(ctx, args, "no-reuse-images", &val))
93 if (fz_option_eq(val, "yes"))
94 wri->reuse_images = 0;
95 wri->path = fz_strdup(ctx, path ? path : "out-%04d.svg");
96 }
97 fz_catch(ctx)
98 {
99 fz_free(ctx, wri);
100 fz_rethrow(ctx);
101 }
102
103 return (fz_document_writer*)wri;
104}
105