static void pdf_out_w(fz_context *ctx, pdf_processor *proc, float linewidth) { fz_output *out = ((pdf_output_processor*)proc)->out; if (!((pdf_output_processor*)proc)->extgstate) fz_printf(ctx, out, "%f w\n", linewidth); }
static void pdf_out_j(fz_context *ctx, pdf_processor *proc, int linejoin) { fz_output *out = ((pdf_output_processor*)proc)->out; if (!((pdf_output_processor*)proc)->extgstate) fz_printf(ctx, out, "%d j\n", linejoin); }
static void pdf_out_i(fz_context *ctx, pdf_processor *proc, float flatness) { fz_output *out = ((pdf_output_processor*)proc)->out; if (!((pdf_output_processor*)proc)->extgstate) fz_printf(ctx, out, "%f i\n", flatness); }
static void pdf_out_gs_begin(fz_context *ctx, pdf_processor *proc, const char *name, pdf_obj *extgstate) { fz_output *out = ((pdf_output_processor*)proc)->out; ((pdf_output_processor*)proc)->extgstate = 1; fz_printf(ctx, out, "/%s gs\n", name); }
static void pdf_out_squote(fz_context *ctx, pdf_processor *proc, char *str, int len) { fz_output *out = ((pdf_output_processor*)proc)->out; put_string(ctx, out, (const unsigned char *)str, len); fz_printf(ctx, out, " '\n"); }
static void pdf_out_ri(fz_context *ctx, pdf_processor *proc, const char *intent) { fz_output *out = ((pdf_output_processor*)proc)->out; if (!((pdf_output_processor*)proc)->extgstate) fz_printf(ctx, out, "/%s ri\n", intent); }
static void pdf_out_M(fz_context *ctx, pdf_processor *proc, float a) { fz_output *out = ((pdf_output_processor*)proc)->out; if (!((pdf_output_processor*)proc)->extgstate) fz_printf(ctx, out, "%f M\n", a); }
static void pdf_out_TJ(fz_context *ctx, pdf_processor *proc, pdf_obj *array) { fz_output *out = ((pdf_output_processor*)proc)->out; pdf_output_obj(ctx, out, array, 1); fz_printf(ctx, out, " TJ\n"); }
static void pdf_out_Tf(fz_context *ctx, pdf_processor *proc, const char *name, pdf_font_desc *font, float size) { fz_output *out = ((pdf_output_processor*)proc)->out; if (!((pdf_output_processor*)proc)->extgstate) fz_printf(ctx, out, "/%s %f Tf\n", name, size); }
static void svg_path_lineto(fz_context *ctx, void *arg, float x, float y) { fz_output *out = (fz_output *)arg; fz_printf(ctx, out, "L %g %g ", x, y); }
static void svg_path_close(fz_context *ctx, void *arg) { fz_output *out = (fz_output *)arg; fz_printf(ctx, out, "Z "); }
static void svg_dev_close_device(fz_context *ctx, fz_device *dev) { svg_device *sdev = (svg_device*)dev; fz_output *out = sdev->out; fz_printf(ctx, out, "</svg>\n"); }
static void svg_path_curveto(fz_context *ctx, void *arg, float x1, float y1, float x2, float y2, float x3, float y3) { fz_output *out = (fz_output *)arg; fz_printf(ctx, out, "C %g %g %g %g %g %g ", x1, y1, x2, y2, x3, y3); }
fz_device *fz_new_svg_device(fz_context *ctx, fz_output *out, float page_width, float page_height) { svg_device *dev = fz_new_device(ctx, sizeof *dev); dev->super.drop_imp = svg_dev_drop_imp; dev->super.fill_path = svg_dev_fill_path; dev->super.stroke_path = svg_dev_stroke_path; dev->super.clip_path = svg_dev_clip_path; dev->super.clip_stroke_path = svg_dev_clip_stroke_path; dev->super.fill_text = svg_dev_fill_text; dev->super.stroke_text = svg_dev_stroke_text; dev->super.clip_text = svg_dev_clip_text; dev->super.clip_stroke_text = svg_dev_clip_stroke_text; dev->super.ignore_text = svg_dev_ignore_text; dev->super.fill_shade = svg_dev_fill_shade; dev->super.fill_image = svg_dev_fill_image; dev->super.fill_image_mask = svg_dev_fill_image_mask; dev->super.clip_image_mask = svg_dev_clip_image_mask; dev->super.pop_clip = svg_dev_pop_clip; dev->super.begin_mask = svg_dev_begin_mask; dev->super.end_mask = svg_dev_end_mask; dev->super.begin_group = svg_dev_begin_group; dev->super.end_group = svg_dev_end_group; dev->super.begin_tile = svg_dev_begin_tile; dev->super.end_tile = svg_dev_end_tile; dev->super.hints |= FZ_MAINTAIN_CONTAINER_STACK; dev->out = out; dev->out_store = out; dev->id = 0; fz_printf(ctx, out, "<?xml version=\"1.0\" 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); return (fz_device*)dev; }
static void svg_dev_end_group(fz_device *dev) { svg_device *sdev = (svg_device *)dev->user; fz_output *out = sdev->out; fz_printf(out, "</g>\n"); }
static void svg_dev_end_group(fz_context *ctx, fz_device *dev) { svg_device *sdev = (svg_device*)dev; fz_output *out = sdev->out; fz_printf(ctx, out, "</g>\n"); }
static void svg_dev_stroke_color(fz_context *ctx, svg_device *sdev, fz_colorspace *colorspace, float *color, float alpha) { fz_output *out = sdev->out; float rgb[FZ_MAX_COLORS]; if (colorspace != fz_device_rgb(ctx)) { /* If it's not rgb, make it rgb */ colorspace->to_rgb(ctx, colorspace, color, rgb); color = rgb; } fz_printf(ctx, out, " fill=\"none\" stroke=\"rgb(%d,%d,%d)\"", (int)(255*color[0] + 0.5), (int)(255*color[1] + 0.5), (int)(255*color[2]+0.5)); if (alpha != 1) fz_printf(ctx, out, " stroke-opacity=\"%g\"", alpha); }
static void fz_trace_text_span(fz_context *ctx, fz_output *out, fz_text_span *span) { int i; fz_printf(ctx, out, "<span font=\"%s\" wmode=\"%d\"", span->font->name, span->wmode); fz_printf(ctx, out, " trm=\"%g %g %g %g\">\n", span->trm.a, span->trm.b, span->trm.c, span->trm.d); for (i = 0; i < span->len; i++) { if (!isxmlmeta(span->items[i].ucs)) fz_printf(ctx, out, "<g ucs=\"%c\" gid=\"%d\" x=\"%g\" y=\"%g\" />\n", span->items[i].ucs, span->items[i].gid, span->items[i].x, span->items[i].y); else fz_printf(ctx, out, "<g ucs=\"U+%04X\" gid=\"%d\" x=\"%g\" y=\"%g\" />\n", span->items[i].ucs, span->items[i].gid, span->items[i].x, span->items[i].y); } fz_printf(ctx, out, "</span>\n"); }
static void svg_dev_clip_image_mask(fz_device *dev, fz_image *image, const fz_rect *rect, const fz_matrix *ctm) { svg_device *sdev = dev->user; fz_output *out = sdev->out; fz_printf(out, "<g>\n"); }
static void fz_trace_begin_group(fz_context *ctx, fz_device *dev, const fz_rect *bbox, int isolated, int knockout, int blendmode, float alpha) { fz_output *out = ((fz_trace_device*)dev)->out; fz_printf(ctx, out, "<group bbox=\"%g %g %g %g\" isolated=\"%d\" knockout=\"%d\" blendmode=\"%s\" alpha=\"%g\">\n", bbox->x0, bbox->y0, bbox->x1, bbox->y1, isolated, knockout, fz_blendmode_name(blendmode), alpha); }
static void svg_dev_begin_group(fz_context *ctx, fz_device *dev, const fz_rect *bbox, int isolated, int knockout, int blendmode, float alpha) { svg_device *sdev = (svg_device*)dev; fz_output *out = sdev->out; /* SVG 1.1 doesn't support adequate blendmodes/knockout etc, so just ignore it for now */ fz_printf(ctx, out, "<g>\n"); }
static void svg_dev_pop_clip(fz_context *ctx, fz_device *dev) { svg_device *sdev = (svg_device*)dev; fz_output *out = sdev->out; /* FIXME */ fz_printf(ctx, out, "</g>\n"); }
static void svg_dev_clip_path(fz_device *dev, fz_path *path, const fz_rect *rect, int even_odd, const fz_matrix *ctm) { svg_device *sdev = dev->user; fz_output *out; int num = sdev->id++; out = start_def(sdev); fz_printf(out, "<clipPath id=\"cp%d\">\n", num); fz_printf(out, "<path"); svg_dev_ctm(sdev, ctm); svg_dev_path(sdev, path); if (even_odd) fz_printf(out, " fill-rule=\"evenodd\""); fz_printf(out, "/>\n</clipPath>\n"); out = end_def(sdev); fz_printf(out, "<g clip-path=\"url(#cp%d)\">\n", num); }
static void svg_dev_pop_clip(fz_device *dev) { svg_device *sdev = (svg_device *)dev->user; fz_output *out = sdev->out; /* FIXME */ fz_printf(out, "</g>\n"); }
static void svg_dev_fill_shade(fz_context *ctx, fz_device *dev, fz_shade *shade, const fz_matrix *ctm, float alpha) { svg_device *sdev = (svg_device*)dev; fz_output *out = sdev->out; fz_rect rect; fz_irect bbox; fz_pixmap *pix; fz_buffer *buf = NULL; fz_var(buf); if (dev->container_len == 0) return; fz_round_rect(&bbox, fz_intersect_rect(fz_bound_shade(ctx, shade, ctm, &rect), &dev->container[dev->container_len-1].scissor)); if (fz_is_empty_irect(&bbox)) return; pix = fz_new_pixmap_with_bbox(ctx, fz_device_rgb(ctx), &bbox); fz_clear_pixmap(ctx, pix); fz_try(ctx) { fz_paint_shade(ctx, shade, ctm, pix, &bbox); buf = fz_new_buffer_from_pixmap_as_png(ctx, pix); if (alpha != 1.0f) fz_printf(ctx, out, "<g opacity=\"%g\">", 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); send_data_base64(ctx, out, buf); fz_printf(ctx, out, "\"/>\n"); if (alpha != 1.0f) fz_printf(ctx, out, "</g>"); } fz_always(ctx) { fz_drop_buffer(ctx, buf); fz_drop_pixmap(ctx, pix); } fz_catch(ctx) { fz_rethrow(ctx); } }
static void pdf_out_d(fz_context *ctx, pdf_processor *proc, pdf_obj *array, float phase) { fz_output *out = ((pdf_output_processor*)proc)->out; if (!((pdf_output_processor*)proc)->extgstate) { pdf_print_obj(ctx, out, array, 1); fz_printf(ctx, out, " %f d\n", phase); } }
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] = { 255, 255, 255 }; fz_bound_text(ctx, text, NULL, ctm, &bounds); 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, 1.0f); svg_dev_text(sdev, ctm, text); fz_printf(out, "</mask>\n<g mask=\"url(#ma%d)\">\n", num); }
static void svg_dev_end_tile(fz_device *dev) { svg_device *sdev = (svg_device *)dev->user; fz_output *out = sdev->out; int num; tile *t; if (sdev->num_tiles == 0) return; num = --sdev->num_tiles; t = &sdev->tiles[num]; fz_printf(out, "</g>\n</pattern>\n"); fz_printf(out, "<rect"); svg_dev_ctm(sdev, &t->ctm); fz_printf(out, " fill=\"url(#pa%d)\" x=\"%g\" y=\"%g\" width=\"%g\" height=\"%g\"/>\n", t->pattern, t->area.x0, t->area.y0, t->area.x1 - t->area.x0, t->area.y1 - t->area.y0); }
static void do_debug_outline_xml(fz_output *out, fz_outline *outline, int level) { while (outline) { fz_printf(out, "<outline title=\"%s\" page=\"%d\"", outline->title, outline->dest.kind == FZ_LINK_GOTO ? outline->dest.ld.gotor.page + 1 : 0); if (outline->down) { fz_printf(out, ">\n"); do_debug_outline_xml(out, outline->down, level + 1); fz_printf(out, "</outline>\n"); } else { fz_printf(out, " />\n"); } outline = outline->next; } }
static void pdf_print_key(fz_context *ctx, fz_output *out, void *key_) { pdf_obj *key = (pdf_obj *)key_; if (pdf_is_indirect(ctx, key)) fz_printf(ctx, out, "(%d %d R) ", pdf_to_num(ctx, key), pdf_to_gen(ctx, key)); else pdf_print_obj(ctx, out, key, 0); }