summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2013-07-25 16:18:55 +0100
committerRobin Watts <robin.watts@artifex.com>2013-07-25 16:42:08 +0100
commit1b7709d17557e8364715b559f43b84838effe8c1 (patch)
tree8d30a89a77f43c5271739dabe9f4e82a2bfcf5db /source
parente02d137f205bcf3c5e79128762e6dcff51ad5945 (diff)
downloadmupdf-1b7709d17557e8364715b559f43b84838effe8c1.tar.xz
Bug 694402: Fix various SVG output problems
Images were missing a space, hence giving errors. SVG text gets confused by leading (and repeated) whitespace, so elide it.
Diffstat (limited to 'source')
-rw-r--r--source/fitz/svg-device.c68
1 files changed, 62 insertions, 6 deletions
diff --git a/source/fitz/svg-device.c b/source/fitz/svg-device.c
index 4dd82120..902a606c 100644
--- a/source/fitz/svg-device.c
+++ b/source/fitz/svg-device.c
@@ -148,6 +148,37 @@ svg_dev_stroke_color(svg_device *sdev, fz_colorspace *colorspace, float *color,
fz_printf(out, " stroke-opacity=\"%g\"", alpha);
}
+static inline int
+is_unicode_wspace(int c)
+{
+ return (c == 9 || /* TAB */
+ c == 0x0a || /* HT */
+ c == 0x0b || /* LF */
+ c == 0x0c || /* VT */
+ c == 0x0d || /* FF */
+ c == 0x20 || /* CR */
+ c == 0x85 || /* NEL */
+ c == 0xA0 || /* No break space */
+ c == 0x1680 || /* Ogham space mark */
+ c == 0x180E || /* Mongolian Vowel Separator */
+ c == 0x2000 || /* En quad */
+ c == 0x2001 || /* Em quad */
+ c == 0x2002 || /* En space */
+ c == 0x2003 || /* Em space */
+ c == 0x2004 || /* Three-per-Em space */
+ c == 0x2005 || /* Four-per-Em space */
+ c == 0x2006 || /* Five-per-Em space */
+ c == 0x2007 || /* Figure space */
+ c == 0x2008 || /* Punctuation space */
+ c == 0x2009 || /* Thin space */
+ c == 0x200A || /* Hair space */
+ c == 0x2028 || /* Line separator */
+ c == 0x2029 || /* Paragraph separator */
+ c == 0x202F || /* Narrow no-break space */
+ c == 0x205F || /* Medium mathematical space */
+ c == 0x3000); /* Ideographic space */
+}
+
static void
svg_dev_text(svg_device *sdev, const fz_matrix *ctm, fz_text *text)
{
@@ -156,6 +187,7 @@ svg_dev_text(svg_device *sdev, const fz_matrix *ctm, fz_text *text)
fz_matrix inverse;
fz_matrix local_trm;
float size;
+ int start, is_wspace, was_wspace;
/* Rely on the fact that trm.{e,f} == 0 */
size = fz_matrix_expansion(&text->trm);
@@ -173,31 +205,55 @@ svg_dev_text(svg_device *sdev, const fz_matrix *ctm, fz_text *text)
fz_printf(out, " font-size=\"%g\"", size);
fz_printf(out, " font-family=\"%s\"", text->font->name);
+ /* Leading (and repeated) whitespace presents a problem for SVG
+ * text, so elide it here. */
+ for (start=0; start < text->len; start++)
+ {
+ fz_text_item *it = &text->items[start];
+ if (!is_unicode_wspace(it->ucs))
+ break;
+ }
+
fz_printf(out, " x=");
- for (i=0; i < text->len; i++)
+ was_wspace = 0;
+ for (i=start; i < text->len; i++)
{
fz_text_item *it = &text->items[i];
fz_point p;
+ is_wspace = is_unicode_wspace(it->ucs);
+ if (is_wspace && was_wspace)
+ continue;
+ was_wspace = is_wspace;
p.x = it->x;
p.y = it->y;
fz_transform_point(&p, &inverse);
- fz_printf(out, "%c%g", i == 0 ? '\"' : ' ', p.x);
+ fz_printf(out, "%c%g", i == start ? '\"' : ' ', p.x);
}
fz_printf(out, "\" y=");
- for (i=0; i < text->len; i++)
+ was_wspace = 0;
+ for (i=start; i < text->len; i++)
{
fz_text_item *it = &text->items[i];
fz_point p;
+ is_wspace = is_unicode_wspace(it->ucs);
+ if (is_wspace && was_wspace)
+ continue;
+ was_wspace = is_wspace;
p.x = it->x;
p.y = it->y;
fz_transform_point(&p, &inverse);
- fz_printf(out, "%c%g", i == 0 ? '\"' : ' ', p.y);
+ fz_printf(out, "%c%g", i == start ? '\"' : ' ', p.y);
}
fz_printf(out, "\">\n");
- for (i=0; i < text->len; i++)
+ was_wspace = 0;
+ for (i=start; i < text->len; i++)
{
fz_text_item *it = &text->items[i];
int c = it->ucs;
+ is_wspace = is_unicode_wspace(c);
+ if (is_wspace && was_wspace)
+ continue;
+ was_wspace = is_wspace;
if (c >= 32 && c <= 127 && c != '<' && c != '&')
fz_printf(out, "%c", c);
else
@@ -399,7 +455,7 @@ svg_dev_fill_image(fz_device *dev, fz_image *image, const fz_matrix *ctm, float
fz_concat(&local_ctm, &scale, ctm);
fz_printf(out, "<image");
svg_dev_ctm(sdev, &local_ctm);
- fz_printf(out, "width=\"%dpx\" height=\"%dpx\" xlink:href=\"data:", image->w, image->h);
+ fz_printf(out, " width=\"%dpx\" height=\"%dpx\" xlink:href=\"data:", image->w, image->h);
switch (image->buffer == NULL ? FZ_IMAGE_JPX : image->buffer->params.type)
{
case FZ_IMAGE_JPEG: