diff options
Diffstat (limited to 'source/fitz/svg-device.c')
-rw-r--r-- | source/fitz/svg-device.c | 214 |
1 files changed, 117 insertions, 97 deletions
diff --git a/source/fitz/svg-device.c b/source/fitz/svg-device.c index 4461f79e..a2cc5ed1 100644 --- a/source/fitz/svg-device.c +++ b/source/fitz/svg-device.c @@ -238,82 +238,86 @@ svg_dev_text(fz_context *ctx, svg_device *sdev, const fz_matrix *ctm, fz_text *t fz_matrix local_trm; float size; int start, is_wspace, was_wspace; + fz_text_span *span; - /* Rely on the fact that trm.{e,f} == 0 */ - size = fz_matrix_expansion(&text->trm); - local_trm.a = text->trm.a / size; - local_trm.b = text->trm.b / size; - local_trm.c = -text->trm.c / size; - local_trm.d = -text->trm.d / size; - local_trm.e = 0; - local_trm.f = 0; - fz_invert_matrix(&inverse, &local_trm); - fz_concat(&local_trm, &local_trm, ctm); + for (span = text->head; text; span = span->next) + { + /* Rely on the fact that trm.{e,f} == 0 */ + size = fz_matrix_expansion(&span->trm); + local_trm.a = span->trm.a / size; + local_trm.b = span->trm.b / size; + local_trm.c = -span->trm.c / size; + local_trm.d = -span->trm.d / size; + local_trm.e = 0; + local_trm.f = 0; + fz_invert_matrix(&inverse, &local_trm); + fz_concat(&local_trm, &local_trm, ctm); - fz_printf(ctx, out, " transform=\"matrix(%g,%g,%g,%g,%g,%g)\"", - local_trm.a, local_trm.b, local_trm.c, local_trm.d, local_trm.e, local_trm.f); - fz_printf(ctx, out, " font-size=\"%g\"", size); - fz_printf(ctx, out, " font-family=\"%s\"", text->font->name); + fz_printf(ctx, out, " transform=\"matrix(%g,%g,%g,%g,%g,%g)\"", + local_trm.a, local_trm.b, local_trm.c, local_trm.d, local_trm.e, local_trm.f); + fz_printf(ctx, out, " font-size=\"%g\"", size); + fz_printf(ctx, out, " font-family=\"%s\"", span->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_xml_wspace(it->ucs)) - break; - } + /* Leading (and repeated) whitespace presents a problem for SVG + * text, so elide it here. */ + for (start=0; start < span->len; start++) + { + fz_text_item *it = &span->items[start]; + if (!is_xml_wspace(it->ucs)) + break; + } - fz_printf(ctx, out, " x="); - was_wspace = 0; - for (i=start; i < text->len; i++) - { - fz_text_item *it = &text->items[i]; - fz_point p; - is_wspace = is_xml_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(ctx, out, "%c%g", i == start ? '\"' : ' ', p.x); - } - fz_printf(ctx, out, "\" y="); - was_wspace = 0; - for (i=start; i < text->len; i++) - { - fz_text_item *it = &text->items[i]; - fz_point p; - is_wspace = is_xml_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(ctx, out, "%c%g", i == start ? '\"' : ' ', p.y); - } - fz_printf(ctx, out, "\">\n"); - was_wspace = 0; - for (i=start; i < text->len; i++) - { - fz_text_item *it = &text->items[i]; - int c = it->ucs; - is_wspace = is_xml_wspace(c); - if (is_wspace && was_wspace) - continue; - was_wspace = is_wspace; - if (c >= 32 && c <= 127 && c != '<' && c != '&') - fz_printf(ctx, out, "%c", c); - else - fz_printf(ctx, out, "&#x%04x;", c); + fz_printf(ctx, out, " x="); + was_wspace = 0; + for (i=start; i < span->len; i++) + { + fz_text_item *it = &span->items[i]; + fz_point p; + is_wspace = is_xml_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(ctx, out, "%c%g", i == start ? '\"' : ' ', p.x); + } + fz_printf(ctx, out, "\" y="); + was_wspace = 0; + for (i=start; i < span->len; i++) + { + fz_text_item *it = &span->items[i]; + fz_point p; + is_wspace = is_xml_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(ctx, out, "%c%g", i == start ? '\"' : ' ', p.y); + } + fz_printf(ctx, out, "\">\n"); + was_wspace = 0; + for (i=start; i < span->len; i++) + { + fz_text_item *it = &span->items[i]; + int c = it->ucs; + is_wspace = is_xml_wspace(c); + if (is_wspace && was_wspace) + continue; + was_wspace = is_wspace; + if (c >= 32 && c <= 127 && c != '<' && c != '&') + fz_printf(ctx, out, "%c", c); + else + fz_printf(ctx, out, "&#x%04x;", c); + } + fz_printf(ctx, out, "\n</text>\n"); } - fz_printf(ctx, out, "\n</text>\n"); } static font * -svg_dev_text_as_paths_defs(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matrix *ctm) +svg_dev_text_span_as_paths_defs(fz_context *ctx, fz_device *dev, fz_text_span *span, const fz_matrix *ctm) { svg_device *sdev = (svg_device*)dev; fz_output *out = sdev->out; @@ -323,7 +327,7 @@ svg_dev_text_as_paths_defs(fz_context *ctx, fz_device *dev, fz_text *text, const for (font_idx = 0; font_idx < sdev->num_fonts; font_idx++) { - if (sdev->fonts[font_idx].font == text->font) + if (sdev->fonts[font_idx].font == span->font) break; } if (font_idx == sdev->num_fonts) @@ -339,14 +343,14 @@ svg_dev_text_as_paths_defs(fz_context *ctx, fz_device *dev, fz_text *text, const sdev->max_fonts = newmax; } sdev->fonts[font_idx].id = sdev->id++; - sdev->fonts[font_idx].font = fz_keep_font(ctx, text->font); + sdev->fonts[font_idx].font = fz_keep_font(ctx, span->font); sdev->num_fonts++; } fnt = &sdev->fonts[font_idx]; - for (i=0; i < text->len; i++) + for (i=0; i < span->len; i++) { - fz_text_item *it = &text->items[i]; + fz_text_item *it = &span->items[i]; int gid = it->gid; if (gid < 0) @@ -367,7 +371,7 @@ svg_dev_text_as_paths_defs(fz_context *ctx, fz_device *dev, fz_text *text, const /* Need to send this one */ fz_rect rect; fz_path *path; - path = fz_outline_glyph(ctx, text->font, gid, &fz_identity); + path = fz_outline_glyph(ctx, span->font, gid, &fz_identity); if (path) { fz_bound_path(ctx, path, NULL, &fz_identity, &rect); @@ -382,12 +386,12 @@ svg_dev_text_as_paths_defs(fz_context *ctx, fz_device *dev, fz_text *text, const } else { - fz_bound_glyph(ctx, text->font, gid, &fz_identity, &rect); + fz_bound_glyph(ctx, span->font, gid, &fz_identity, &rect); shift.e = -rect.x0; shift.f = -rect.y0; out = start_def(ctx, sdev); fz_printf(ctx, out, "<symbol id=\"font_%x_%x\">", fnt->id, gid); - fz_run_t3_glyph(ctx, text->font, gid, &shift, dev); + fz_run_t3_glyph(ctx, span->font, gid, &shift, dev); } fz_printf(ctx, out, "</symbol>"); out = end_def(ctx, sdev); @@ -399,7 +403,7 @@ svg_dev_text_as_paths_defs(fz_context *ctx, fz_device *dev, fz_text *text, const } static void -svg_dev_text_as_paths_fill(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matrix *ctm, +svg_dev_text_span_as_paths_fill(fz_context *ctx, fz_device *dev, fz_text_span *span, const fz_matrix *ctm, fz_colorspace *colorspace, float *color, float alpha, font *fnt) { svg_device *sdev = (svg_device*)dev; @@ -410,16 +414,16 @@ svg_dev_text_as_paths_fill(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matrix shift = { 1, 0, 0, 1, 0, 0}; /* Rely on the fact that trm.{e,f} == 0 */ - local_trm.a = text->trm.a; - local_trm.b = text->trm.b; - local_trm.c = text->trm.c; - local_trm.d = text->trm.d; + local_trm.a = span->trm.a; + local_trm.b = span->trm.b; + local_trm.c = span->trm.c; + local_trm.d = span->trm.d; local_trm.e = 0; local_trm.f = 0; - for (i=0; i < text->len; i++) + for (i=0; i < span->len; i++) { - fz_text_item *it = &text->items[i]; + fz_text_item *it = &span->items[i]; int gid = it->gid; if (gid < 0) @@ -439,7 +443,7 @@ svg_dev_text_as_paths_fill(fz_context *ctx, fz_device *dev, fz_text *text, const } static void -svg_dev_text_as_paths_stroke(fz_context *ctx, fz_device *dev, fz_text *text, +svg_dev_text_span_as_paths_stroke(fz_context *ctx, fz_device *dev, fz_text_span *span, fz_stroke_state *stroke, const fz_matrix *ctm, fz_colorspace *colorspace, float *color, float alpha, font *fnt) { @@ -451,16 +455,16 @@ svg_dev_text_as_paths_stroke(fz_context *ctx, fz_device *dev, fz_text *text, fz_matrix shift = { 1, 0, 0, 1, 0, 0}; /* Rely on the fact that trm.{e,f} == 0 */ - local_trm.a = text->trm.a; - local_trm.b = text->trm.b; - local_trm.c = text->trm.c; - local_trm.d = text->trm.d; + local_trm.a = span->trm.a; + local_trm.b = span->trm.b; + local_trm.c = span->trm.c; + local_trm.d = span->trm.d; local_trm.e = 0; local_trm.f = 0; - for (i=0; i < text->len; i++) + for (i=0; i < span->len; i++) { - fz_text_item *it = &text->items[i]; + fz_text_item *it = &span->items[i]; int gid = it->gid; if (gid < 0) @@ -566,12 +570,16 @@ svg_dev_fill_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matri fz_output *out = sdev->out; font *fnt; + fz_text_span *span; fz_printf(ctx, out, "<text"); svg_dev_fill_color(ctx, sdev, colorspace, color, 0.0f); svg_dev_text(ctx, sdev, ctm, text); - fnt = svg_dev_text_as_paths_defs(ctx, dev, text, ctm); - svg_dev_text_as_paths_fill(ctx, dev, text, ctm, colorspace, color, alpha, fnt); + for (span = text->head; span; span = span->next) + { + fnt = svg_dev_text_span_as_paths_defs(ctx, dev, span, ctm); + svg_dev_text_span_as_paths_fill(ctx, dev, span, ctm, colorspace, color, alpha, fnt); + } } static void @@ -582,12 +590,16 @@ svg_dev_stroke_text(fz_context *ctx, fz_device *dev, fz_text *text, fz_stroke_st fz_output *out = sdev->out; font *fnt; + fz_text_span *span; fz_printf(ctx, out, "<text"); svg_dev_fill_color(ctx, sdev, colorspace, color, 0.0f); svg_dev_text(ctx, sdev, ctm, text); - fnt = svg_dev_text_as_paths_defs(ctx, dev, text, ctm); - svg_dev_text_as_paths_stroke(ctx, dev, text, stroke, ctm, colorspace, color, alpha, fnt); + for (span = text->head; span; span = span->next) + { + fnt = svg_dev_text_span_as_paths_defs(ctx, dev, span, ctm); + svg_dev_text_span_as_paths_stroke(ctx, dev, span, stroke, ctm, colorspace, color, alpha, fnt); + } } static void @@ -600,6 +612,7 @@ svg_dev_clip_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matri int num = sdev->id++; float white[3] = { 1, 1, 1 }; font *fnt; + fz_text_span *span; fz_bound_text(ctx, text, NULL, ctm, &bounds); @@ -609,8 +622,11 @@ svg_dev_clip_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matri fz_printf(ctx, out, "<text"); svg_dev_fill_color(ctx, sdev, fz_device_rgb(ctx), white, 0.0f); svg_dev_text(ctx, sdev, ctm, text); - fnt = svg_dev_text_as_paths_defs(ctx, dev, text, ctm); - svg_dev_text_as_paths_fill(ctx, dev, text, ctm, fz_device_rgb(ctx), white, 1.0f, fnt); + for (span = text->head; span; span = span->next) + { + fnt = svg_dev_text_span_as_paths_defs(ctx, dev, span, ctm); + svg_dev_text_span_as_paths_fill(ctx, dev, span, ctm, fz_device_rgb(ctx), white, 1.0f, fnt); + } fz_printf(ctx, out, "</mask>\n"); out = end_def(ctx, sdev); fz_printf(ctx, out, "<g mask=\"url(#ma%d)\">\n", num); @@ -626,6 +642,7 @@ svg_dev_clip_stroke_text(fz_context *ctx, fz_device *dev, fz_text *text, fz_stro int num = sdev->id++; float white[3] = { 255, 255, 255 }; font *fnt; + fz_text_span *span; fz_bound_text(ctx, text, NULL, ctm, &bounds); @@ -636,8 +653,11 @@ svg_dev_clip_stroke_text(fz_context *ctx, fz_device *dev, fz_text *text, fz_stro svg_dev_stroke_state(ctx, sdev, stroke, &fz_identity); svg_dev_stroke_color(ctx, sdev, fz_device_rgb(ctx), white, 0.0f); svg_dev_text(ctx, sdev, ctm, text); - fnt = svg_dev_text_as_paths_defs(ctx, dev, text, ctm); - svg_dev_text_as_paths_stroke(ctx, dev, text, stroke, ctm, fz_device_rgb(ctx), white, 1.0f, fnt); + for (span = text->head; span; span = span->next) + { + fnt = svg_dev_text_span_as_paths_defs(ctx, dev, span, ctm); + svg_dev_text_span_as_paths_stroke(ctx, dev, span, stroke, ctm, fz_device_rgb(ctx), white, 1.0f, fnt); + } fz_printf(ctx, out, "</mask>\n"); out = end_def(ctx, sdev); fz_printf(ctx, out, "<g mask=\"url(#ma%d)\">\n", num); |