static void pdf_write_widget_appearance(fz_context *ctx, pdf_annot *annot, fz_buffer *buf, fz_rect *rect, fz_rect *bbox, fz_matrix *matrix, pdf_obj **res) { pdf_obj *ft = pdf_dict_get_inheritable(ctx, annot->obj, PDF_NAME(FT)); if (pdf_name_eq(ctx, ft, PDF_NAME(Tx))) { int ff = pdf_field_flags(ctx, annot->obj); char *format = NULL; const char *text = NULL; if (!annot->ignore_trigger_events) { format = pdf_field_event_format(ctx, annot->page->doc, annot->obj); if (format) text = format; else text = pdf_field_value(ctx, annot->obj); } else { text = pdf_field_value(ctx, annot->obj); } fz_try(ctx) pdf_write_tx_widget_appearance(ctx, annot, buf, rect, bbox, matrix, res, text, ff); fz_always(ctx) fz_free(ctx, format); fz_catch(ctx) fz_rethrow(ctx); } else if (pdf_name_eq(ctx, ft, PDF_NAME(Ch))) { pdf_write_ch_widget_appearance(ctx, annot, buf, rect, bbox, matrix, res); } else if (pdf_name_eq(ctx, ft, PDF_NAME(Sig))) { pdf_write_sig_widget_appearance(ctx, annot, buf, rect, bbox, matrix, res); } else { fz_throw(ctx, FZ_ERROR_GENERIC, "cannot create appearance stream for %s widgets", pdf_to_name(ctx, ft)); } }
static void pdf_write_tx_widget_appearance(fz_context *ctx, pdf_annot *annot, fz_buffer *buf, fz_rect *rect, fz_rect *bbox, fz_matrix *matrix, pdf_obj **res, const char *text, int ff) { const char *font; float size, color[3]; float w, h, t, b; int has_bc = 0; int q, r; r = pdf_dict_get_int(ctx, pdf_dict_get(ctx, annot->obj, PDF_NAME(MK)), PDF_NAME(R)); q = pdf_annot_quadding(ctx, annot); pdf_annot_default_appearance(ctx, annot, &font, &size, color); w = rect->x1 - rect->x0; h = rect->y1 - rect->y0; if (r == 90 || r == 270) t = h, h = w, w = t; *matrix = fz_rotate(r); *bbox = fz_make_rect(0, 0, w, h); fz_append_string(ctx, buf, "/Tx BMC\nq\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); has_bc = 1; } fz_append_printf(ctx, buf, "%g %g %g %g re\nW\nn\n", b, b, w-b*2, h-b*2); if (ff & PDF_TX_FIELD_IS_MULTILINE) { write_variable_text(ctx, annot, buf, res, text, font, size, color, q, w, h, b*2, 1.116f, 1.116f, 1, 0, 1); } else if (ff & PDF_TX_FIELD_IS_COMB) { int maxlen = pdf_to_int(ctx, pdf_dict_get_inheritable(ctx, annot->obj, PDF_NAME(MaxLen))); if (has_bc && maxlen > 1) { float cell_w = (w - 2 * b) / maxlen; int i; for (i = 1; i < maxlen; ++i) { float x = b + cell_w * i; fz_append_printf(ctx, buf, "%g %g m %g %g l s\n", x, b, x, h-b); } } write_variable_text(ctx, annot, buf, res, text, font, size, color, q, w, h, 0, 0.8f, 1.2f, 0, maxlen, 0); } else { write_variable_text(ctx, annot, buf, res, text, font, size, color, q, w, h, b*2, 0.8f, 1.2f, 0, 0, 0); } fz_append_string(ctx, buf, "Q\nEMC\n"); }
static pdf_annot * pdf_update_tx_widget_annot(pdf_xref *xref, fz_obj *obj) { fz_obj *ap, *res, *value; fz_rect rect; fz_buffer *content, *base_ap; int flags, align, rotate, is_multiline; float font_size, x, y; char *font_name; unsigned short *ucs2, *rest; fz_context *ctx = xref->ctx; if (strcmp(fz_to_name(ctx, fz_dict_gets(ctx, obj, "Subtype")), "Widget") != 0) return NULL; if (!fz_to_bool(ctx, pdf_dict_get_inheritable(xref, NULL, "NeedAppearances")) && pdf_get_ap_stream(xref, obj)) return NULL; value = pdf_dict_get_inheritable(xref, obj, "FT"); if (strcmp(fz_to_name(ctx, value), "Tx") != 0) return NULL; ap = pdf_dict_get_inheritable(xref, obj, "DA"); value = pdf_dict_get_inheritable(xref, obj, "V"); if (!ap || !value) return NULL; res = pdf_dict_get_inheritable(xref, obj, "DR"); rect = pdf_to_rect(ctx, fz_dict_gets(ctx, obj, "Rect")); rotate = fz_to_int(ctx, fz_dict_gets(ctx, fz_dict_gets(ctx, obj, "MK"), "R")); rect = fz_transform_rect(fz_rotate(rotate), rect); flags = fz_to_int(ctx, fz_dict_gets(ctx, obj, "Ff")); is_multiline = (flags & (1 << 12)) != 0; if ((flags & (1 << 25) /* richtext */)) fz_warn(ctx, "missing support for richtext fields"); align = fz_to_int(ctx, fz_dict_gets(ctx, obj, "Q")); font_size = pdf_extract_font_size(xref, fz_to_str_buf(ctx, ap), &font_name); if (!font_size || !font_name) font_size = is_multiline ? 10 /* FIXME */ : floor(rect.y1 - rect.y0 - 2); content = fz_new_buffer(ctx, 256); base_ap = fz_new_buffer(ctx, 256); pdf_prepend_ap_background(content, xref, obj); fz_buffer_printf(ctx, content, "/Tx BMC q 1 1 %.4f %.4f re W n BT %s ", rect.x1 - rect.x0 - 2.0f, rect.y1 - rect.y0 - 2.0f, fz_to_str_buf(ctx, ap)); fz_buffer_printf(ctx, base_ap, "/Tx BMC q BT %s ", fz_to_str_buf(ctx, ap)); if (font_name) { fz_buffer_printf(ctx, content, "/%s %.4f Tf ", font_name, font_size); fz_buffer_printf(ctx, base_ap, "/%s %.4f Tf ", font_name, font_size); fz_free(ctx, font_name); } y = 0.5f * (rect.y1 - rect.y0) + 0.6f * font_size; if (is_multiline) y = rect.y1 - rect.y0 - 2; fz_buffer_printf(ctx, content, "1 0 0 1 2 %.4f Tm ", y); ucs2 = pdf_to_ucs2(ctx, value); for (rest = ucs2; *rest; rest++) if (*rest > 0xFF) *rest = '?'; if ((flags & (1 << 13) /* password */)) for (rest = ucs2; *rest; rest++) *rest = '*'; x = 0; rest = ucs2; if ((flags & (1 << 24) /* comb */)) { pdf_append_combed_line(xref, res, content, base_ap, ucs2, font_size, rect.x1 - rect.x0, fz_to_int(ctx, pdf_dict_get_inheritable(xref, obj, "MaxLen"))); rest = L""; } while (*rest) rest = pdf_append_line(xref, res, content, base_ap, rest, font_size, align, rect.x1 - rect.x0 - 4.0f, is_multiline, &x); fz_free(ctx, ucs2); fz_buffer_printf(ctx, content, "ET Q EMC"); fz_drop_buffer(ctx, base_ap); rect = fz_transform_rect(fz_rotate(-rotate), rect); return pdf_create_annot(ctx, rect, fz_keep_obj(obj), content, res ? fz_keep_obj(res) : NULL, 0); }