static pdf_obj *draw_check_button(fz_context *ctx, pdf_annot *annot, fz_rect bbox, fz_matrix matrix, float w, float h, int yes) { float black[3] = { 0, 0, 0 }; pdf_obj *ap, *res = NULL; fz_buffer *buf; float b; fz_var(res); buf = fz_new_buffer(ctx, 1024); fz_try(ctx) { fz_append_string(ctx, buf, "q\n"); if (pdf_write_MK_BG_appearance(ctx, annot, buf)) fz_append_printf(ctx, buf, "0 0 %g %g re\nf\n", w, h); b = pdf_write_border_appearance(ctx, annot, buf); if (b > 0 && pdf_write_MK_BC_appearance(ctx, annot, buf)) fz_append_printf(ctx, buf, "%g %g %g %g re\nS\n", b/2, b/2, w-b, h-b); if (yes) write_variable_text(ctx, annot, buf, &res, "3", "ZaDb", h, black, 0, w, h, b+h/10, 0.8f, 1.2f, 0, 0, 0); fz_append_string(ctx, buf, "Q\n"); ap = pdf_new_xobject(ctx, annot->page->doc, bbox, matrix, res, buf); } fz_always(ctx) { pdf_drop_obj(ctx, res); fz_drop_buffer(ctx, buf); } fz_catch(ctx) fz_rethrow(ctx); return ap; }
static pdf_obj *draw_radio_button(fz_context *ctx, pdf_annot *annot, fz_rect bbox, fz_matrix matrix, float w, float h, int yes) { pdf_obj *ap; fz_buffer *buf; float b; buf = fz_new_buffer(ctx, 1024); fz_try(ctx) { fz_append_string(ctx, buf, "q\n"); if (pdf_write_MK_BG_appearance(ctx, annot, buf)) draw_circle_in_box(ctx, buf, "f\n", 0, 0, 0, w, h); b = pdf_write_border_appearance(ctx, annot, buf); if (b > 0 && pdf_write_MK_BC_appearance(ctx, annot, buf)) draw_circle_in_box(ctx, buf, "s\n", b, 0, 0, w, h); if (yes) { fz_append_string(ctx, buf, "0 g\n"); draw_circle(ctx, buf, "f\n", (w-b*2)/4, (h-b*2)/4, w/2, h/2); } fz_append_string(ctx, buf, "Q\n"); ap = pdf_new_xobject(ctx, annot->page->doc, bbox, matrix, NULL, buf); } fz_always(ctx) fz_drop_buffer(ctx, buf); fz_catch(ctx) fz_rethrow(ctx); return ap; }
static pdf_obj *draw_push_button(fz_context *ctx, pdf_annot *annot, fz_rect bbox, fz_matrix matrix, float w, float h, const char *caption, const char *font, float size, float color[3], int down) { pdf_obj *ap, *res = NULL; fz_buffer *buf; float bc[3] = { 0, 0, 0 }; float bg[3] = { 0.8f, 0.8f, 0.8f }; float hi[3], sh[3]; int has_bg, has_bc; float b; int i; buf = fz_new_buffer(ctx, 1024); fz_var(res); fz_try(ctx) { b = pdf_annot_border(ctx, annot); has_bc = pdf_annot_MK_BC_rgb(ctx, annot, bc); has_bg = pdf_annot_MK_BG_rgb(ctx, annot, bg); for (i = 0; i < 3; ++i) { if (down) { sh[i] = 1 - (1 - bg[i]) / 2; hi[i] = bg[i] / 2; } else { hi[i] = 1 - (1 - bg[i]) / 2; sh[i] = bg[i] / 2; } } fz_append_string(ctx, buf, "q\n"); fz_append_printf(ctx, buf, "%g w\n", b); if (has_bg) { fz_append_printf(ctx, buf, "%g %g %g rg\n", bg[0], bg[1], bg[2]); fz_append_printf(ctx, buf, "0 0 %g %g re\nf\n", 0, 0, w, h); } if (has_bc && b > 0) { fz_append_printf(ctx, buf, "%g %g %g RG\n", bc[0], bc[1], bc[2]); fz_append_printf(ctx, buf, "%g %g %g %g re\nS\n", b/2, b/2, w-b, h-b); } if (has_bg) { fz_append_printf(ctx, buf, "%g %g %g rg\n", hi[0], hi[1], hi[2]); fz_append_printf(ctx, buf, "%g %g m %g %g l %g %g l %g %g l %g %g l %g %g l f\n", b, b, b, h-b, w-b, h-b, w-b-2, h-b-2, b+2, h-b-2, b+2, b+2); fz_append_printf(ctx, buf, "%g %g %g rg\n", sh[0], sh[1], sh[2]); fz_append_printf(ctx, buf, "%g %g m %g %g l %g %g l %g %g l %g %g l %g %g l f\n", b, b, b+2, b+2, w-b-2, b+2, w-b-2, h-b-2, w-b, h-b, w-b, b); } if (down) fz_append_string(ctx, buf, "1 0 0 1 2 -2 cm\n"); write_variable_text(ctx, annot, buf, &res, caption, font, size, color, 1, w, h, b+6, 0.8f, 1.2f, 0, 0, 0); fz_append_string(ctx, buf, "Q\n"); ap = pdf_new_xobject(ctx, annot->page->doc, bbox, matrix, res, buf); } fz_always(ctx) { pdf_drop_obj(ctx, res); fz_drop_buffer(ctx, buf); } fz_catch(ctx) fz_rethrow(ctx); return ap; }
void pdf_put_image(PDF *p, int im, pdf_bool firststrip) { id length_id; long length; pdf_image *image; int i; image = &p->images[im]; /* york: how to check? see also F-imagecolor! switch (image->colorspace) { case ImageMask: case DeviceGray: case Indexed: case DeviceRGB: case DeviceCMYK: break; default: pdf_error(p, PDF_SystemError, "Unknown color space"); break; } */ /* Images may also be written to the output before the first page */ if (PDF_GET_STATE(p) == pdf_state_page) pdf_end_contents_section(p); /* Image object */ image->no = pdf_new_xobject(p, image_xobject, NEW_ID); pdf_begin_dict(p); /* XObject */ pdf_puts(p, "/Type/XObject\n"); pdf_puts(p, "/Subtype/Image\n"); pdf_printf(p,"/Width %d\n", (int) image->width); pdf_printf(p,"/Height %d\n", (int) image->height); pdf_printf(p,"/BitsPerComponent %d\n", image->bpc); /* * Transparency handling */ /* Masking by color: single transparent color value */ if (image->transparent) { if (image->colorspace == Indexed || image->colorspace == DeviceGray) pdf_printf(p,"/Mask[%d %d]\n", (int) image->transval[0], (int) image->transval[0]); else if (image->colorspace == DeviceRGB) pdf_printf(p,"/Mask[%d %d %d %d %d %d]\n", (int) image->transval[0], (int) image->transval[0], (int) image->transval[1], (int) image->transval[1], (int) image->transval[2], (int) image->transval[2]); else if (image->colorspace == DeviceCMYK) pdf_printf(p,"/Mask[%d %d %d %d %d %d %d %d]\n", (int) image->transval[0], (int) image->transval[0], (int) image->transval[1], (int) image->transval[1], (int) image->transval[2], (int) image->transval[2], (int) image->transval[3], (int) image->transval[3]); else pdf_error(p, PDF_SystemError, "Unknown color space with transparency"); /* Masking by position: separate bitmap mask */ } else if (image->mask != -1) { pdf_printf(p, "/Mask %ld 0 R\n", p->xobjects[p->images[image->mask].no].obj_id); } switch (image->colorspace) { case ImageMask: pdf_puts(p, "/ImageMask true\n"); break; case Indexed: if (firststrip) image->colormap_id = pdf_alloc_id(p); pdf_puts(p, "/ColorSpace[/Indexed/DeviceRGB "); pdf_printf(p, "%d %ld 0 R]\n", image->palette_size - 1, image->colormap_id); break; default: /* colorize the image with a spot color */ if (image->colorspace >= LastCS) { /* TODO: reconsider spot color numbering scheme */ int spot = image->colorspace - LastCS; p->colorspaces[spot].used_on_current_page = pdf_true; pdf_printf(p, "/ColorSpace %ld 0 R\n", p->colorspaces[spot].obj_id); /* the following is tricky: /Separation color space * always works as a subtractive color space. The * image, however, is Grayscale, and therefore * additive. */ if (firststrip) { image->invert = !image->invert; } } else { pdf_printf(p, "/ColorSpace/%s\n", pdf_colorspace_names[image->colorspace]); } break; } /* special case: referenced image data instead of direct data */ if (image->reference != pdf_ref_direct) { if (image->compression != none) { pdf_printf(p, "/FFilter[/%s]\n", pdf_filter_names[image->compression]); } if (image->compression == ccitt) { pdf_puts(p, "/FDecodeParms[<<"); if ((int) image->width != 1728) /* CCITT default width */ pdf_printf(p, "/Columns %d", (int) image->width); pdf_printf(p, "/Rows %d", (int) image->height); /* write CCITT parameters if required */ if (image->params) pdf_puts(p, image->params); pdf_puts(p, ">>]\n"); } if (image->reference == pdf_ref_file) { /* LATER: make image file name platform-neutral: * Change : to / on the Mac * Change \ to / on Windows */ pdf_printf(p, "/F(%s)/Length 0", image->filename); } else if (image->reference == pdf_ref_url) { pdf_printf(p, "/F<</FS/URL/F(%s)>>/Length 0", image->filename); } pdf_end_dict(p); /* XObject */ pdf_begin_stream(p); /* dummy image data */ pdf_end_stream(p); /* dummy image data */ if (PDF_GET_STATE(p) == pdf_state_page) pdf_begin_contents_section(p); pdf_end_obj(p); /* XObject */ return; } /* * Now the (more common) handling of actual image * data to be included in the PDF output. */ /* do we need a filter (either ASCII or decompression)? */ if (p->debug['a']) { pdf_puts(p, "/Filter[/ASCIIHexDecode"); if (image->compression != none) pdf_printf(p, "/%s", pdf_filter_names[image->compression]); pdf_puts(p, "]\n"); } else { /* force compression if not a recognized precompressed image format */ if (!image->use_raw && p->compresslevel) image->compression = flate; if (image->compression != none) pdf_printf(p, "/Filter[/%s]\n", pdf_filter_names[image->compression]); } /* prepare precompressed (raw) image data */ if (image->use_raw) { pdf_printf(p, "/DecodeParms[%s<<", (p->debug['a'] ? "null" : "")); /* write EarlyChange or CCITT parameters if required */ if (image->params) pdf_puts(p, image->params); if (image->compression == flate || image->compression == lzw) { if (image->predictor != pred_default) { pdf_printf(p, "/Predictor %d", (int) image->predictor); pdf_printf(p, "/Columns %d", (int) image->width); if (image->bpc != 8) pdf_printf(p, "/BitsPerComponent %d", image->bpc); if (image->colorspace < LastCS) { switch (image->colorspace) { case Indexed: case ImageMask: case DeviceGray: /* 1 is default */ break; case DeviceRGB: pdf_puts(p, "/Colors 3"); break; case DeviceCMYK: pdf_puts(p, "/Colors 4"); break; default: pdf_error(p, PDF_SystemError, "Unknown colorspace (%d)", (int )image->colorspace); break; } } } } if (image->compression == ccitt) { if ((int) image->width != 1728) /* CCITT default width */ pdf_printf(p, "/Columns %d", (int) image->width); pdf_printf(p, "/Rows %d", (int) image->height); } pdf_puts(p, ">>]\n"); /* DecodeParms dict and array */ } if (image->invert) { pdf_puts(p, "/Decode[1 0"); for (i = 1; i < image->components; i++) pdf_puts(p, " 1 0"); pdf_puts(p, "]\n"); } /* Write the actual image data */ length_id = pdf_alloc_id(p); pdf_printf(p,"/Length %ld 0 R\n", length_id); pdf_end_dict(p); /* XObject */ pdf_begin_stream(p); /* image data */ p->start_contents_pos = pdf_tell(p); /* image data */ if (p->debug['a']) pdf_ASCIIHexEncode(p, &image->src); else { if (image->use_raw) pdf_copy(p, &image->src); else pdf_compress(p, &image->src); } length = pdf_tell(p) - p->start_contents_pos; pdf_end_stream(p); /* image data */ pdf_end_obj(p); /* XObject */ pdf_begin_obj(p, length_id); /* Length object */ pdf_printf(p,"%ld\n", length); pdf_end_obj(p); if (p->flush & PDF_FLUSH_CONTENT) pdf_flush_stream(p); /* Image data done */ /* * Write colormap information for indexed color spaces */ if (firststrip && image->colorspace == Indexed) { pdf_begin_obj(p, image->colormap_id); /* colormap object */ pdf_begin_dict(p); if (p->debug['a']) pdf_puts(p, "/Filter[/ASCIIHexDecode]\n"); else if (p->compresslevel) pdf_puts(p, "/Filter[/FlateDecode]\n"); /* Length of colormap object */ length_id = pdf_alloc_id(p); pdf_printf(p,"/Length %ld 0 R\n", length_id); pdf_end_dict(p); pdf_begin_stream(p); /* colormap data */ p->start_contents_pos = pdf_tell(p); if (image->components != 1) { pdf_error(p, PDF_SystemError, "Bogus indexed colorspace (%d color components)", image->components); } image->src.init = pdf_noop; image->src.fill = pdf_data_source_buf_fill; image->src.terminate = pdf_noop; image->src.buffer_start = (unsigned char *) image->colormap; image->src.buffer_length= (size_t) (image->palette_size * 3); image->src.bytes_available = 0; image->src.next_byte = NULL; /* Write colormap data */ if (p->debug['a']) pdf_ASCIIHexEncode(p, &image->src); else { pdf_compress(p, &image->src); } length = pdf_tell(p) - p->start_contents_pos; pdf_end_stream(p); /* Colormap data */ pdf_end_obj(p); /* Colormap object */ pdf_begin_obj(p, length_id); /* Length object for colormap */ pdf_printf(p, "%ld\n", length); pdf_end_obj(p); /* Length object for colormap */ } if (PDF_GET_STATE(p) == pdf_state_page) pdf_begin_contents_section(p); if (p->flush & PDF_FLUSH_CONTENT) pdf_flush_stream(p); }