Example #1
0
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");
}
Example #2
0
/* 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);
}
Example #3
0
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, ')');
}
Example #4
0
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;
}
Example #5
0
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);
	}
}
Example #6
0
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');
}