static pdf_font_desc * load_font_or_hail_mary(fz_context *ctx, pdf_document *doc, pdf_obj *rdb, pdf_obj *font, int depth, fz_cookie *cookie) { pdf_font_desc *desc; fz_try(ctx) { desc = pdf_load_font(ctx, doc, rdb, font, depth); } fz_catch(ctx) { if (fz_caught(ctx) == FZ_ERROR_TRYLATER && cookie && cookie->incomplete_ok) { desc = NULL; cookie->incomplete++; } else { fz_rethrow(ctx); } } if (desc == NULL) desc = pdf_load_hail_mary_font(ctx, doc); return desc; }
void pdf_set_free_text_details(fz_context *ctx, pdf_annot *annot, fz_point *pos, char *text, char *font_name, float font_size, float color[3]) { pdf_document *doc = annot->page->doc; char nbuf[32]; pdf_obj *dr; pdf_obj *form_fonts; pdf_obj *font = NULL; pdf_obj *ref; pdf_font_desc *font_desc = NULL; fz_matrix page_ctm, inv_page_ctm; pdf_da_info da_info; fz_buffer *fzbuf = NULL; fz_point page_pos; pdf_page_transform(ctx, annot->page, NULL, &page_ctm); fz_invert_matrix(&inv_page_ctm, &page_ctm); dr = pdf_dict_get(ctx, annot->page->obj, PDF_NAME_Resources); if (!dr) { dr = pdf_new_dict(ctx, doc, 1); pdf_dict_put_drop(ctx, annot->page->obj, PDF_NAME_Resources, dr); } /* Ensure the resource dictionary includes a font dict */ form_fonts = pdf_dict_get(ctx, dr, PDF_NAME_Font); if (!form_fonts) { form_fonts = pdf_new_dict(ctx, doc, 1); pdf_dict_put_drop(ctx, dr, PDF_NAME_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; size_t da_len; fz_rect bounds; find_free_font_name(ctx, form_fonts, nbuf, sizeof(nbuf)); font = pdf_new_dict(ctx, doc, 5); ref = pdf_add_object(ctx, doc, font); pdf_dict_puts_drop(ctx, form_fonts, nbuf, ref); pdf_dict_put_drop(ctx, font, PDF_NAME_Type, PDF_NAME_Font); pdf_dict_put_drop(ctx, font, PDF_NAME_Subtype, PDF_NAME_Type1); pdf_dict_put_drop(ctx, font, PDF_NAME_BaseFont, pdf_new_name(ctx, doc, font_name)); pdf_dict_put_drop(ctx, font, PDF_NAME_Encoding, PDF_NAME_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_put_drop(ctx, annot->obj, PDF_NAME_DA, pdf_new_string(ctx, doc, (char *)da_str, da_len)); /* FIXME: should convert to WinAnsiEncoding */ pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_Contents, pdf_new_string(ctx, doc, text, strlen(text))); font_desc = pdf_load_font(ctx, doc, NULL, font, 0); pdf_measure_text(ctx, font_desc, (unsigned char *)text, strlen(text), &bounds); page_pos = *pos; fz_transform_point(&page_pos, &inv_page_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_put_drop(ctx, annot->obj, PDF_NAME_Rect, pdf_new_rect(ctx, doc, &bounds)); } fz_always(ctx) { pdf_drop_obj(ctx, font); fz_drop_buffer(ctx, fzbuf); pdf_drop_font(ctx, font_desc); } fz_catch(ctx) { fz_rethrow(ctx); } }
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); } }