void pdf_add_annot_quad_point(fz_context *ctx, pdf_annot *annot, fz_rect bbox) { pdf_document *doc = annot->page->doc; fz_matrix page_ctm, inv_page_ctm; pdf_obj *quad_points; check_allowed_subtypes(ctx, annot, PDF_NAME(QuadPoints), quad_point_subtypes); pdf_page_transform(ctx, annot->page, NULL, &page_ctm); fz_invert_matrix(&inv_page_ctm, &page_ctm); quad_points = pdf_dict_get(ctx, annot->obj, PDF_NAME(QuadPoints)); if (!pdf_is_array(ctx, quad_points)) { quad_points = pdf_new_array(ctx, doc, 8); pdf_dict_put_drop(ctx, annot->obj, PDF_NAME(QuadPoints), quad_points); } /* Contrary to the specification, the points within a QuadPoint are NOT ordered * in a counterclockwise fashion. Experiments with Adobe's implementation * indicates a cross-wise ordering is intended: ul, ur, ll, lr. */ fz_transform_rect(&bbox, &inv_page_ctm); pdf_array_push_real(ctx, quad_points, bbox.x0); /* ul */ pdf_array_push_real(ctx, quad_points, bbox.y1); pdf_array_push_real(ctx, quad_points, bbox.x1); /* ur */ pdf_array_push_real(ctx, quad_points, bbox.y1); pdf_array_push_real(ctx, quad_points, bbox.x0); /* ll */ pdf_array_push_real(ctx, quad_points, bbox.y0); pdf_array_push_real(ctx, quad_points, bbox.x1); /* lr */ pdf_array_push_real(ctx, quad_points, bbox.y0); pdf_dirty_annot(ctx, annot); }
void pdf_set_annot_vertices(fz_context *ctx, pdf_annot *annot, int n, const float *v) { pdf_document *doc = annot->page->doc; fz_matrix page_ctm, inv_page_ctm; pdf_obj *vertices; fz_point point; int i; check_allowed_subtypes(ctx, annot, PDF_NAME_Vertices, vertices_subtypes); if (n <= 0 || !v) fz_throw(ctx, FZ_ERROR_GENERIC, "invalid number of vertices"); pdf_page_transform(ctx, annot->page, NULL, &page_ctm); fz_invert_matrix(&inv_page_ctm, &page_ctm); vertices = pdf_new_array(ctx, doc, n * 2); for (i = 0; i < n; ++i) { point.x = v[i * 2]; point.y = v[i * 2 + 1]; fz_transform_point(&point, &inv_page_ctm); pdf_array_push_drop(ctx, vertices, pdf_new_real(ctx, doc, point.x)); pdf_array_push_drop(ctx, vertices, pdf_new_real(ctx, doc, point.y)); } pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_Vertices, vertices); annot->changed = 1; }
void pdf_set_annot_quad_points(fz_context *ctx, pdf_annot *annot, int n, const float *v) { pdf_document *doc = annot->page->doc; fz_matrix page_ctm, inv_page_ctm; pdf_obj *quad_points; fz_point point; int i, k; check_allowed_subtypes(ctx, annot, PDF_NAME_QuadPoints, quad_point_subtypes); if (n <= 0 || !v) fz_throw(ctx, FZ_ERROR_GENERIC, "invalid number of quadrilaterals"); pdf_page_transform(ctx, annot->page, NULL, &page_ctm); fz_invert_matrix(&inv_page_ctm, &page_ctm); quad_points = pdf_new_array(ctx, doc, n * 8); for (i = 0; i < n; ++i) { for (k = 0; k < 4; ++k) { point.x = v[i * 8 + k * 2 + 0]; point.y = v[i * 8 + k * 2 + 1]; fz_transform_point(&point, &inv_page_ctm); pdf_array_push_drop(ctx, quad_points, pdf_new_real(ctx, doc, point.x)); pdf_array_push_drop(ctx, quad_points, pdf_new_real(ctx, doc, point.y)); } } pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_QuadPoints, quad_points); annot->changed = 1; }
void pdf_annot_quad_point(fz_context *ctx, pdf_annot *annot, int idx, float v[8]) { pdf_obj *quad_points; pdf_obj *quad_point; fz_matrix page_ctm; int i; check_allowed_subtypes(ctx, annot, PDF_NAME_QuadPoints, quad_point_subtypes); quad_points = pdf_dict_get(ctx, annot->obj, PDF_NAME_QuadPoints); quad_point = pdf_array_get(ctx, quad_points, idx); pdf_page_transform(ctx, annot->page, NULL, &page_ctm); for (i = 0; i < 8; i += 2) { fz_point point; point.x = pdf_to_real(ctx, pdf_array_get(ctx, quad_point, i+0)); point.y = pdf_to_real(ctx, pdf_array_get(ctx, quad_point, i+1)); fz_transform_point(&point, &page_ctm); v[i+0] = point.x; v[i+1] = point.y; } }
void pdf_annot_ink_list_stroke_vertex(fz_context *ctx, pdf_annot *annot, int i, int k, float v[2]) { pdf_obj *ink_list; pdf_obj *stroke; fz_matrix page_ctm; fz_point point = { 0, 0 }; check_allowed_subtypes(ctx, annot, PDF_NAME_InkList, ink_list_subtypes); ink_list = pdf_dict_get(ctx, annot->obj, PDF_NAME_InkList); stroke = pdf_array_get(ctx, ink_list, i); if (v) { pdf_page_transform(ctx, annot->page, NULL, &page_ctm); point.x = pdf_to_real(ctx, pdf_array_get(ctx, stroke, k * 2 + 0)); point.y = pdf_to_real(ctx, pdf_array_get(ctx, stroke, k * 2 + 1)); fz_transform_point(&point, &page_ctm); v[0] = point.x; v[1] = point.y; } }
void pdf_set_annot_ink_list(fz_context *ctx, pdf_annot *annot, int n, const int *count, const float *v) { pdf_document *doc = annot->page->doc; fz_matrix page_ctm, inv_page_ctm; pdf_obj *ink_list, *stroke; fz_point point; int i, k; check_allowed_subtypes(ctx, annot, PDF_NAME_InkList, ink_list_subtypes); pdf_page_transform(ctx, annot->page, NULL, &page_ctm); fz_invert_matrix(&inv_page_ctm, &page_ctm); // TODO: update Rect (in update appearance perhaps?) ink_list = pdf_new_array(ctx, doc, n); for (i = 0; i < n; ++i) { stroke = pdf_new_array(ctx, doc, count[i]); for (k = 0; k < count[i]; ++k) { point.x = *v++; point.y = *v++; fz_transform_point(&point, &inv_page_ctm); pdf_array_push_drop(ctx, stroke, pdf_new_real(ctx, doc, point.x)); pdf_array_push_drop(ctx, stroke, pdf_new_real(ctx, doc, point.y)); } pdf_array_push_drop(ctx, ink_list, stroke); } pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_InkList, ink_list); annot->changed = 1; }
static void pdf_run_annot_with_usage(fz_context *ctx, pdf_document *doc, pdf_page *page, pdf_annot *annot, fz_device *dev, const fz_matrix *ctm, const char *usage, fz_cookie *cookie) { fz_matrix local_ctm, page_ctm; fz_rect mediabox; pdf_processor *proc; fz_default_colorspaces *default_cs; default_cs = pdf_load_default_colorspaces(ctx, doc, page); if (default_cs) fz_set_default_colorspaces(ctx, dev, default_cs); fz_drop_default_colorspaces(ctx, default_cs); pdf_page_transform(ctx, page, &mediabox, &page_ctm); fz_concat(&local_ctm, &page_ctm, ctm); proc = pdf_new_run_processor(ctx, dev, &local_ctm, usage, NULL, 0); fz_try(ctx) { pdf_process_annot(ctx, proc, doc, page, annot, cookie); pdf_close_processor(ctx, proc); } fz_always(ctx) pdf_drop_processor(ctx, proc); fz_catch(ctx) fz_rethrow(ctx); }
void pdf_set_annot_quad_points(fz_context *ctx, pdf_annot *annot, int n, const float *v) { pdf_document *doc = annot->page->doc; fz_matrix page_ctm, inv_page_ctm; pdf_obj *quad_points; fz_point point; int i, k; // TODO: check annot type pdf_page_transform(ctx, annot->page, NULL, &page_ctm); fz_invert_matrix(&inv_page_ctm, &page_ctm); quad_points = pdf_new_array(ctx, doc, n * 8); for (i = 0; i < n; ++i) { for (k = 0; k < 4; ++k) { point.x = v[i * 8 + k * 2 + 0]; point.y = v[i * 8 + k * 2 + 1]; fz_transform_point(&point, &inv_page_ctm); pdf_array_push_drop(ctx, quad_points, pdf_new_real(ctx, doc, point.x)); pdf_array_push_drop(ctx, quad_points, pdf_new_real(ctx, doc, point.y)); } } pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_QuadPoints, quad_points); annot->changed = 1; }
void pdf_set_annot_ink_list(fz_context *ctx, pdf_annot *annot, int n, const int *count, const float *v) { pdf_document *doc = annot->page->doc; fz_matrix page_ctm, inv_page_ctm; pdf_obj *ink_list, *stroke; fz_point point; int i, k; if (pdf_annot_type(ctx, annot) != PDF_ANNOT_INK) fz_throw(ctx, FZ_ERROR_GENERIC, "cannot set InkList on non-ink annotations"); pdf_page_transform(ctx, annot->page, NULL, &page_ctm); fz_invert_matrix(&inv_page_ctm, &page_ctm); // TODO: update Rect (in update appearance perhaps?) ink_list = pdf_new_array(ctx, doc, n); for (i = 0; i < n; ++i) { stroke = pdf_new_array(ctx, doc, count[i]); for (k = 0; k < count[i]; ++k) { point.x = *v++; point.y = *v++; fz_transform_point(&point, &inv_page_ctm); pdf_array_push_drop(ctx, stroke, pdf_new_real(ctx, doc, point.x)); pdf_array_push_drop(ctx, stroke, pdf_new_real(ctx, doc, point.y)); } pdf_array_push_drop(ctx, ink_list, stroke); } pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_InkList, ink_list); annot->changed = 1; }
void pdf_annot_rect(fz_context *ctx, pdf_annot *annot, fz_rect *rect) { fz_matrix page_ctm; pdf_page_transform(ctx, annot->page, NULL, &page_ctm); pdf_to_rect(ctx, pdf_dict_get(ctx, annot->obj, PDF_NAME_Rect), rect); fz_transform_rect(rect, &page_ctm); }
fz_rect * pdf_bound_annot(fz_context *ctx, pdf_annot *annot, fz_rect *rect) { pdf_obj *obj = pdf_dict_get(ctx, annot->obj, PDF_NAME_Rect); fz_rect mediabox; fz_matrix page_ctm; pdf_to_rect(ctx, obj, rect); pdf_page_transform(ctx, annot->page, &mediabox, &page_ctm); fz_transform_rect(rect, &page_ctm); return rect; }
void pdf_set_annot_rect(fz_context *ctx, pdf_annot *annot, const fz_rect *rect) { fz_rect trect = *rect; fz_matrix page_ctm, inv_page_ctm; pdf_page_transform(ctx, annot->page, NULL, &page_ctm); fz_invert_matrix(&inv_page_ctm, &page_ctm); fz_transform_rect(&trect, &inv_page_ctm); pdf_dict_put_rect(ctx, annot->obj, PDF_NAME(Rect), &trect); pdf_dirty_annot(ctx, annot); }
void pdf_set_annot_rect(fz_context *ctx, pdf_annot *annot, const fz_rect *rect) { pdf_document *doc = annot->page->doc; fz_rect trect = *rect; fz_matrix page_ctm, inv_page_ctm; pdf_page_transform(ctx, annot->page, NULL, &page_ctm); fz_invert_matrix(&inv_page_ctm, &page_ctm); fz_transform_rect(&trect, &inv_page_ctm); pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_Rect, pdf_new_rect(ctx, doc, &trect)); annot->changed = 1; }
void pdf_set_annot_vertex(fz_context *ctx, pdf_annot *annot, int i, fz_point p) { fz_matrix page_ctm, inv_page_ctm; pdf_obj *vertices; check_allowed_subtypes(ctx, annot, PDF_NAME(Vertices), vertices_subtypes); pdf_page_transform(ctx, annot->page, NULL, &page_ctm); fz_invert_matrix(&inv_page_ctm, &page_ctm); fz_transform_point(&p, &inv_page_ctm); vertices = pdf_dict_get(ctx, annot->obj, PDF_NAME(Vertices)); pdf_array_put_drop(ctx, vertices, i * 2 + 0, pdf_new_real(ctx, p.x)); pdf_array_put_drop(ctx, vertices, i * 2 + 1, pdf_new_real(ctx, p.y)); }
void pdf_annot_line(fz_context *ctx, pdf_annot *annot, fz_point *a, fz_point *b) { fz_matrix page_ctm; pdf_obj *line; check_allowed_subtypes(ctx, annot, PDF_NAME(L), line_subtypes); pdf_page_transform(ctx, annot->page, NULL, &page_ctm); line = pdf_dict_get(ctx, annot->obj, PDF_NAME(L)); a->x = pdf_array_get_real(ctx, line, 0); a->y = pdf_array_get_real(ctx, line, 1); b->x = pdf_array_get_real(ctx, line, 2); b->y = pdf_array_get_real(ctx, line, 3); fz_transform_point(a, &page_ctm); fz_transform_point(b, &page_ctm); }
fz_point pdf_annot_vertex(fz_context *ctx, pdf_annot *annot, int i) { pdf_obj *vertices; fz_matrix page_ctm; fz_point point; check_allowed_subtypes(ctx, annot, PDF_NAME(Vertices), vertices_subtypes); vertices = pdf_dict_get(ctx, annot->obj, PDF_NAME(Vertices)); pdf_page_transform(ctx, annot->page, NULL, &page_ctm); point.x = pdf_array_get_real(ctx, vertices, i * 2); point.y = pdf_array_get_real(ctx, vertices, i * 2 + 1); fz_transform_point(&point, &page_ctm); return point; }
void pdf_annot_vertex(fz_context *ctx, pdf_annot *annot, int i, float v[2]) { pdf_obj *vertices; fz_matrix page_ctm; fz_point point; check_allowed_subtypes(ctx, annot, PDF_NAME_Vertices, vertices_subtypes); vertices = pdf_dict_get(ctx, annot->obj, PDF_NAME_Vertices); pdf_page_transform(ctx, annot->page, NULL, &page_ctm); point.x = pdf_to_real(ctx, pdf_array_get(ctx, vertices, i * 2)); point.y = pdf_to_real(ctx, pdf_array_get(ctx, vertices, i * 2 + 1)); fz_transform_point(&point, &page_ctm); v[0] = point.x; v[1] = point.y; }
void pdf_add_annot_ink_list(fz_context *ctx, pdf_annot *annot, int n, fz_point p[]) { pdf_document *doc = annot->page->doc; fz_matrix page_ctm, inv_page_ctm; pdf_obj *ink_list, *stroke; int i; check_allowed_subtypes(ctx, annot, PDF_NAME(InkList), ink_list_subtypes); pdf_page_transform(ctx, annot->page, NULL, &page_ctm); fz_invert_matrix(&inv_page_ctm, &page_ctm); ink_list = pdf_dict_get(ctx, annot->obj, PDF_NAME(InkList)); if (!pdf_is_array(ctx, ink_list)) { ink_list = pdf_new_array(ctx, doc, 10); pdf_dict_put_drop(ctx, annot->obj, PDF_NAME(InkList), ink_list); } stroke = pdf_new_array(ctx, doc, n * 2); fz_try(ctx) { for (i = 0; i < n; ++i) { fz_point tp = p[i]; fz_transform_point(&tp, &inv_page_ctm); pdf_array_push_real(ctx, stroke, tp.x); pdf_array_push_real(ctx, stroke, tp.y); } } fz_catch(ctx) { pdf_drop_obj(ctx, stroke); fz_rethrow(ctx); } pdf_array_push_drop(ctx, ink_list, stroke); pdf_dirty_annot(ctx, annot); }
fz_point pdf_annot_ink_list_stroke_vertex(fz_context *ctx, pdf_annot *annot, int i, int k) { pdf_obj *ink_list; pdf_obj *stroke; fz_matrix page_ctm; fz_point point; check_allowed_subtypes(ctx, annot, PDF_NAME(InkList), ink_list_subtypes); ink_list = pdf_dict_get(ctx, annot->obj, PDF_NAME(InkList)); stroke = pdf_array_get(ctx, ink_list, i); pdf_page_transform(ctx, annot->page, NULL, &page_ctm); point.x = pdf_array_get_real(ctx, stroke, k * 2 + 0); point.y = pdf_array_get_real(ctx, stroke, k * 2 + 1); fz_transform_point(&point, &page_ctm); return point; }
void pdf_set_text_annot_position(fz_context *ctx, pdf_annot *annot, fz_point pt) { fz_matrix page_ctm, inv_page_ctm; fz_rect rect; int flags; pdf_page_transform(ctx, annot->page, NULL, &page_ctm); fz_invert_matrix(&inv_page_ctm, &page_ctm); rect.x0 = pt.x; rect.x1 = pt.x + TEXT_ANNOT_SIZE; rect.y0 = pt.y; rect.y1 = pt.y + TEXT_ANNOT_SIZE; fz_transform_rect(&rect, &inv_page_ctm); pdf_dict_put_rect(ctx, annot->obj, PDF_NAME(Rect), &rect); flags = pdf_dict_get_int(ctx, annot->obj, PDF_NAME(F)); flags |= (PDF_ANNOT_IS_NO_ZOOM|PDF_ANNOT_IS_NO_ROTATE); pdf_dict_put_int(ctx, annot->obj, PDF_NAME(F), flags); }
void pdf_set_text_annot_position(fz_context *ctx, pdf_annot *annot, fz_point pt) { pdf_document *doc = annot->page->doc; fz_matrix page_ctm, inv_page_ctm; fz_rect rect; int flags; pdf_page_transform(ctx, annot->page, NULL, &page_ctm); fz_invert_matrix(&inv_page_ctm, &page_ctm); rect.x0 = pt.x; rect.x1 = pt.x + TEXT_ANNOT_SIZE; rect.y0 = pt.y; rect.y1 = pt.y + TEXT_ANNOT_SIZE; fz_transform_rect(&rect, &inv_page_ctm); pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_Rect, pdf_new_rect(ctx, doc, &rect)); flags = pdf_to_int(ctx, pdf_dict_get(ctx, annot->obj, PDF_NAME_F)); flags |= (PDF_ANNOT_IS_NO_ZOOM|PDF_ANNOT_IS_NO_ROTATE); pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_F, pdf_new_int(ctx, doc, flags)); }
void pdf_set_annot_line(fz_context *ctx, pdf_annot *annot, fz_point a, fz_point b) { fz_matrix page_ctm, inv_page_ctm; pdf_obj *line; check_allowed_subtypes(ctx, annot, PDF_NAME(L), line_subtypes); pdf_page_transform(ctx, annot->page, NULL, &page_ctm); fz_invert_matrix(&inv_page_ctm, &page_ctm); fz_transform_point(&a, &inv_page_ctm); fz_transform_point(&b, &inv_page_ctm); line = pdf_new_array(ctx, annot->page->doc, 4); pdf_dict_put_drop(ctx, annot->obj, PDF_NAME(L), line); pdf_array_push_real(ctx, line, a.x); pdf_array_push_real(ctx, line, a.y); pdf_array_push_real(ctx, line, b.x); pdf_array_push_real(ctx, line, b.y); pdf_dirty_annot(ctx, annot); }
void pdf_add_annot_vertex(fz_context *ctx, pdf_annot *annot, fz_point p) { pdf_document *doc = annot->page->doc; fz_matrix page_ctm, inv_page_ctm; pdf_obj *vertices; check_allowed_subtypes(ctx, annot, PDF_NAME(Vertices), vertices_subtypes); pdf_page_transform(ctx, annot->page, NULL, &page_ctm); fz_invert_matrix(&inv_page_ctm, &page_ctm); vertices = pdf_dict_get(ctx, annot->obj, PDF_NAME(Vertices)); if (!pdf_is_array(ctx, vertices)) { vertices = pdf_new_array(ctx, doc, 32); pdf_dict_put_drop(ctx, annot->obj, PDF_NAME(Vertices), vertices); } fz_transform_point(&p, &inv_page_ctm); pdf_array_push_real(ctx, vertices, p.x); pdf_array_push_real(ctx, vertices, p.y); pdf_dirty_annot(ctx, annot); }
static void pdf_run_page_contents_with_usage(fz_context *ctx, pdf_document *doc, pdf_page *page, fz_device *dev, const fz_matrix *ctm, const char *usage, fz_cookie *cookie) { fz_matrix local_ctm, page_ctm; pdf_obj *resources; pdf_obj *contents; fz_rect mediabox; pdf_processor *proc = NULL; fz_default_colorspaces *default_cs; fz_var(proc); default_cs = pdf_load_default_colorspaces(ctx, doc, page); if (default_cs) fz_set_default_colorspaces(ctx, dev, default_cs); fz_try(ctx) { pdf_page_transform(ctx, page, &mediabox, &page_ctm); fz_concat(&local_ctm, &page_ctm, ctm); resources = pdf_page_resources(ctx, page); contents = pdf_page_contents(ctx, page); if (page->transparency) { fz_colorspace *colorspace = NULL; pdf_obj *group = pdf_page_group(ctx, page); if (group) { pdf_obj *cs = pdf_dict_get(ctx, group, PDF_NAME_CS); if (cs) { fz_try(ctx) colorspace = pdf_load_colorspace(ctx, cs); fz_catch(ctx) colorspace = NULL; } } else colorspace = fz_keep_colorspace(ctx, fz_default_output_intent(ctx, default_cs)); fz_begin_group(ctx, dev, fz_transform_rect(&mediabox, &local_ctm), colorspace, 1, 0, 0, 1); fz_drop_colorspace(ctx, colorspace); } proc = pdf_new_run_processor(ctx, dev, &local_ctm, usage, NULL, 0); pdf_process_contents(ctx, proc, doc, resources, contents, cookie); pdf_close_processor(ctx, proc); } fz_always(ctx) { fz_drop_default_colorspaces(ctx, default_cs); pdf_drop_processor(ctx, proc); } fz_catch(ctx) fz_rethrow(ctx); if (page->transparency) fz_end_group(ctx, dev); }
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); } }