Esempio n. 1
0
static void
pdf_write_strike_out_appearance(fz_context *ctx, pdf_annot *annot, fz_buffer *buf, fz_rect *rect)
{
	fz_point quad[4], a, b;
	float h;
	pdf_obj *qp;
	int i, n;

	pdf_write_stroke_color_appearance(ctx, annot, buf);

	qp = pdf_dict_get(ctx, annot->obj, PDF_NAME(QuadPoints));
	n = pdf_array_len(ctx, qp);
	if (n > 0)
	{
		*rect = fz_empty_rect;
		for (i = 0; i < n; i += 8)
		{
			/* Acrobat draws the line at 3/7 of the box width from the bottom
			 * of the box and 1/16 thick of the box width. */

			h = extract_quad(ctx, quad, qp, i);
			a = lerp_point(quad[LL], quad[UL], 3/7.0f);
			b = lerp_point(quad[LR], quad[UR], 3/7.0f);

			fz_append_printf(ctx, buf, "%g w\n", h/16);
			fz_append_printf(ctx, buf, "%g %g m\n", a.x, a.y);
			fz_append_printf(ctx, buf, "%g %g l\n", b.x, b.y);
			fz_append_printf(ctx, buf, "S\n");

			union_quad(rect, quad, h/16);
		}
	}
}
Esempio n. 2
0
static pdf_obj *draw_check_button(fz_context *ctx, pdf_annot *annot, fz_rect bbox, fz_matrix matrix, float w, float h, int yes)
{
	float black[3] = { 0, 0, 0 };
	pdf_obj *ap, *res = NULL;
	fz_buffer *buf;
	float b;

	fz_var(res);

	buf = fz_new_buffer(ctx, 1024);
	fz_try(ctx)
	{
		fz_append_string(ctx, buf, "q\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);
		if (yes)
			write_variable_text(ctx, annot, buf, &res, "3", "ZaDb", h, black, 0, w, h, b+h/10, 0.8f, 1.2f, 0, 0, 0);
		fz_append_string(ctx, buf, "Q\n");
		ap = pdf_new_xobject(ctx, annot->page->doc, bbox, matrix, res, buf);
	}
	fz_always(ctx)
	{
		pdf_drop_obj(ctx, res);
		fz_drop_buffer(ctx, buf);
	}
	fz_catch(ctx)
		fz_rethrow(ctx);
	return ap;
}
Esempio n. 3
0
static void
write_stamp(fz_context *ctx, fz_buffer *buf, fz_font *font, const char *text, float y, float h)
{
	float tw = measure_simple_string(ctx, font, text) * h;
	fz_append_string(ctx, buf, "BT\n");
	fz_append_printf(ctx, buf, "/Times %g Tf\n", h);
	fz_append_printf(ctx, buf, "%g %g Td\n", (190-tw)/2, y);
	write_stamp_string(ctx, buf, font, text);
	fz_append_string(ctx, buf, " Tj\n");
	fz_append_string(ctx, buf, "ET\n");
}
Esempio n. 4
0
static void
draw_circle(fz_context *ctx, fz_buffer *buf, const char *op, float rx, float ry, float cx, float cy)
{
	float mx = rx * CIRCLE_MAGIC;
	float my = ry * CIRCLE_MAGIC;
	fz_append_printf(ctx, buf, "%g %g m\n", cx, cy+ry);
	fz_append_printf(ctx, buf, "%g %g %g %g %g %g c\n", cx+mx, cy+ry, cx+rx, cy+my, cx+rx, cy);
	fz_append_printf(ctx, buf, "%g %g %g %g %g %g c\n", cx+rx, cy-my, cx+mx, cy-ry, cx, cy-ry);
	fz_append_printf(ctx, buf, "%g %g %g %g %g %g c\n", cx-mx, cy-ry, cx-rx, cy-my, cx-rx, cy);
	fz_append_printf(ctx, buf, "%g %g %g %g %g %g c\n", cx-rx, cy+my, cx-mx, cy+ry, cx, cy+ry);
	fz_append_string(ctx, buf, op);
}
Esempio n. 5
0
static int pdf_write_MK_BC_appearance(fz_context *ctx, pdf_annot *annot, fz_buffer *buf)
{
	float color[4];
	int n;
	pdf_annot_MK_BC(ctx, annot, &n, color);
	switch (n)
	{
	default: return 0;
	case 1: fz_append_printf(ctx, buf, "%g G\n", color[0]); break;
	case 3: fz_append_printf(ctx, buf, "%g %g %g RG\n", color[0], color[1], color[2]); break;
	case 4: fz_append_printf(ctx, buf, "%g %g %g %g K\n", color[0], color[1], color[2], color[3]); break;
	}
	return 1;
}
Esempio n. 6
0
static void
write_simple_string_with_quadding(fz_context *ctx, fz_buffer *buf, fz_font *font, float size,
	const char *a, float maxw, int q)
{
	const char *b;
	float px = 0, x = 0, w;
	while (*a)
	{
		w = break_simple_string(ctx, font, size, a, &b, maxw);
		if (b > a)
		{
			if (q > 0)
			{
				if (q == 1)
					x = (maxw - w) / 2;
				else
					x = (maxw - w);
				fz_append_printf(ctx, buf, "%g %g Td ", x - px, -size);
			}
			if (b[-1] == '\n' || b[-1] == '\r')
				write_simple_string(ctx, buf, a, b-1);
			else
				write_simple_string(ctx, buf, a, b);
			a = b;
			px = x;
			fz_append_string(ctx, buf, (q > 0) ? "Tj\n" : "'\n");
		}
	}
}
Esempio n. 7
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");
}
Esempio n. 8
0
static void
pdf_write_squiggly_appearance(fz_context *ctx, pdf_annot *annot, fz_buffer *buf, fz_rect *rect)
{
	fz_point quad[4], a, b, c, v;
	float h, x, w;
	pdf_obj *qp;
	int i, n;

	*rect = fz_empty_rect;

	pdf_write_stroke_color_appearance(ctx, annot, buf);

	qp = pdf_dict_get(ctx, annot->obj, PDF_NAME(QuadPoints));
	n = pdf_array_len(ctx, qp);
	if (n > 0)
	{
		for (i = 0; i < n; i += 8)
		{
			int up = 1;
			h = extract_quad(ctx, quad, qp, i);
			v = fz_make_point(quad[LR].x - quad[LL].x, quad[LR].y - quad[LL].y);
			w = sqrtf(v.x * v.x + v.y * v.y);
			x = 0;

			fz_append_printf(ctx, buf, "%g w\n", h/16);
			fz_append_printf(ctx, buf, "%g %g m\n", quad[LL].x, quad[LL].y);
			while (x < w)
			{
				x += h/7;
				a = lerp_point(quad[LL], quad[LR], x/w);
				if (up)
				{
					b = lerp_point(quad[UL], quad[UR], x/w);
					c = lerp_point(a, b, 1/7.0f);
					fz_append_printf(ctx, buf, "%g %g l\n", c.x, c.y);
				}
				else
					fz_append_printf(ctx, buf, "%g %g l\n", a.x, a.y);
				up = !up;
			}
			fz_append_printf(ctx, buf, "S\n");

			union_quad(rect, quad, h/16);
		}
	}
}
Esempio n. 9
0
static void
pdf_write_sig_widget_appearance(fz_context *ctx, pdf_annot *annot, fz_buffer *buf,
	fz_rect *rect, fz_rect *bbox, fz_matrix *matrix, pdf_obj **res)
{
	float x0 = rect->x0 + 1;
	float y0 = rect->y0 + 1;
	float x1 = rect->x1 - 1;
	float y1 = rect->y1 - 1;
	float w = x1 - x0;
	float h = y1 - y0;
	fz_append_printf(ctx, buf, "1 w\n0 G\n");
	fz_append_printf(ctx, buf, "%g %g %g %g re\n", x0, y0, w, h);
	fz_append_printf(ctx, buf, "%g %g m %g %g l\n", x0, y0, x1, y1);
	fz_append_printf(ctx, buf, "%g %g m %g %g l\n", x1, y0, x0, y1);
	fz_append_printf(ctx, buf, "s\n");
	*bbox = *rect;
	*matrix = fz_identity;
}
Esempio n. 10
0
static void pdf_write_arrow_appearance(fz_context *ctx, fz_buffer *buf, fz_rect *rect, float x, float y, float dx, float dy, float w)
{
	float r = fz_max(1, w);
	float angle = atan2f(dy, dx);
	fz_point v, a, b;

	v = rotate_vector(angle, 8.8f*r, 4.5f*r);
	a = fz_make_point(x + v.x, y + v.y);
	v = rotate_vector(angle, 8.8f*r, -4.5f*r);
	b = fz_make_point(x + v.x, y + v.y);

	*rect = fz_include_point_in_rect(*rect, a);
	*rect = fz_include_point_in_rect(*rect, b);
	*rect = fz_expand_rect(*rect, w);

	fz_append_printf(ctx, buf, "%g %g m\n", a.x, a.y);
	fz_append_printf(ctx, buf, "%g %g l\n", x, y);
	fz_append_printf(ctx, buf, "%g %g l\n", b.x, b.y);
}
Esempio n. 11
0
static void
pdf_write_free_text_appearance(fz_context *ctx, pdf_annot *annot, fz_buffer *buf,
	fz_rect *rect, fz_rect *bbox, fz_matrix *matrix, pdf_obj **res)
{
	const char *font;
	float size, color[3];
	const char *text;
	float w, h, t, b;
	int q, r;

	/* /Rotate is an undocumented annotation property supported by Adobe */
	text = pdf_annot_contents(ctx, annot);
	r = pdf_dict_get_int(ctx, annot->obj, PDF_NAME(Rotate));
	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);

	if (pdf_write_fill_color_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)
	{
		fz_append_printf(ctx, buf, "%g %g %g RG\n", color[0], color[1], color[2]);
		fz_append_printf(ctx, buf, "%g %g %g %g re\nS\n", b/2, b/2, w-b, h-b);
	}

	fz_append_printf(ctx, buf, "%g %g %g %g re\nW\nn\n", b, b, w-b*2, h-b*2);

	write_variable_text(ctx, annot, buf, res, text, font, size, color, q, w, h, b*2,
		0.8f, 1.2f, 1, 0, 0);
}
Esempio n. 12
0
static void
pdf_dev_ctm(fz_context *ctx, pdf_device *pdev, fz_matrix ctm)
{
	fz_matrix inverse;
	gstate *gs = CURRENT_GSTATE(pdev);

	if (memcmp(&gs->ctm, &ctm, sizeof(ctm)) == 0)
		return;
	inverse = fz_invert_matrix(gs->ctm);
	inverse = fz_concat(ctm, inverse);
	gs->ctm = ctm;
	fz_append_printf(ctx, gs->buf, "%M cm\n", &inverse);
}
Esempio n. 13
0
static void
pdf_write_polygon_appearance(fz_context *ctx, pdf_annot *annot, fz_buffer *buf, fz_rect *rect, int close)
{
	pdf_obj *verts;
	fz_point p;
	int i, n;
	float lw;

	lw = pdf_write_border_appearance(ctx, annot, buf);
	pdf_write_stroke_color_appearance(ctx, annot, buf);

	*rect = fz_empty_rect;

	verts = pdf_dict_get(ctx, annot->obj, PDF_NAME(Vertices));
	n = pdf_array_len(ctx, verts) / 2;
	if (n > 0)
	{
		for (i = 0; i < n; ++i)
		{
			p.x = pdf_array_get_real(ctx, verts, i*2+0);
			p.y = pdf_array_get_real(ctx, verts, i*2+1);
			if (i == 0)
			{
				rect->x0 = rect->x1 = p.x;
				rect->y0 = rect->y1 = p.y;
			}
			else
				*rect = fz_include_point_in_rect(*rect, p);
			if (i == 0)
				fz_append_printf(ctx, buf, "%g %g m\n", p.x, p.y);
			else
				fz_append_printf(ctx, buf, "%g %g l\n", p.x, p.y);
		}
		fz_append_string(ctx, buf, close ? "s" : "S");
		*rect = fz_expand_rect(*rect, lw);
	}
}
Esempio n. 14
0
static void
pdf_write_ink_appearance(fz_context *ctx, pdf_annot *annot, fz_buffer *buf, fz_rect *rect)
{
	pdf_obj *ink_list, *stroke;
	int i, n, k, m;
	float lw;
	fz_point p;

	lw = pdf_write_border_appearance(ctx, annot, buf);
	pdf_write_stroke_color_appearance(ctx, annot, buf);

	*rect = fz_empty_rect;

	ink_list = pdf_dict_get(ctx, annot->obj, PDF_NAME(InkList));
	n = pdf_array_len(ctx, ink_list);
	for (i = 0; i < n; ++i)
	{
		stroke = pdf_array_get(ctx, ink_list, i);
		m = pdf_array_len(ctx, stroke) / 2;
		for (k = 0; k < m; ++k)
		{
			p.x = pdf_array_get_real(ctx, stroke, k*2+0);
			p.y = pdf_array_get_real(ctx, stroke, k*2+1);
			if (i == 0 && k == 0)
			{
				rect->x0 = rect->x1 = p.x;
				rect->y0 = rect->y1 = p.y;
			}
			else
				*rect = fz_include_point_in_rect(*rect, p);
			fz_append_printf(ctx, buf, "%g %g %c\n", p.x, p.y, k == 0 ? 'm' : 'l');
		}
	}
	fz_append_printf(ctx, buf, "S");
	*rect = fz_expand_rect(*rect, lw);
}
Esempio n. 15
0
static int make_fake_doc(pdfapp_t *app)
{
	fz_context *ctx = app->ctx;
	pdf_document *pdf = NULL;
	fz_buffer *contents = NULL;
	pdf_obj *page_obj = NULL;

	fz_var(contents);
	fz_var(page_obj);

	fz_try(ctx)
	{
		fz_rect mediabox = { 0, 0, app->winw, app->winh };
		int i;

		pdf = pdf_create_document(ctx);


		contents = fz_new_buffer(ctx, 100);
		fz_append_printf(ctx, contents, "1 0 0 RG %g w 0 0 m %g %g l 0 %g m %g 0 l s\n",
			fz_min(mediabox.x1, mediabox.y1) / 20,
			mediabox.x1, mediabox.y1,
			mediabox.y1, mediabox.x1);

		/* Create enough copies of our blank(ish) page so that the
		 * page number is preserved if and when a subsequent load
		 * works. */
		page_obj = pdf_add_page(ctx, pdf, &mediabox, 0, NULL, contents);
		for (i = 0; i < app->pagecount; i++)
			pdf_insert_page(ctx, pdf, -1, page_obj);
	}
	fz_always(ctx)
	{
		pdf_drop_obj(ctx, page_obj);
		fz_drop_buffer(ctx, contents);
	}
	fz_catch(ctx)
	{
		fz_drop_document(ctx, (fz_document *) pdf);
		return 1;
	}

	app->doc = (fz_document*)pdf;
	return 0;
}
Esempio n. 16
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);
}
Esempio n. 17
0
static void
pdf_write_square_appearance(fz_context *ctx, pdf_annot *annot, fz_buffer *buf, fz_rect *rect)
{
	float x, y, w, h;
	float lw;
	int ic;

	lw = pdf_write_border_appearance(ctx, annot, buf);
	pdf_write_stroke_color_appearance(ctx, annot, buf);
	ic = pdf_write_interior_fill_color_appearance(ctx, annot, buf);

	x = rect->x0 + lw;
	y = rect->y0 + lw;
	w = rect->x1 - x - lw;
	h = rect->y1 - y - lw;

	fz_append_printf(ctx, buf, "%g %g %g %g re\n", x, y, w, h);
	fz_append_string(ctx, buf, ic ? "b" : "s");
}
Esempio n. 18
0
static void
pdf_write_line_appearance(fz_context *ctx, pdf_annot *annot, fz_buffer *buf, fz_rect *rect)
{
	pdf_obj *line, *le;
	fz_point a, b;
	float w;
	int ic;

	w = pdf_write_border_appearance(ctx, annot, buf);
	pdf_write_stroke_color_appearance(ctx, annot, buf);
	ic = pdf_write_interior_fill_color_appearance(ctx, annot, buf);

	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_append_printf(ctx, buf, "%g %g m\n%g %g l\nS\n", a.x, a.y, b.x, b.y);

	rect->x0 = fz_min(a.x, b.x);
	rect->y0 = fz_min(a.y, b.y);
	rect->x1 = fz_max(a.x, b.x);
	rect->y1 = fz_max(a.y, b.y);

	le = pdf_dict_get(ctx, annot->obj, PDF_NAME(LE));
	if (pdf_array_len(ctx, le) == 2)
	{
		float dx = b.x - a.x;
		float dy = b.y - a.y;
		float l = sqrtf(dx*dx + dy*dy);
		pdf_write_line_cap_appearance(ctx, buf, rect, a.x, a.y, dx/l, dy/l, w, ic, pdf_array_get(ctx, le, 0));
		pdf_write_line_cap_appearance(ctx, buf, rect, b.x, b.y, -dx/l, -dy/l, w, ic, pdf_array_get(ctx, le, 1));
	}
	*rect = fz_expand_rect(*rect, fz_max(1, w));
}
Esempio n. 19
0
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");
}
Esempio n. 20
0
static void
pdf_dev_color(fz_context *ctx, pdf_device *pdev, fz_colorspace *colorspace, const float *color, int stroke, const fz_color_params *color_params)
{
	int diff = 0;
	int i;
	int cspace = 0;
	float rgb[FZ_MAX_COLORS];
	gstate *gs = CURRENT_GSTATE(pdev);

	if (colorspace == fz_device_gray(ctx))
		cspace = 1;
	else if (colorspace == fz_device_rgb(ctx))
		cspace = 3;
	else if (colorspace == fz_device_cmyk(ctx))
		cspace = 4;

	if (cspace == 0)
	{
		/* If it's an unknown colorspace, fallback to rgb */
		fz_convert_color(ctx, color_params, NULL, fz_device_rgb(ctx), rgb, colorspace, color);
		color = rgb;
		colorspace = fz_device_rgb(ctx);
		cspace = 3;
	}

	if (gs->colorspace[stroke] != colorspace)
	{
		gs->colorspace[stroke] = colorspace;
		diff = 1;
	}

	for (i=0; i < cspace; i++)
		if (gs->color[stroke][i] != color[i])
		{
			gs->color[stroke][i] = color[i];
			diff = 1;
		}

	if (diff == 0)
		return;

	switch (cspace + stroke*8)
	{
		case 1:
			fz_append_printf(ctx, gs->buf, "%g g\n", color[0]);
			break;
		case 3:
			fz_append_printf(ctx, gs->buf, "%g %g %g rg\n", color[0], color[1], color[2]);
			break;
		case 4:
			fz_append_printf(ctx, gs->buf, "%g %g %g %g k\n", color[0], color[1], color[2], color[3]);
			break;
		case 1+8:
			fz_append_printf(ctx, gs->buf, "%g G\n", color[0]);
			break;
		case 3+8:
			fz_append_printf(ctx, gs->buf, "%g %g %g RG\n", color[0], color[1], color[2]);
			break;
		case 4+8:
			fz_append_printf(ctx, gs->buf, "%g %g %g %g K\n", color[0], color[1], color[2], color[3]);
			break;
	}
}
Esempio n. 21
0
static pdf_obj *draw_push_button(fz_context *ctx, pdf_annot *annot, fz_rect bbox, fz_matrix matrix, float w, float h,
	const char *caption, const char *font, float size, float color[3],
	int down)
{
	pdf_obj *ap, *res = NULL;
	fz_buffer *buf;
	float bc[3] = { 0, 0, 0 };
	float bg[3] = { 0.8f, 0.8f, 0.8f };
	float hi[3], sh[3];
	int has_bg, has_bc;
	float b;
	int i;

	buf = fz_new_buffer(ctx, 1024);
	fz_var(res);
	fz_try(ctx)
	{
		b = pdf_annot_border(ctx, annot);
		has_bc = pdf_annot_MK_BC_rgb(ctx, annot, bc);
		has_bg = pdf_annot_MK_BG_rgb(ctx, annot, bg);

		for (i = 0; i < 3; ++i)
		{
			if (down)
			{
				sh[i] = 1 - (1 - bg[i]) / 2;
				hi[i] = bg[i] / 2;
			}
			else
			{
				hi[i] = 1 - (1 - bg[i]) / 2;
				sh[i] = bg[i] / 2;
			}
		}

		fz_append_string(ctx, buf, "q\n");
		fz_append_printf(ctx, buf, "%g w\n", b);
		if (has_bg)
		{
			fz_append_printf(ctx, buf, "%g %g %g rg\n", bg[0], bg[1], bg[2]);
			fz_append_printf(ctx, buf, "0 0 %g %g re\nf\n", 0, 0, w, h);
		}
		if (has_bc && b > 0)
		{
			fz_append_printf(ctx, buf, "%g %g %g RG\n", bc[0], bc[1], bc[2]);
			fz_append_printf(ctx, buf, "%g %g %g %g re\nS\n", b/2, b/2, w-b, h-b);
		}
		if (has_bg)
		{
			fz_append_printf(ctx, buf, "%g %g %g rg\n", hi[0], hi[1], hi[2]);
			fz_append_printf(ctx, buf, "%g %g m %g %g l %g %g l %g %g l %g %g l %g %g l f\n",
				b, b, b, h-b, w-b, h-b, w-b-2, h-b-2, b+2, h-b-2, b+2, b+2);
			fz_append_printf(ctx, buf, "%g %g %g rg\n", sh[0], sh[1], sh[2]);
			fz_append_printf(ctx, buf, "%g %g m %g %g l %g %g l %g %g l %g %g l %g %g l f\n",
				b, b, b+2, b+2, w-b-2, b+2, w-b-2, h-b-2, w-b, h-b, w-b, b);
		}
		if (down)
			fz_append_string(ctx, buf, "1 0 0 1 2 -2 cm\n");
		write_variable_text(ctx, annot, buf, &res, caption, font, size, color, 1, w, h, b+6, 0.8f, 1.2f, 0, 0, 0);
		fz_append_string(ctx, buf, "Q\n");

		ap = pdf_new_xobject(ctx, annot->page->doc, bbox, matrix, res, buf);
	}
	fz_always(ctx)
	{
		pdf_drop_obj(ctx, res);
		fz_drop_buffer(ctx, buf);
	}
	fz_catch(ctx)
		fz_rethrow(ctx);
	return ap;
}
Esempio n. 22
0
static void
pdf_dev_path_curveto(fz_context *ctx, void *arg, float x1, float y1, float x2, float y2, float x3, float y3)
{
	fz_buffer *buf = (fz_buffer *)arg;
	fz_append_printf(ctx, buf, "%g %g %g %g %g %g c\n", x1, y1, x2, y2, x3, y3);
}
Esempio n. 23
0
static void
pdf_dev_path_lineto(fz_context *ctx, void *arg, float x, float y)
{
	fz_buffer *buf = (fz_buffer *)arg;
	fz_append_printf(ctx, buf, "%g %g l\n", x, y);
}
Esempio n. 24
0
static void
pdf_write_line_cap_appearance(fz_context *ctx, fz_buffer *buf, fz_rect *rect,
		float x, float y, float dx, float dy, float w, int ic, pdf_obj *cap)
{
	if (cap == PDF_NAME(Square))
	{
		float r = fz_max(2.5f, w * 2.5f);
		fz_append_printf(ctx, buf, "%g %g %g %g re\n", x-r, y-r, r*2, r*2);
		fz_append_string(ctx, buf, ic ? "b\n" : "s\n");
		include_cap(rect, x, y, r);
	}
	else if (cap == PDF_NAME(Circle))
	{
		float r = fz_max(2.5f, w * 2.5f);
		float m = r * CIRCLE_MAGIC;
		fz_append_printf(ctx, buf, "%g %g m\n", x, y+r);
		fz_append_printf(ctx, buf, "%g %g %g %g %g %g c\n", x+m, y+r, x+r, y+m, x+r, y);
		fz_append_printf(ctx, buf, "%g %g %g %g %g %g c\n", x+r, y-m, x+m, y-r, x, y-r);
		fz_append_printf(ctx, buf, "%g %g %g %g %g %g c\n", x-m, y-r, x-r, y-m, x-r, y);
		fz_append_printf(ctx, buf, "%g %g %g %g %g %g c\n", x-r, y+m, x-m, y+r, x, y+r);
		fz_append_string(ctx, buf, ic ? "b\n" : "s\n");
		include_cap(rect, x, y, r);
	}
	else if (cap == PDF_NAME(Diamond))
	{
		float r = fz_max(2.5f, w * 2.5f);
		fz_append_printf(ctx, buf, "%g %g m\n", x, y+r);
		fz_append_printf(ctx, buf, "%g %g l\n", x+r, y);
		fz_append_printf(ctx, buf, "%g %g l\n", x, y-r);
		fz_append_printf(ctx, buf, "%g %g l\n", x-r, y);
		fz_append_string(ctx, buf, ic ? "b\n" : "s\n");
		include_cap(rect, x, y, r);
	}
	else if (cap == PDF_NAME(OpenArrow))
	{
		pdf_write_arrow_appearance(ctx, buf, rect, x, y, dx, dy, w);
		fz_append_string(ctx, buf, "S\n");
	}
	else if (cap == PDF_NAME(ClosedArrow))
	{
		pdf_write_arrow_appearance(ctx, buf, rect, x, y, dx, dy, w);
		fz_append_string(ctx, buf, ic ? "b\n" : "s\n");
	}
	/* PDF 1.5 */
	else if (cap == PDF_NAME(Butt))
	{
		float r = fz_max(3, w * 3);
		fz_point a = { x-dy*r, y+dx*r };
		fz_point b = { x+dy*r, y-dx*r };
		fz_append_printf(ctx, buf, "%g %g m\n", a.x, a.y);
		fz_append_printf(ctx, buf, "%g %g l\n", b.x, b.y);
		fz_append_string(ctx, buf, "S\n");
		*rect = fz_include_point_in_rect(*rect, a);
		*rect = fz_include_point_in_rect(*rect, b);
	}
	/* PDF 1.6 */
	else if (cap == PDF_NAME(ROpenArrow))
	{
		pdf_write_arrow_appearance(ctx, buf, rect, x, y, -dx, -dy, w);
		fz_append_string(ctx, buf, "S\n");
	}
	else if (cap == PDF_NAME(RClosedArrow))
	{
		pdf_write_arrow_appearance(ctx, buf, rect, x, y, -dx, -dy, w);
		fz_append_string(ctx, buf, ic ? "b\n" : "s\n");
	}
	else if (cap == PDF_NAME(Slash))
	{
		float r = fz_max(5, w * 5);
		float angle = atan2f(dy, dx) - (30 * FZ_PI / 180);
		fz_point a, b, v;
		v = rotate_vector(angle, 0, r);
		a = fz_make_point(x + v.x, y + v.y);
		v = rotate_vector(angle, 0, -r);
		b = fz_make_point(x + v.x, y + v.y);
		fz_append_printf(ctx, buf, "%g %g m\n", a.x, a.y);
		fz_append_printf(ctx, buf, "%g %g l\n", b.x, b.y);
		fz_append_string(ctx, buf, "S\n");
		*rect = fz_include_point_in_rect(*rect, a);
		*rect = fz_include_point_in_rect(*rect, b);
	}
}
Esempio n. 25
0
static void
write_variable_text(fz_context *ctx, pdf_annot *annot, fz_buffer *buf, pdf_obj **res,
	const char *text, const char *fontname, float size, float color[3], int q,
	float w, float h, float padding, float baseline, float lineheight,
	int multiline, int comb, int adjust_baseline)
{
	pdf_obj *res_font;
	fz_font *font;

	w -= padding * 2;
	h -= padding * 2;

	font = fz_new_base14_font(ctx, full_font_name(&fontname));
	fz_try(ctx)
	{
		if (size == 0)
		{
			if (multiline)
				size = 12;
			else
			{
				size = w / measure_simple_string(ctx, font, text);
				if (size > h)
					size = h;
			}
		}

		lineheight = size * lineheight;
		baseline = size * baseline;

		if (adjust_baseline)
		{
			/* Make sure baseline is inside rectangle */
			if (baseline + 0.2f * size > h)
				baseline = h - 0.2f * size;
		}

		/* /Resources << /Font << /Helv %d 0 R >> >> */
		*res = pdf_new_dict(ctx, annot->page->doc, 1);
		res_font = pdf_dict_put_dict(ctx, *res, PDF_NAME(Font), 1);
		pdf_dict_puts_drop(ctx, res_font, fontname, pdf_add_simple_font(ctx, annot->page->doc, font, 0));

		fz_append_string(ctx, buf, "BT\n");
		fz_append_printf(ctx, buf, "%g %g %g rg\n", color[0], color[1], color[2]);
		fz_append_printf(ctx, buf, "/%s %g Tf\n", fontname, size);
		if (multiline)
		{
			fz_append_printf(ctx, buf, "%g TL\n", lineheight);
			fz_append_printf(ctx, buf, "%g %g Td\n", padding, padding+h-baseline+lineheight);
			write_simple_string_with_quadding(ctx, buf, font, size, text, w, q);
		}
		else if (comb > 0)
		{
			float ty = (h - size) / 2;
			fz_append_printf(ctx, buf, "%g %g Td\n", padding, padding+h-baseline-ty);
			write_comb_string(ctx, buf, text, text + strlen(text), font, (w * 1000 / size) / comb);
		}
		else
		{
			float tx = 0, ty = (h - size) / 2;
			if (q > 0)
			{
				float tw = measure_simple_string(ctx, font, text) * size;
				if (q == 1)
					tx = (w - tw) / 2;
				else
					tx = (w - tw);
			}
			fz_append_printf(ctx, buf, "%g %g Td\n", padding+tx, padding+h-baseline-ty);
			write_simple_string(ctx, buf, text, text + strlen(text));
			fz_append_printf(ctx, buf, " Tj\n");
		}
		fz_append_string(ctx, buf, "ET\n");
	}
	fz_always(ctx)
		fz_drop_font(ctx, font);
	fz_catch(ctx)
		fz_rethrow(ctx);
}
Esempio n. 26
0
static float pdf_write_border_appearance(fz_context *ctx, pdf_annot *annot, fz_buffer *buf)
{
	float w = pdf_annot_border(ctx, annot);
	fz_append_printf(ctx, buf, "%g w\n", w);
	return w;
}
Esempio n. 27
0
static void
pdf_write_stamp_appearance(fz_context *ctx, pdf_annot *annot, fz_buffer *buf, fz_rect *rect, fz_rect *bbox, pdf_obj **res)
{
	fz_font *font;
	pdf_obj *res_font;
	pdf_obj *name;
	float w, h, xs, ys;
	fz_matrix rotate;

	name = pdf_dict_get(ctx, annot->obj, PDF_NAME(Name));
	if (!name)
		name = PDF_NAME(Draft);

	h = rect->y1 - rect->y0;
	w = rect->x1 - rect->x0;
	xs = w / 190;
	ys = h / 50;

	font = fz_new_base14_font(ctx, "Times-Bold");
	fz_try(ctx)
	{
		/* /Resources << /Font << /Times %d 0 R >> >> */
		*res = pdf_new_dict(ctx, annot->page->doc, 1);
		res_font = pdf_dict_put_dict(ctx, *res, PDF_NAME(Font), 1);
		pdf_dict_put_drop(ctx, res_font, PDF_NAME(Times), pdf_add_simple_font(ctx, annot->page->doc, font, 0));

		pdf_write_fill_color_appearance(ctx, annot, buf);
		pdf_write_stroke_color_appearance(ctx, annot, buf);
		rotate = fz_rotate(0.6f);
		fz_append_printf(ctx, buf, "%M cm\n", &rotate);
		fz_append_string(ctx, buf, "2 w\n2 2 186 44 re\nS\n");

		if (name == PDF_NAME(Approved))
			write_stamp(ctx, buf, font, "APPROVED", 13, 30);
		else if (name == PDF_NAME(AsIs))
			write_stamp(ctx, buf, font, "AS IS", 13, 30);
		else if (name == PDF_NAME(Confidential))
			write_stamp(ctx, buf, font, "CONFIDENTIAL", 17, 20);
		else if (name == PDF_NAME(Departmental))
			write_stamp(ctx, buf, font, "DEPARTMENTAL", 17, 20);
		else if (name == PDF_NAME(Experimental))
			write_stamp(ctx, buf, font, "EXPERIMENTAL", 17, 20);
		else if (name == PDF_NAME(Expired))
			write_stamp(ctx, buf, font, "EXPIRED", 13, 30);
		else if (name == PDF_NAME(Final))
			write_stamp(ctx, buf, font, "FINAL", 13, 30);
		else if (name == PDF_NAME(ForComment))
			write_stamp(ctx, buf, font, "FOR COMMENT", 17, 20);
		else if (name == PDF_NAME(ForPublicRelease))
		{
			write_stamp(ctx, buf, font, "FOR PUBLIC", 26, 18);
			write_stamp(ctx, buf, font, "RELEASE", 8.5f, 18);
		}
		else if (name == PDF_NAME(NotApproved))
			write_stamp(ctx, buf, font, "NOT APPROVED", 17, 20);
		else if (name == PDF_NAME(NotForPublicRelease))
		{
			write_stamp(ctx, buf, font, "NOT FOR", 26, 18);
			write_stamp(ctx, buf, font, "PUBLIC RELEASE", 8.5, 18);
		}
		else if (name == PDF_NAME(Sold))
			write_stamp(ctx, buf, font, "SOLD", 13, 30);
		else if (name == PDF_NAME(TopSecret))
			write_stamp(ctx, buf, font, "TOP SECRET", 14, 26);
		else if (name == PDF_NAME(Draft))
			write_stamp(ctx, buf, font, "DRAFT", 13, 30);
		else
			write_stamp(ctx, buf, font, pdf_to_name(ctx, name), 17, 20);
	}
	fz_always(ctx)
		fz_drop_font(ctx, font);
	fz_catch(ctx)
		fz_rethrow(ctx);

	*bbox = fz_make_rect(0, 0, 190, 50);
	if (xs > ys)
	{
		float xc = (rect->x1+rect->x0) / 2;
		rect->x0 = xc - 95 * ys;
		rect->x1 = xc + 95 * ys;
	}
	else
	{
		float yc = (rect->y1+rect->y0) / 2;
		rect->y0 = yc - 25 * xs;
		rect->y1 = yc + 25 * xs;
	}
}
Esempio n. 28
0
static void
pdf_write_highlight_appearance(fz_context *ctx, pdf_annot *annot, fz_buffer *buf, fz_rect *rect, pdf_obj **res)
{
	pdf_obj *res_egs, *res_egs_h;
	pdf_obj *qp;
	fz_point quad[4], mquad[4], v;
	float opacity, h, m, dx, dy, vn;
	int i, n;

	*rect = fz_empty_rect;

	/* /Resources << /ExtGState << /H << /Type/ExtGState /BM/Multiply /CA %g >> >> >> */
	*res = pdf_new_dict(ctx, annot->page->doc, 1);
	res_egs = pdf_dict_put_dict(ctx, *res, PDF_NAME(ExtGState), 1);
	res_egs_h = pdf_dict_put_dict(ctx, res_egs, PDF_NAME(H), 2);
	pdf_dict_put(ctx, res_egs_h, PDF_NAME(Type), PDF_NAME(ExtGState));
	pdf_dict_put(ctx, res_egs_h, PDF_NAME(BM), PDF_NAME(Multiply));
	opacity = pdf_annot_opacity(ctx, annot);
	if (opacity < 1)
		pdf_dict_put_real(ctx, res_egs_h, PDF_NAME(ca), opacity);

	pdf_write_fill_color_appearance(ctx, annot, buf);

	fz_append_printf(ctx, buf, "/H gs\n");

	qp = pdf_dict_get(ctx, annot->obj, PDF_NAME(QuadPoints));
	n = pdf_array_len(ctx, qp);
	if (n > 0)
	{
		for (i = 0; i < n; i += 8)
		{
			h = extract_quad(ctx, quad, qp, i);
			m = h / 4.2425f; /* magic number that matches adobe's appearance */
			dx = quad[LR].x - quad[LL].x;
			dy = quad[LR].y - quad[LL].y;
			vn = sqrtf(dx * dx + dy * dy);
			v = fz_make_point(dx * m / vn, dy * m / vn);

			mquad[LL].x = quad[LL].x - v.x - v.y;
			mquad[LL].y = quad[LL].y - v.y + v.x;
			mquad[UL].x = quad[UL].x - v.x + v.y;
			mquad[UL].y = quad[UL].y - v.y - v.x;
			mquad[LR].x = quad[LR].x + v.x - v.y;
			mquad[LR].y = quad[LR].y + v.y + v.x;
			mquad[UR].x = quad[UR].x + v.x + v.y;
			mquad[UR].y = quad[UR].y + v.y - v.x;

			fz_append_printf(ctx, buf, "%g %g m\n", quad[LL].x, quad[LL].y);
			fz_append_printf(ctx, buf, "%g %g %g %g %g %g c\n",
				mquad[LL].x, mquad[LL].y,
				mquad[UL].x, mquad[UL].y,
				quad[UL].x, quad[UL].y);
			fz_append_printf(ctx, buf, "%g %g l\n", quad[UR].x, quad[UR].y);
			fz_append_printf(ctx, buf, "%g %g %g %g %g %g c\n",
				mquad[UR].x, mquad[UR].y,
				mquad[LR].x, mquad[LR].y,
				quad[LR].x, quad[LR].y);
			fz_append_printf(ctx, buf, "f\n");

			union_quad(rect, quad, h/16);
			union_quad(rect, mquad, 0);
		}
	}
}