From 7ff59224621050fc29bf455b28e583b4c339f251 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Thu, 16 Feb 2017 16:21:23 +0100 Subject: Add svg writer. Now mutool convert can write SVG documents. --- include/mupdf/fitz/writer.h | 6 ++- platform/win32/libmupdf.vcproj | 4 ++ source/fitz/draw-device.c | 2 +- source/fitz/output-svg.c | 87 ++++++++++++++++++++++++++++++++++++++++++ source/fitz/writer.c | 6 ++- source/tools/muconvert.c | 3 +- 6 files changed, 102 insertions(+), 6 deletions(-) create mode 100644 source/fitz/output-svg.c diff --git a/include/mupdf/fitz/writer.h b/include/mupdf/fitz/writer.h index b9d28138..bf6a9175 100644 --- a/include/mupdf/fitz/writer.h +++ b/include/mupdf/fitz/writer.h @@ -28,11 +28,13 @@ void fz_close_document_writer(fz_context *ctx, fz_document_writer *wri); void fz_drop_document_writer(fz_context *ctx, fz_document_writer *wri); fz_document_writer *fz_new_cbz_writer(fz_context *ctx, const char *path, const char *options); -fz_document_writer *fz_new_png_writer(fz_context *ctx, const char *path, const char *options); fz_document_writer *fz_new_pdf_writer(fz_context *ctx, const char *path, const char *options); +fz_document_writer *fz_new_png_writer(fz_context *ctx, const char *path, const char *options); +fz_document_writer *fz_new_svg_writer(fz_context *ctx, const char *path, const char *options); extern const char *fz_cbz_write_options_usage; -extern const char *fz_png_write_options_usage; extern const char *fz_pdf_write_options_usage; +extern const char *fz_png_write_options_usage; +extern const char *fz_svg_write_options_usage; #endif diff --git a/platform/win32/libmupdf.vcproj b/platform/win32/libmupdf.vcproj index b83f68e3..fa8761af 100644 --- a/platform/win32/libmupdf.vcproj +++ b/platform/win32/libmupdf.vcproj @@ -1804,6 +1804,10 @@ RelativePath="..\..\source\fitz\output-pwg.c" > + + diff --git a/source/fitz/draw-device.c b/source/fitz/draw-device.c index d2b2d380..230e3a8e 100644 --- a/source/fitz/draw-device.c +++ b/source/fitz/draw-device.c @@ -2404,7 +2404,7 @@ fz_bound_path_accurate(fz_context *ctx, fz_irect *bbox, const fz_irect *scissor, const char *fz_draw_options_usage = "Common raster format output options:\n" "\trotate=N: rotate rendered pages N degrees counterclockwise\n" - "\tresolution=N: set both X and Y resolution of rendered pages in pixels per inch\n" + "\tresolution=N: set both X and Y resolution in pixels per inch\n" "\tx-resolution=N: X resolution of rendered pages in pixels per inch\n" "\ty-resolution=N: Y resolution of rendered pages in pixels per inch\n" "\twidth=N: render pages to fit N pixels wide (ignore resolution option)\n" diff --git a/source/fitz/output-svg.c b/source/fitz/output-svg.c new file mode 100644 index 00000000..40260fae --- /dev/null +++ b/source/fitz/output-svg.c @@ -0,0 +1,87 @@ +#include "mupdf/fitz.h" + +typedef struct fz_svg_writer_s fz_svg_writer; + +struct fz_svg_writer_s +{ + fz_document_writer super; + char *path; + int count; + fz_output *out; + int text_format; +}; + +const char *fz_svg_write_options_usage = + "SVG output options:\n" + "\ttext=text: Emit text as elements (inaccurate fonts).\n" + "\ttext=path: Emit text as elements (accurate fonts).\n" + "\n" + ; + +static fz_device * +svg_begin_page(fz_context *ctx, fz_document_writer *wri_, const fz_rect *mediabox) +{ + fz_svg_writer *wri = (fz_svg_writer*)wri_; + char path[PATH_MAX]; + + float w = mediabox->x1 - mediabox->x0; + float h = mediabox->y1 - mediabox->y0; + + wri->count += 1; + + fz_format_output_path(ctx, path, sizeof path, wri->path, wri->count); + wri->out = fz_new_output_with_path(ctx, path, 0); + return fz_new_svg_device(ctx, wri->out, w, h, wri->text_format); +} + +static void +svg_end_page(fz_context *ctx, fz_document_writer *wri_, fz_device *dev) +{ + fz_svg_writer *wri = (fz_svg_writer*)wri_; + + fz_close_device(ctx, dev); + fz_drop_device(ctx, dev); + fz_drop_output(ctx, wri->out); + wri->out = NULL; +} + +static void +svg_drop_writer(fz_context *ctx, fz_document_writer *wri_) +{ + fz_svg_writer *wri = (fz_svg_writer*)wri_; + fz_drop_output(ctx, wri->out); + fz_free(ctx, wri->path); +} + +fz_document_writer * +fz_new_svg_writer(fz_context *ctx, const char *path, const char *args) +{ + fz_svg_writer *wri; + const char *val; + + wri = fz_malloc_struct(ctx, fz_svg_writer); + wri->super.begin_page = svg_begin_page; + wri->super.end_page = svg_end_page; + wri->super.drop_writer = svg_drop_writer; + + wri->text_format = FZ_SVG_TEXT_AS_PATH; + + fz_try(ctx) + { + if (fz_has_option(ctx, args, "text", &val)) + { + if (fz_option_eq(val, "text")) + wri->text_format = FZ_SVG_TEXT_AS_TEXT; + else if (fz_option_eq(val, "path")) + wri->text_format = FZ_SVG_TEXT_AS_PATH; + } + wri->path = fz_strdup(ctx, path ? path : "out-%04d.svg"); + } + fz_catch(ctx) + { + fz_free(ctx, wri); + fz_rethrow(ctx); + } + + return (fz_document_writer*)wri; +} diff --git a/source/fitz/writer.c b/source/fitz/writer.c index fe9e8635..6ef40ffb 100644 --- a/source/fitz/writer.c +++ b/source/fitz/writer.c @@ -61,12 +61,14 @@ fz_new_document_writer(fz_context *ctx, const char *path, const char *format, co if (!fz_strcasecmp(format, "cbz")) return fz_new_cbz_writer(ctx, path, options); - if (!fz_strcasecmp(format, "png")) - return fz_new_png_writer(ctx, path, options); #if FZ_ENABLE_PDF if (!fz_strcasecmp(format, "pdf")) return fz_new_pdf_writer(ctx, path, options); #endif + if (!fz_strcasecmp(format, "png")) + return fz_new_png_writer(ctx, path, options); + if (!fz_strcasecmp(format, "svg")) + return fz_new_svg_writer(ctx, path, options); fz_throw(ctx, FZ_ERROR_GENERIC, "unknown output document format: %s", format); } diff --git a/source/tools/muconvert.c b/source/tools/muconvert.c index c3673852..46a8d67a 100644 --- a/source/tools/muconvert.c +++ b/source/tools/muconvert.c @@ -39,7 +39,7 @@ static void usage(void) "\n" "\t-o -\toutput file name (%%d for page number)\n" "\t-F -\toutput format (default inferred from output file name)\n" - "\t\tcbz, pdf, png\n" + "\t\tcbz, pdf, png, svg\n" "\t-O -\tcomma separated list of options for output format\n" "\n" "\tpages\tcomma separated list of page ranges (N=last page)\n" @@ -52,6 +52,7 @@ static void usage(void) #if FZ_ENABLE_PDF fputs(fz_pdf_write_options_usage, stderr); #endif + fputs(fz_svg_write_options_usage, stderr); exit(1); } -- cgit v1.2.3