static void write_comb_string(fz_context *ctx, fz_buffer *buf, const char *a, const char *b, fz_font *font, float cell_w) { float gw, pad, carry = 0; fz_append_byte(ctx, buf, '['); while (a < b) { int c, g; a += fz_chartorune(&c, a); c = fz_windows_1252_from_unicode(c); if (c < 0) c = REPLACEMENT; g = fz_encode_character(ctx, font, c); gw = fz_advance_glyph(ctx, font, g, 0) * 1000; pad = (cell_w - gw) / 2; fz_append_printf(ctx, buf, "%g", -(carry + pad)); carry = pad; fz_append_byte(ctx, buf, '('); if (c == '(' || c == ')' || c == '\\') fz_append_byte(ctx, buf, '\\'); fz_append_byte(ctx, buf, c); fz_append_byte(ctx, buf, ')'); } fz_append_string(ctx, buf, "] TJ\n"); }
/* Helper functions */ static void pdf_dev_stroke_state(fz_context *ctx, pdf_device *pdev, const fz_stroke_state *stroke_state) { gstate *gs = CURRENT_GSTATE(pdev); if (stroke_state == gs->stroke_state) return; if (gs->stroke_state && !memcmp(stroke_state, gs->stroke_state, sizeof(*stroke_state))) return; if (!gs->stroke_state || gs->stroke_state->linewidth != stroke_state->linewidth) { fz_append_printf(ctx, gs->buf, "%g w\n", stroke_state->linewidth); } if (!gs->stroke_state || gs->stroke_state->start_cap != stroke_state->start_cap) { int cap = stroke_state->start_cap; /* FIXME: Triangle caps aren't supported in pdf */ if (cap == FZ_LINECAP_TRIANGLE) cap = FZ_LINECAP_BUTT; fz_append_printf(ctx, gs->buf, "%d J\n", cap); } if (!gs->stroke_state || gs->stroke_state->linejoin != stroke_state->linejoin) { int join = stroke_state->linejoin; if (join == FZ_LINEJOIN_MITER_XPS) join = FZ_LINEJOIN_MITER; fz_append_printf(ctx, gs->buf, "%d j\n", join); } if (!gs->stroke_state || gs->stroke_state->miterlimit != stroke_state->miterlimit) { fz_append_printf(ctx, gs->buf, "%g M\n", stroke_state->miterlimit); } if (gs->stroke_state == NULL && stroke_state->dash_len == 0) {} else if (!gs->stroke_state || gs->stroke_state->dash_phase != stroke_state->dash_phase || gs->stroke_state->dash_len != stroke_state->dash_len || memcmp(gs->stroke_state->dash_list, stroke_state->dash_list, sizeof(float)*stroke_state->dash_len)) { int i; if (stroke_state->dash_len == 0) fz_append_byte(ctx, gs->buf, '['); for (i = 0; i < stroke_state->dash_len; i++) { if (i > 0) fz_append_byte(ctx, gs->buf, ' '); fz_append_printf(ctx, gs->buf, "%g", stroke_state->dash_list[i]); } fz_append_printf(ctx, gs->buf, "]%g d\n", stroke_state->dash_phase); } fz_drop_stroke_state(ctx, gs->stroke_state); gs->stroke_state = fz_keep_stroke_state(ctx, stroke_state); }
static void write_simple_string(fz_context *ctx, fz_buffer *buf, const char *a, const char *b) { fz_append_byte(ctx, buf, '('); while (a < b) { int c; a += fz_chartorune(&c, a); c = fz_windows_1252_from_unicode(c); if (c < 0) c = REPLACEMENT; if (c == '(' || c == ')' || c == '\\') fz_append_byte(ctx, buf, '\\'); fz_append_byte(ctx, buf, c); } fz_append_byte(ctx, buf, ')'); }
char * fz_copy_selection(fz_context *ctx, fz_stext_page *page, fz_rect rect) { fz_buffer *buffer; fz_rect hitbox; int c, seen = 0; unsigned char *s; fz_stext_block *block; fz_stext_line *line; fz_stext_char *ch; float x0 = rect.x0; float x1 = rect.x1; float y0 = rect.y0; float y1 = rect.y1; buffer = fz_new_buffer(ctx, 1024); for (block = page->first_block; block; block = block->next) { if (block->type != FZ_STEXT_BLOCK_TEXT) continue; for (line = block->u.t.first_line; line; line = line->next) { if (seen) { fz_append_byte(ctx, buffer, '\n'); } seen = 0; for (ch = line->first_char; ch; ch = ch->next) { fz_stext_char_bbox(ctx, &hitbox, line, ch); c = ch->c; if (c < 32) c = FZ_REPLACEMENT_CHARACTER; if (hitbox.x1 >= x0 && hitbox.x0 <= x1 && hitbox.y1 >= y0 && hitbox.y0 <= y1) { fz_append_rune(ctx, buffer, c); seen = 1; } } seen = (seen && line == block->u.t.last_line); } } fz_terminate_buffer(ctx, buffer); fz_buffer_extract(ctx, buffer, &s); /* take over the data */ fz_drop_buffer(ctx, buffer); return (char*)s; }
static void pdf_write_ch_widget_appearance(fz_context *ctx, pdf_annot *annot, fz_buffer *buf, fz_rect *rect, fz_rect *bbox, fz_matrix *matrix, pdf_obj **res) { int ff = pdf_field_flags(ctx, annot->obj); if (ff & PDF_CH_FIELD_IS_COMBO) { /* TODO: Pop-down arrow */ pdf_write_tx_widget_appearance(ctx, annot, buf, rect, bbox, matrix, res, pdf_field_value(ctx, annot->obj), 0); } else { fz_buffer *text = fz_new_buffer(ctx, 1024); fz_try(ctx) { pdf_obj *opt = pdf_dict_get(ctx, annot->obj, PDF_NAME(Opt)); int i = pdf_dict_get_int(ctx, annot->obj, PDF_NAME(TI)); int n = pdf_array_len(ctx, opt); /* TODO: Scrollbar */ /* TODO: Highlight selected items */ if (i < 0) i = 0; for (; i < n; ++i) { pdf_obj *val = pdf_array_get(ctx, opt, i); if (pdf_is_array(ctx, val)) fz_append_string(ctx, text, pdf_array_get_text_string(ctx, val, 1)); else fz_append_string(ctx, text, pdf_to_text_string(ctx, val)); fz_append_byte(ctx, text, '\n'); } pdf_write_tx_widget_appearance(ctx, annot, buf, rect, bbox, matrix, res, fz_string_from_buffer(ctx, text), PDF_TX_FIELD_IS_MULTILINE); } fz_always(ctx) fz_drop_buffer(ctx, text); fz_catch(ctx) fz_rethrow(ctx); } }
static void on_copy_line_lf(fz_context *ctx, void *arg, fz_stext_line *line) { fz_buffer *buffer = arg; fz_append_byte(ctx, buffer, '\n'); }