static void svg_dev_clip_text(fz_context *ctx, fz_device *dev, fz_text *text, const fz_matrix *ctm) { svg_device *sdev = (svg_device*)dev; fz_output *out = sdev->out; fz_rect bounds; int num = sdev->id++; float white[3] = { 1, 1, 1 }; font *fnt; fz_text_span *span; fz_bound_text(ctx, text, NULL, ctm, &bounds); out = start_def(ctx, sdev); fz_printf(ctx, out, "<mask id=\"ma%d\" x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" maskUnits=\"userSpaceOnUse\" maskContentUnits=\"userSpaceOnUse\">\n", num, bounds.x0, bounds.y0, bounds.x1 - bounds.x0, bounds.y1 - bounds.y0); 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); 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); }
static void svg_dev_clip_text(fz_device *dev, fz_text *text, const fz_matrix *ctm, int accumulate) { svg_device *sdev = dev->user; fz_output *out = sdev->out; fz_context *ctx = dev->ctx; fz_rect bounds; int num = sdev->id++; float white[3] = { 1, 1, 1 }; font *fnt; fz_bound_text(ctx, text, NULL, ctm, &bounds); out = start_def(sdev); fz_printf(out, "<mask id=\"ma%d\" x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\" maskUnits=\"userSpaceOnUse\" maskContentUnits=\"userSpaceOnUse\">\n", num, bounds.x0, bounds.y0, bounds.x1 - bounds.x0, bounds.y1 - bounds.y0); fz_printf(out, "<text"); svg_dev_fill_color(sdev, fz_device_rgb(ctx), white, 0.0f); svg_dev_text(sdev, ctm, text); fnt = svg_dev_text_as_paths_defs(dev, text, ctm); svg_dev_text_as_paths_fill(dev, text, ctm, fz_device_rgb(ctx), white, 1.0f, fnt); fz_printf(out, "</mask>\n"); out = end_def(sdev); fz_printf(out, "<g mask=\"url(#ma%d)\">\n", num); }
static void svg_dev_fill_text(fz_device *dev, fz_text *text, const fz_matrix *ctm, fz_colorspace *colorspace, float *color, float alpha) { svg_device *sdev = dev->user; fz_output *out = sdev->out; fz_printf(out, "<text"); svg_dev_fill_color(sdev, colorspace, color, alpha); svg_dev_text(sdev, ctm, text); }
static void svg_dev_ignore_text(fz_device *dev, fz_text *text, const fz_matrix *ctm) { svg_device *sdev = dev->user; fz_output *out = sdev->out; float black[3] = { 0, 0, 0}; fz_printf(out, "<text"); svg_dev_fill_color(sdev, fz_device_rgb(sdev->ctx), black, 0.0f); svg_dev_text(sdev, ctm, text); }
static void svg_dev_stroke_text(fz_device *dev, fz_text *text, fz_stroke_state *stroke, const fz_matrix *ctm, fz_colorspace *colorspace, float *color, float alpha) { svg_device *sdev = dev->user; fz_output *out = sdev->out; font *fnt; fz_printf(out, "<text"); svg_dev_fill_color(sdev, colorspace, color, 0.0f); svg_dev_text(sdev, ctm, text); fnt = svg_dev_text_as_paths_defs(dev, text, ctm); svg_dev_text_as_paths_stroke(dev, text, stroke, ctm, colorspace, color, alpha, fnt); }
static void svg_dev_fill_path(fz_context *ctx, fz_device *dev, fz_path *path, int even_odd, const fz_matrix *ctm, fz_colorspace *colorspace, float *color, float alpha) { svg_device *sdev = (svg_device*)dev; fz_output *out = sdev->out; fz_printf(ctx, out, "<path"); svg_dev_ctm(ctx, sdev, ctm); svg_dev_path(ctx, sdev, path); svg_dev_fill_color(ctx, sdev, colorspace, color, alpha); if (even_odd) fz_printf(ctx, out, " fill-rule=\"evenodd\""); fz_printf(ctx, out, "/>\n"); }
static void svg_dev_ignore_text(fz_context *ctx, fz_device *dev, const fz_text *text, const fz_matrix *ctm) { svg_device *sdev = (svg_device*)dev; fz_output *out = sdev->out; fz_text_span *span; float black[3] = { 0, 0, 0}; for (span = text->head; span; span = span->next) { fz_printf(ctx, out, "<text"); svg_dev_fill_color(ctx, sdev, fz_device_rgb(ctx), black, 0.0f); svg_dev_text_span(ctx, sdev, ctm, span); } }
static void svg_dev_fill_image_mask(fz_context *ctx, fz_device *dev, fz_image *image, const fz_matrix *ctm, fz_colorspace *colorspace, const float *color, float alpha) { svg_device *sdev = (svg_device*)dev; fz_compressed_buffer *buffer; fz_output *out; fz_matrix local_ctm = *ctm; fz_matrix scale = { 0 }; int mask = sdev->id++; scale.a = 1.0f / image->w; scale.d = 1.0f / image->h; fz_concat(&local_ctm, &scale, ctm); out = start_def(ctx, sdev); fz_printf(ctx, out, "<mask id=\"ma%d\"><image", mask); fz_printf(ctx, out, " width=\"%dpx\" height=\"%dpx\" xlink:href=\"data:", image->w, image->h); buffer = fz_compressed_image_buffer(ctx, image); switch (buffer == NULL ? FZ_IMAGE_JPX : buffer->params.type) { case FZ_IMAGE_JPEG: fz_printf(ctx, out, "image/jpeg;base64,"); send_data_base64(ctx, out, buffer->buffer); break; case FZ_IMAGE_PNG: fz_printf(ctx, out, "image/png;base64,"); send_data_base64(ctx, out, buffer->buffer); break; default: { fz_buffer *buf = fz_new_buffer_from_image_as_png(ctx, image); fz_printf(ctx, out, "image/png;base64,"); send_data_base64(ctx, out, buf); fz_drop_buffer(ctx, buf); break; } } fz_printf(ctx, out, "\"/></mask>\n"); out = end_def(ctx, sdev); fz_printf(ctx, out, "<rect x=\"0\" y=\"0\" width=\"%d\" height=\"%d\"", image->w, image->h); svg_dev_fill_color(ctx, sdev, colorspace, color, alpha); svg_dev_ctm(ctx, sdev, &local_ctm); fz_printf(ctx, out, " mask=\"url(#ma%d)\"/>\n", mask); }
static void svg_dev_stroke_text(fz_context *ctx, fz_device *dev, fz_text *text, fz_stroke_state *stroke, const fz_matrix *ctm, fz_colorspace *colorspace, float *color, float alpha) { svg_device *sdev = (svg_device*)dev; 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); 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 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; fz_output *out = sdev->out; fz_matrix local_trm, local_trm2; int i; fz_matrix shift = { 1, 0, 0, 1, 0, 0}; /* Rely on the fact that trm.{e,f} == 0 */ 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 < span->len; i++) { fz_text_item *it = &span->items[i]; int gid = it->gid; if (gid < 0) continue; shift.e = fnt->sentlist[gid].x_off; shift.f = fnt->sentlist[gid].y_off; local_trm.e = it->x; local_trm.f = it->y; fz_concat(&local_trm2, &local_trm, ctm); fz_concat(&local_trm2, &shift, &local_trm2); fz_printf(ctx, out, "<use xlink:href=\"#font_%x_%x\"", fnt->id, gid); svg_dev_ctm(ctx, sdev, &local_trm2); svg_dev_fill_color(ctx, sdev, colorspace, color, alpha); fz_printf(ctx, out, "/>\n"); } }