static void pdf_dev_alpha(fz_context *ctx, pdf_device *pdev, float alpha, int stroke) { int i; pdf_document *doc = pdev->doc; gstate *gs = CURRENT_GSTATE(pdev); /* If the alpha is unchanged, nothing to do */ if (gs->alpha[stroke] == alpha) return; /* Have we sent such an alpha before? */ for (i = 0; i < pdev->num_alphas; i++) if (pdev->alphas[i].alpha == alpha && pdev->alphas[i].stroke == stroke) break; if (i == pdev->num_alphas) { pdf_obj *o, *ref; /* No. Need to make a new one */ if (pdev->num_alphas == pdev->max_alphas) { int newmax = pdev->max_alphas * 2; if (newmax == 0) newmax = 4; pdev->alphas = fz_resize_array(ctx, pdev->alphas, newmax, sizeof(*pdev->alphas)); pdev->max_alphas = newmax; } pdev->alphas[i].alpha = alpha; pdev->alphas[i].stroke = stroke; o = pdf_new_dict(ctx, doc, 1); fz_try(ctx) { char text[32]; pdf_dict_put_real(ctx, o, (stroke ? PDF_NAME(CA) : PDF_NAME(ca)), alpha); fz_snprintf(text, sizeof(text), "ExtGState/Alp%d", i); ref = pdf_add_object(ctx, doc, o); pdf_dict_putp_drop(ctx, pdev->resources, text, ref); } fz_always(ctx) { pdf_drop_obj(ctx, o); } fz_catch(ctx) { fz_rethrow(ctx); } pdev->num_alphas++; }
int pdfportfolio_main(int argc, char **argv) { char *password = ""; char *outfile = NULL; char *outopts = "compress"; char *infile; int exit_code = 0; int do_save = 0; int has_old_file = 0; int c; while ((c = fz_getopt(argc, argv, "p:o:O:")) != -1) { switch (c) { case 'p': password = fz_optarg; break; case 'o': outfile = fz_optarg; break; case 'O': outopts = fz_optarg; break; default: usage(); break; } } if (fz_optind == argc) usage(); infile = argv[fz_optind++]; if (!outfile) outfile = infile; ctx = fz_new_context(NULL, NULL, FZ_STORE_UNLIMITED); if (!ctx) { fprintf(stderr, "cannot initialise context\n"); exit(1); } if (fz_file_exists(ctx, infile)) { doc = pdf_open_document(ctx, infile); if (pdf_needs_password(ctx, doc)) if (!pdf_authenticate_password(ctx, doc, password)) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot authenticate password: %s", infile); has_old_file = 1; } else { doc = pdf_create_document(ctx); /* add a blank page */ { const char *template = "BT /Tm 16 Tf 50 434 TD (This is a portfolio document.) Tj ET\n"; const unsigned char *data; int size; fz_font *font; pdf_obj *font_obj, *page_obj; pdf_obj *resources; fz_buffer *contents; fz_rect mediabox = { 0, 0, 400, 500 }; data = fz_lookup_base14_font(ctx, "Times-Roman", &size); font = fz_new_font_from_memory(ctx, "Times-Roman", data, size, 0, 0); font_obj = pdf_add_simple_font(ctx, doc, font, PDF_SIMPLE_ENCODING_LATIN); fz_drop_font(ctx, font); resources = pdf_add_new_dict(ctx, doc, 1); pdf_dict_putp_drop(ctx, resources, "Font/Tm", font_obj); contents = fz_new_buffer_from_shared_data(ctx, (const unsigned char *)template, strlen(template));
void pdf_set_free_text_details(pdf_document *doc, pdf_annot *annot, fz_point *pos, char *text, char *font_name, float font_size, float color[3]) { fz_context *ctx = doc->ctx; char nbuf[32]; pdf_obj *dr; pdf_obj *form_fonts; pdf_obj *font = NULL; pdf_obj *ref; pdf_font_desc *font_desc = NULL; pdf_da_info da_info; fz_buffer *fzbuf = NULL; fz_matrix ctm; fz_point page_pos; fz_invert_matrix(&ctm, &annot->page->ctm); dr = pdf_dict_gets(annot->page->me, "Resources"); if (!dr) { dr = pdf_new_dict(doc, 1); pdf_dict_putp_drop(annot->page->me, "Resources", dr); } /* Ensure the resource dictionary includes a font dict */ form_fonts = pdf_dict_gets(dr, "Font"); if (!form_fonts) { form_fonts = pdf_new_dict(doc, 1); pdf_dict_puts_drop(dr, "Font", form_fonts); /* form_fonts is still valid if execution continues past the above call */ } fz_var(fzbuf); fz_var(font); fz_try(ctx) { unsigned char *da_str; int da_len; fz_rect bounds; find_free_font_name(form_fonts, nbuf, sizeof(nbuf)); font = pdf_new_dict(doc, 5); ref = pdf_new_ref(doc, font); pdf_dict_puts_drop(form_fonts, nbuf, ref); pdf_dict_puts_drop(font, "Type", pdf_new_name(doc, "Font")); pdf_dict_puts_drop(font, "Subtype", pdf_new_name(doc, "Type1")); pdf_dict_puts_drop(font, "BaseFont", pdf_new_name(doc, font_name)); pdf_dict_puts_drop(font, "Encoding", pdf_new_name(doc, "WinAnsiEncoding")); memcpy(da_info.col, color, sizeof(float)*3); da_info.col_size = 3; da_info.font_name = nbuf; da_info.font_size = font_size; fzbuf = fz_new_buffer(ctx, 0); pdf_fzbuf_print_da(ctx, fzbuf, &da_info); da_len = fz_buffer_storage(ctx, fzbuf, &da_str); pdf_dict_puts_drop(annot->obj, "DA", pdf_new_string(doc, (char *)da_str, da_len)); /* FIXME: should convert to WinAnsiEncoding */ pdf_dict_puts_drop(annot->obj, "Contents", pdf_new_string(doc, text, strlen(text))); font_desc = pdf_load_font(doc, NULL, font, 0); pdf_measure_text(ctx, font_desc, (unsigned char *)text, strlen(text), &bounds); page_pos = *pos; fz_transform_point(&page_pos, &ctm); bounds.x0 *= font_size; bounds.x1 *= font_size; bounds.y0 *= font_size; bounds.y1 *= font_size; bounds.x0 += page_pos.x; bounds.x1 += page_pos.x; bounds.y0 += page_pos.y; bounds.y1 += page_pos.y; pdf_dict_puts_drop(annot->obj, "Rect", pdf_new_rect(doc, &bounds)); update_rect(ctx, annot); } fz_always(ctx) { pdf_drop_obj(font); fz_drop_buffer(ctx, fzbuf); pdf_drop_font(ctx, font_desc); } fz_catch(ctx) { fz_rethrow(ctx); } }