Beispiel #1
0
static pdf_annot *
pdf_create_freetext_annot(pdf_xref *xref, fz_obj *obj)
{
	fz_context *ctx = xref->ctx;
	fz_buffer *content = fz_new_buffer(ctx, 256);
	fz_buffer *base_ap = fz_new_buffer(ctx, 256);
	fz_obj *ap = fz_dict_gets(ctx, obj, "DA");
	fz_obj *value = fz_dict_gets(ctx, obj, "Contents");
	fz_rect rect = pdf_to_rect(ctx, fz_dict_gets(ctx, obj, "Rect"));
	int align = fz_to_int(ctx, fz_dict_gets(ctx, obj, "Q"));
	fz_obj *res = pdf_dict_from_string(xref, ANNOT_FREETEXT_AP_RESOURCES);
	unsigned short *ucs2, *rest;
	float x;

	char *font_name = NULL;
	float font_size = pdf_extract_font_size(xref, fz_to_str_buf(ctx, ap), &font_name);
	if (!font_size)
		font_size = 10;
	/* TODO: what resource dictionary does this font name refer to? */
	if (font_name)
	{
		fz_obj *font = fz_dict_gets(ctx, res, "Font");
		fz_dict_puts(ctx, font, font_name, fz_dict_gets(ctx, font, "Default"));
		fz_free(ctx, font_name);
	}

	fz_buffer_printf(ctx, content, "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, "q BT %s ", fz_to_str_buf(ctx, ap));
	fz_buffer_printf(ctx, content, "/Default %.4f Tf ", font_size);
	fz_buffer_printf(ctx, base_ap, "/Default %.4f Tf ", font_size);
	fz_buffer_printf(ctx, content, "1 0 0 1 2 %.4f Tm ", rect.y1 - rect.y0 - 2);

	/* Adobe Reader seems to consider "[1 0 0] r" and "1 0 0 rg" to mean the same(?) */
	if (strchr(base_ap->data, '['))
	{
		float r, g, b;
		if (sscanf(strchr(base_ap->data, '['), "[%f %f %f] r", &r, &g, &b) == 3)
			fz_buffer_printf(ctx, content, "%.4f %.4f %.4f rg ", r, g, b);
	}

	ucs2 = pdf_to_ucs2(ctx, value);
	for (rest = ucs2; *rest; rest++)
		if (*rest > 0xFF)
			*rest = '?';

	x = 0;
	rest = ucs2;
	while (*rest)
		rest = pdf_append_line(xref, res, content, base_ap, rest, font_size, align, rect.x1 - rect.x0 - 4.0f, 1, &x);

	fz_free(ctx, ucs2);
	fz_buffer_printf(ctx, content, "ET Q");
	fz_drop_buffer(ctx, base_ap);

	return pdf_create_annot(ctx, rect, fz_keep_obj(obj), content, res, 0);
}
Beispiel #2
0
/* Convert Unicode/PdfDocEncoding string into ucs-2 */
unsigned short *
pdf_to_ucs2(fz_obj *src)
{
	unsigned char *srcptr = (unsigned char *) fz_to_str_buf(src);
	unsigned short *dstptr, *dst;
	int srclen = fz_to_str_len(src);
	int i;

	if (srclen >= 2 && srcptr[0] == 254 && srcptr[1] == 255)
	{
		dstptr = dst = fz_calloc((srclen - 2) / 2 + 1, sizeof(short));
		for (i = 2; i + 1 < srclen; i += 2)
			*dstptr++ = srcptr[i] << 8 | srcptr[i+1];
	}
	else if (srclen >= 2 && srcptr[0] == 255 && srcptr[1] == 254)
	{
		dstptr = dst = fz_calloc((srclen - 2) / 2 + 1, sizeof(short));
		for (i = 2; i + 1 < srclen; i += 2)
			*dstptr++ = srcptr[i] | srcptr[i+1] << 8;
	}
	else
	{
		dstptr = dst = fz_calloc(srclen + 1, sizeof(short));
		for (i = 0; i < srclen; i++)
			*dstptr++ = pdf_doc_encoding[srcptr[i]];
	}

	*dstptr = '\0';
	return dst;
}
Beispiel #3
0
/* Convert Unicode/PdfDocEncoding string into utf-8 */
char *
pdf_to_utf8(fz_obj *src)
{
	unsigned char *srcptr = (unsigned char *) fz_to_str_buf(src);
	char *dstptr, *dst;
	int srclen = fz_to_str_len(src);
	int dstlen = 0;
	int ucs;
	int i;

	if (srclen >= 2 && srcptr[0] == 254 && srcptr[1] == 255)
	{
		for (i = 2; i + 1 < srclen; i += 2)
		{
			ucs = srcptr[i] << 8 | srcptr[i+1];
			dstlen += runelen(ucs);
		}

		dstptr = dst = fz_malloc(dstlen + 1);

		for (i = 2; i + 1 < srclen; i += 2)
		{
			ucs = srcptr[i] << 8 | srcptr[i+1];
			dstptr += runetochar(dstptr, &ucs);
		}
	}
	else if (srclen >= 2 && srcptr[0] == 255 && srcptr[1] == 254)
	{
		for (i = 2; i + 1 < srclen; i += 2)
		{
			ucs = srcptr[i] | srcptr[i+1] << 8;
			dstlen += runelen(ucs);
		}

		dstptr = dst = fz_malloc(dstlen + 1);

		for (i = 2; i + 1 < srclen; i += 2)
		{
			ucs = srcptr[i] | srcptr[i+1] << 8;
			dstptr += runetochar(dstptr, &ucs);
		}
	}
	else
	{
		for (i = 0; i < srclen; i++)
			dstlen += runelen(pdf_doc_encoding[srcptr[i]]);

		dstptr = dst = fz_malloc(dstlen + 1);

		for (i = 0; i < srclen; i++)
		{
			ucs = pdf_doc_encoding[srcptr[i]];
			dstptr += runetochar(dstptr, &ucs);
		}
	}

	*dstptr = '\0';
	return dst;
}
Beispiel #4
0
static void pdfapp_gotouri(pdfapp_t *app, fz_obj *uri)
{
	char *buf;
	buf = fz_malloc(fz_to_str_len(uri) + 1);
	memcpy(buf, fz_to_str_buf(uri), fz_to_str_len(uri));
	buf[fz_to_str_len(uri)] = 0;
	winopenuri(app, buf);
	fz_free(buf);
}
static fz_error
load_indexed(fz_colorspace **csp, pdf_xref *xref, fz_obj *array)
{
	fz_error error;
	fz_colorspace *cs;
	struct indexed *idx;
	fz_obj *baseobj = fz_array_get(array, 1);
	fz_obj *highobj = fz_array_get(array, 2);
	fz_obj *lookup = fz_array_get(array, 3);
	fz_colorspace *base;
	int i, n;

	error = pdf_load_colorspace(&base, xref, baseobj);
	if (error)
		return fz_rethrow(error, "cannot load base colorspace (%d %d R)", fz_to_num(baseobj), fz_to_gen(baseobj));

	idx = fz_malloc(sizeof(struct indexed));
	idx->base = base;
	idx->high = fz_to_int(highobj);
	idx->high = CLAMP(idx->high, 0, 255);
	n = base->n * (idx->high + 1);
	idx->lookup = fz_malloc(n);
	memset(idx->lookup, 0, n);

	cs = fz_new_colorspace("Indexed", 1);
	cs->to_rgb = indexed_to_rgb;
	cs->free_data = free_indexed;
	cs->data = idx;

	if (fz_is_string(lookup) && fz_to_str_len(lookup) == n)
	{
		unsigned char *buf = (unsigned char *) fz_to_str_buf(lookup);
		for (i = 0; i < n; i++)
			idx->lookup[i] = buf[i];
	}
	else if (fz_is_indirect(lookup))
	{
		fz_stream *file;

		error = pdf_open_stream(&file, xref, fz_to_num(lookup), fz_to_gen(lookup));
		if (error)
		{
			fz_drop_colorspace(cs);
			return fz_rethrow(error, "cannot open colorspace lookup table (%d 0 R)", fz_to_num(lookup));
		}

		i = fz_read(file, idx->lookup, n);
		if (i < 0)
		{
			fz_drop_colorspace(cs);
			return fz_throw("cannot read colorspace lookup table (%d 0 R)", fz_to_num(lookup));
		}

		fz_close(file);
	}
	else
	{
		fz_drop_colorspace(cs);
		return fz_throw("cannot parse colorspace lookup table");
	}

	*csp = cs;
	return fz_okay;
}
Beispiel #6
0
static fz_colorspace *
load_indexed(pdf_document *xref, fz_obj *array)
{
	struct indexed *idx = NULL;
	fz_context *ctx = xref->ctx;
	fz_obj *baseobj = fz_array_get(array, 1);
	fz_obj *highobj = fz_array_get(array, 2);
	fz_obj *lookup = fz_array_get(array, 3);
	fz_colorspace *base = NULL;
	fz_colorspace *cs = NULL;
	int i, n;

	fz_var(idx);
	fz_var(base);
	fz_var(cs);

	fz_try(ctx)
	{
		base = pdf_load_colorspace(xref, baseobj);
		/* "cannot load base colorspace (%d %d R)", fz_to_num(baseobj), fz_to_gen(baseobj) */

		idx = fz_malloc_struct(ctx, struct indexed);
		idx->lookup = NULL;
		idx->base = base;
		idx->high = fz_to_int(highobj);
		idx->high = CLAMP(idx->high, 0, 255);
		n = base->n * (idx->high + 1);
		idx->lookup = fz_malloc_array(ctx, 1, n);

		cs = fz_new_colorspace(ctx, "Indexed", 1);
		cs->to_rgb = indexed_to_rgb;
		cs->free_data = free_indexed;
		cs->data = idx;
		cs->size += sizeof(*idx) + n + (base ? base->size : 0);

		if (fz_is_string(lookup) && fz_to_str_len(lookup) == n)
		{
			unsigned char *buf = (unsigned char *) fz_to_str_buf(lookup);
			for (i = 0; i < n; i++)
				idx->lookup[i] = buf[i];
		}
		else if (fz_is_indirect(lookup))
		{
			fz_stream *file = NULL;

			fz_try(ctx)
			{
				file = pdf_open_stream(xref, fz_to_num(lookup), fz_to_gen(lookup));
			}
			fz_catch(ctx)
			{
				fz_throw(ctx, "cannot open colorspace lookup table (%d 0 R)", fz_to_num(lookup));
			}

			i = fz_read(file, idx->lookup, n);
			if (i < 0)
			{
				fz_close(file);
				fz_throw(ctx, "cannot read colorspace lookup table (%d 0 R)", fz_to_num(lookup));
			}

			fz_close(file);
		}
		else
		{
			fz_throw(ctx, "cannot parse colorspace lookup table");
		}
	}
Beispiel #7
0
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);
}