summaryrefslogtreecommitdiff
path: root/source/fitz/svg-device.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/fitz/svg-device.c')
-rw-r--r--source/fitz/svg-device.c96
1 files changed, 51 insertions, 45 deletions
diff --git a/source/fitz/svg-device.c b/source/fitz/svg-device.c
index 09b3d82d..89c3b4b6 100644
--- a/source/fitz/svg-device.c
+++ b/source/fitz/svg-device.c
@@ -42,6 +42,7 @@ struct svg_device_s
fz_device super;
int text_as_text;
+ int reuse_images;
fz_output *out;
fz_output *out_store;
@@ -806,26 +807,28 @@ send_data_base64(fz_context *ctx, fz_output *out, fz_buffer *buffer)
/* We spot repeated images, and send them just once using
* symbols. Unfortunately, for pathological files, such
* as the example in Bug695988, this can cause viewers to
- * have conniptions. We therefore have a define that can
- * be made to avoid this (SVG_SEND_REPEATED_IMAGES). */
+ * have conniptions. We therefore have an option that is
+ * made to avoid this (reuse-images=no). */
static void
svg_send_image(fz_context *ctx, svg_device *sdev, fz_image *img)
{
fz_output *out = sdev->out;
fz_compressed_buffer *buffer;
-#ifndef SVG_SEND_REPEATED_IMAGES
int i;
int id;
- for (i = sdev->num_images-1; i >= 0; i--)
- {
- if (img == sdev->images[i].image)
- break;
- }
- if (i >= 0)
- id = sdev->images[i].id;
- else
+ if (sdev->reuse_images)
{
+ for (i = sdev->num_images-1; i >= 0; i--)
+ if (img == sdev->images[i].image)
+ break;
+ if (i >= 0)
+ {
+ fz_printf(ctx, out, "<use xlink:href=\"#im%d\" x=\"0\" y=\"0\" width=\"%d\" height=\"%d\"/>\n",
+ sdev->images[i].id, img->w, img->h);
+ return;
+ }
+
/* We need to send this image for the first time */
if (sdev->num_images == sdev->max_images)
{
@@ -838,48 +841,50 @@ svg_send_image(fz_context *ctx, svg_device *sdev, fz_image *img)
id = sdev->id++;
out = start_def(ctx, sdev);
- fz_printf(ctx, out, "<symbol id=\"im%d\">\n", id);
-#endif
- fz_printf(ctx, out, "<image");
- buffer = fz_compressed_image_buffer(ctx, img);
- fz_printf(ctx, out, " width=\"%dpx\" height=\"%dpx\" xlink:href=\"data:", img->w, img->h);
- switch (buffer == NULL ? FZ_IMAGE_JPX : buffer->params.type)
+ fz_printf(ctx, out, "<symbol id=\"im%d\" viewBox=\"0 0 %d %d\">\n", id, img->w, img->h);
+ }
+
+ fz_printf(ctx, out, "<image");
+ buffer = fz_compressed_image_buffer(ctx, img);
+ fz_printf(ctx, out, " width=\"%d\" height=\"%d\" xlink:href=\"data:", img->w, img->h);
+ switch (buffer == NULL ? FZ_IMAGE_JPX : buffer->params.type)
+ {
+ case FZ_IMAGE_PNG:
+ fz_printf(ctx, out, "image/png;base64,");
+ send_data_base64(ctx, out, buffer->buffer);
+ break;
+ case FZ_IMAGE_JPEG:
+ /* SVG cannot cope with CMYK images */
+ if (img->colorspace != fz_device_cmyk(ctx))
{
- case FZ_IMAGE_PNG:
- fz_printf(ctx, out, "image/png;base64,");
+ fz_printf(ctx, out, "image/jpeg;base64,");
send_data_base64(ctx, out, buffer->buffer);
break;
- case FZ_IMAGE_JPEG:
- /* SVG cannot cope with CMYK images */
- if (img->colorspace != fz_device_cmyk(ctx))
- {
- fz_printf(ctx, out, "image/jpeg;base64,");
- send_data_base64(ctx, out, buffer->buffer);
- break;
- }
- /*@fallthough@*/
- default:
- {
- fz_buffer *buf = fz_new_buffer_from_image_as_png(ctx, img);
- fz_printf(ctx, out, "image/png;base64,");
- send_data_base64(ctx, out, buf);
- fz_drop_buffer(ctx, buf);
- break;
- }
}
- fz_printf(ctx, out, "\"/>\n");
-#ifndef SVG_SEND_REPEATED_IMAGES
+ /*@fallthough@*/
+ default:
+ {
+ fz_buffer *buf = fz_new_buffer_from_image_as_png(ctx, img);
+ fz_printf(ctx, out, "image/png;base64,");
+ send_data_base64(ctx, out, buf);
+ fz_drop_buffer(ctx, buf);
+ break;
+ }
+ }
+ fz_printf(ctx, out, "\"/>\n");
+ if (sdev->reuse_images)
+ {
fz_printf(ctx, out, "</symbol>\n");
out = end_def(ctx, sdev);
sdev->images[sdev->num_images].id = id;
sdev->images[sdev->num_images].image = fz_keep_image(ctx, img);
sdev->num_images++;
- }
- fz_printf(ctx, out, "<use x=\"0\" y=\"0\" xlink:href=\"#im%d\"/>\n", id);
-#endif
+ fz_printf(ctx, out, "<use xlink:href=\"#im%d\" x=\"0\" y=\"0\" width=\"%d\" height=\"%d\"/>\n",
+ id, img->w, img->h);
+ }
}
static void
@@ -931,7 +936,7 @@ svg_dev_fill_shade(fz_context *ctx, fz_device *dev, fz_shade *shade, const fz_ma
buf = fz_new_buffer_from_pixmap_as_png(ctx, pix);
if (alpha != 1.0f)
fz_printf(ctx, out, "<g opacity=\"%g\">\n", alpha);
- fz_printf(ctx, out, "<image x=\"%dpx\" y=\"%dpx\" width=\"%dpx\" height=\"%dpx\" xlink:href=\"data:image/png;base64,", pix->x, pix->y, pix->w, pix->h);
+ fz_printf(ctx, out, "<image x=\"%d\" y=\"%d\" width=\"%d\" height=\"%d\" xlink:href=\"data:image/png;base64,", pix->x, pix->y, pix->w, pix->h);
send_data_base64(ctx, out, buf);
fz_printf(ctx, out, "\"/>\n");
if (alpha != 1.0f)
@@ -1198,7 +1203,7 @@ svg_dev_drop_device(fz_context *ctx, fz_device *dev)
fz_free(ctx, sdev->images);
}
-fz_device *fz_new_svg_device(fz_context *ctx, fz_output *out, float page_width, float page_height, int text_format)
+fz_device *fz_new_svg_device(fz_context *ctx, fz_output *out, float page_width, float page_height, int text_format, int reuse_images)
{
svg_device *dev = fz_new_device(ctx, sizeof *dev);
@@ -1237,13 +1242,14 @@ fz_device *fz_new_svg_device(fz_context *ctx, fz_output *out, float page_width,
dev->out_store = out;
dev->id = 0;
dev->text_as_text = (text_format == FZ_SVG_TEXT_AS_TEXT);
+ dev->reuse_images = reuse_images;
fz_printf(ctx, out, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n");
fz_printf(ctx, out, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n");
fz_printf(ctx, out, "<svg xmlns=\"http://www.w3.org/2000/svg\" "
"xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\" "
- "width=\"%gcm\" height=\"%gcm\" viewBox=\"0 0 %g %g\">\n",
- page_width*2.54/72, page_height*2.54/72, page_width, page_height);
+ "width=\"%gpt\" height=\"%gpt\" viewBox=\"0 0 %g %g\">\n",
+ page_width, page_height, page_width, page_height);
return (fz_device*)dev;
}