Exemplo n.º 1
0
/* SumatraPDF: partial support for file attachment icons */
static pdf_annot *
pdf_create_file_annot(pdf_xref *xref, fz_obj *obj)
{
	fz_buffer *content = fz_new_buffer(xref->ctx, 512);
	fz_rect rect = pdf_to_rect(xref->ctx, fz_dict_gets(xref->ctx, obj, "Rect"));
	char *icon_name = fz_to_name(xref->ctx, fz_dict_gets(xref->ctx, obj, "Name"));
	char *content_ap = ANNOT_FILE_ATTACHMENT_AP_PUSHPIN;
	float rgb[3];

	pdf_get_annot_color(xref->ctx, obj, rgb);

	if (!strcmp(icon_name, "Graph"))
		content_ap = ANNOT_FILE_ATTACHMENT_AP_GRAPH;
	else if (!strcmp(icon_name, "Paperclip"))
		content_ap = ANNOT_FILE_ATTACHMENT_AP_PAPERCLIP;
	else if (!strcmp(icon_name, "Tag"))
		content_ap = ANNOT_FILE_ATTACHMENT_AP_TAG;

	fz_buffer_printf(xref->ctx, content, "q %.4f 0 0 %.4f 0 0 cm ",
		(rect.x1 - rect.x0) / 24, (rect.y1 - rect.y0) / 24);
	fz_buffer_printf(xref->ctx, content, content_ap, 0.5, 0.5, 0.5);
	fz_buffer_printf(xref->ctx, content, " 1 0 0 1 0 1 cm ");
	fz_buffer_printf(xref->ctx, content, content_ap, rgb[0], rgb[1], rgb[2]);
	fz_buffer_printf(xref->ctx, content, " Q", content_ap);

	obj = pdf_clone_for_view_only(xref, obj);
	return pdf_create_annot(xref->ctx, rect, obj, content, NULL, 0);
}
Exemplo n.º 2
0
/* SumatraPDF: partial support for link borders */
static pdf_annot *
pdf_create_link_annot(pdf_xref *xref, fz_obj *obj)
{
	fz_obj *border, *dashes;
	fz_buffer *content;
	fz_rect rect;
	float rgb[3];
	int i;

	border = fz_dict_gets(xref->ctx, obj, "Border");
	if (fz_to_real(xref->ctx, fz_array_get(xref->ctx, border, 2)) <= 0)
		return NULL;

	pdf_get_annot_color(xref->ctx, obj, rgb);
	dashes = fz_array_get(xref->ctx, border, 3);
	rect = pdf_to_rect(xref->ctx, fz_dict_gets(xref->ctx, obj, "Rect"));

	obj = pdf_clone_for_view_only(xref, obj);

	// TODO: draw rounded rectangles if the first two /Border values are non-zero
	content = fz_new_buffer(xref->ctx, 128);
	fz_buffer_printf(xref->ctx, content, "q %.4f w [", fz_to_real(xref->ctx, fz_array_get(xref->ctx, border, 2)));
	for (i = 0; i < fz_array_len(xref->ctx, dashes); i++)
		fz_buffer_printf(xref->ctx, content, "%.4f ", fz_to_real(xref->ctx, fz_array_get(xref->ctx, dashes, i)));
	fz_buffer_printf(xref->ctx, content, "] 0 d %.4f %.4f %.4f RG 0 0 %.4f %.4f re S Q",
		rgb[0], rgb[1], rgb[2], rect.x1 - rect.x0, rect.y1 - rect.y0);

	return pdf_create_annot(xref->ctx, rect, obj, content, NULL, 0);
}
Exemplo n.º 3
0
/* SumatraPDF: synthesize appearance streams for a few more annotations */
static pdf_annot *
pdf_create_annot(fz_context *ctx, fz_rect rect, fz_obj *base_obj, fz_buffer *content, fz_obj *resources, int transparency)
{
	pdf_annot *annot;
	pdf_xobject *form;
	int rotate = fz_to_int(ctx, fz_dict_gets(ctx, fz_dict_gets(ctx, base_obj, "MK"), "R")); 

	form = fz_malloc(ctx, sizeof(pdf_xobject));
	memset(form, 0, sizeof(pdf_xobject));
	form->refs = 1;
	form->matrix = fz_rotate(rotate);
	form->bbox.x1 = (rotate % 180 == 0) ? rect.x1 - rect.x0 : rect.y1 - rect.y0;
	form->bbox.y1 = (rotate % 180 == 0) ? rect.y1 - rect.y0 : rect.x1 - rect.x0;
	form->transparency = transparency;
	form->isolated = !transparency;
	form->contents = content;
	form->resources = resources;

	annot = fz_malloc(ctx, sizeof(pdf_annot));
	annot->obj = base_obj;
	annot->rect = rect;
	annot->ap = form;
	annot->next = NULL;

	pdf_transform_annot(annot);

	return annot;
}
Exemplo n.º 4
0
static fz_error
pdf_read_ocg(pdf_xref *xref)
{
	fz_obj *obj, *ocg;
	int len, i;
	pdf_ocg_descriptor *desc;

	obj = fz_dict_gets(fz_dict_gets(xref->trailer, "Root"), "OCProperties");
	if (obj == NULL)
		return fz_okay;
	ocg = fz_dict_gets(obj, "OCGs");
	if (ocg == NULL || !fz_is_array(ocg))
		/* Not ever supposed to happen, but live with it. */
		return fz_okay;
	len = fz_array_len(ocg);
	desc = fz_malloc(sizeof(*desc));
	desc->len = len;
	desc->ocgs = fz_calloc(len, sizeof(*desc->ocgs));
	desc->intent = NULL;

	for (i=0; i < len; i++)
	{
		fz_obj *o = fz_array_get(ocg, i);
		desc->ocgs[i].num = fz_to_num(o);
		desc->ocgs[i].gen = fz_to_gen(o);
		desc->ocgs[i].state = 0;
	}
	xref->ocg = desc;

	return pdf_ocg_set_config(xref, 0);
}
Exemplo n.º 5
0
/*
 * Load uncompressed contents of a stream into buf.
 */
fz_error
pdf_load_stream(fz_buffer **bufp, pdf_xref *xref, int num, int gen)
{
	fz_error error;
	fz_stream *stm;
	fz_obj *dict, *obj;
	int i, len;

	error = pdf_open_stream(&stm, xref, num, gen);
	if (error)
		return fz_rethrow(error, "cannot open stream (%d %d R)", num, gen);

	error = pdf_load_object(&dict, xref, num, gen);
	if (error)
		return fz_rethrow(error, "cannot load stream dictionary (%d %d R)", num, gen);

	len = fz_to_int(fz_dict_gets(dict, "Length"));
	obj = fz_dict_gets(dict, "Filter");
	len = pdf_guess_filter_length(len, fz_to_name(obj));
	for (i = 0; i < fz_array_len(obj); i++)
		len = pdf_guess_filter_length(len, fz_to_name(fz_array_get(obj, i)));

	fz_drop_obj(dict);

	error = fz_read_all(bufp, stm, len);
	if (error)
	{
		fz_close(stm);
		return fz_rethrow(error, "cannot read raw stream (%d %d R)", num, gen);
	}

	fz_close(stm);
	return fz_okay;
}
Exemplo n.º 6
0
static pdf_annot *
pdf_create_highlight_annot(pdf_xref *xref, fz_obj *obj)
{
	fz_context *ctx = xref->ctx;
	fz_buffer *content = fz_new_buffer(ctx, 512);
	fz_rect rect = pdf_to_rect(ctx, fz_dict_gets(ctx, obj, "Rect"));
	fz_obj *quad_points = fz_dict_gets(ctx, obj, "QuadPoints");
	fz_obj *resources = pdf_dict_from_string(xref, ANNOT_HIGHLIGHT_AP_RESOURCES);
	fz_rect a, b;
	float rgb[3];
	float skew;
	int i;

	for (i = 0; i < fz_array_len(ctx, quad_points) / 8; i++)
	{
		pdf_get_quadrilaterals(ctx, quad_points, i, &a, &b);
		skew = 0.15 * fabs(a.y0 - b.y0);
		b.x0 -= skew; b.x1 += skew;
		rect = fz_union_rect(rect, fz_union_rect(a, b));
	}
	pdf_get_annot_color(ctx, obj, rgb);

	fz_buffer_printf(ctx, content, "q /GS gs %.4f %.4f %.4f rg 1 0 0 1 -%.4f -%.4f cm ",
		rgb[0], rgb[1], rgb[2], rect.x0, rect.y0);
	for (i = 0; i < fz_array_len(ctx, quad_points) / 8; i++)
	{
		pdf_get_quadrilaterals(ctx, quad_points, i, &a, &b);
		skew = 0.15 * fabs(a.y0 - b.y0);
		fz_buffer_printf(ctx, content, "%.4f %.4f m %.4f %.4f l %.4f %.4f l %.4f %.4f l h ",
			a.x0, a.y0, b.x1 + skew, b.y1, a.x1, a.y1, b.x0 - skew, b.y0);
	}
	fz_buffer_printf(ctx, content, "f Q");

	return pdf_create_annot(ctx, rect, fz_keep_obj(obj), content, resources, 1);
}
Exemplo n.º 7
0
static void
pdf_load_radial_shading(fz_shade *shade, pdf_xref *xref, fz_obj *dict, int funcs, pdf_function **func)
{
	fz_obj *obj;
	float d0, d1;
	int e0, e1;
	float x0, y0, r0, x1, y1, r1;
	struct vertex p1, p2;
	fz_context *ctx = xref->ctx;

	obj = fz_dict_gets(ctx, dict, "Coords");
	x0 = fz_to_real(ctx, fz_array_get(ctx, obj, 0));
	y0 = fz_to_real(ctx, fz_array_get(ctx, obj, 1));
	r0 = fz_to_real(ctx, fz_array_get(ctx, obj, 2));
	x1 = fz_to_real(ctx, fz_array_get(ctx, obj, 3));
	y1 = fz_to_real(ctx, fz_array_get(ctx, obj, 4));
	r1 = fz_to_real(ctx, fz_array_get(ctx, obj, 5));

	d0 = 0;
	d1 = 1;
	obj = fz_dict_gets(ctx, dict, "Domain");
	if (fz_array_len(ctx, obj) == 2)
	{
		d0 = fz_to_real(ctx, fz_array_get(ctx, obj, 0));
		d1 = fz_to_real(ctx, fz_array_get(ctx, obj, 1));
	}

	e0 = e1 = 0;
	obj = fz_dict_gets(ctx, dict, "Extend");
	if (fz_array_len(ctx, obj) == 2)
	{
		e0 = fz_to_bool(ctx, fz_array_get(ctx, obj, 0));
		e1 = fz_to_bool(ctx, fz_array_get(ctx, obj, 1));
	}

	pdf_sample_shade_function(ctx, shade, funcs, func, d0, d1);

	shade->type = FZ_RADIAL;

	shade->extend[0] = e0;
	shade->extend[1] = e1;

	p1.x = x0;
	p1.y = y0;
	p1.c[0] = r0;
	pdf_add_vertex(ctx, shade, &p1);

	p2.x = x1;
	p2.y = y1;
	p2.c[0] = r1;
	pdf_add_vertex(ctx, shade, &p2);
}
Exemplo n.º 8
0
/* cf. http://bugs.ghostscript.com/show_bug.cgi?id=692078 */
static fz_obj *
pdf_dict_get_inheritable(pdf_xref *xref, fz_obj *obj, char *key)
{
	fz_context *ctx = xref->ctx;
	while (obj)
	{
		fz_obj *val = fz_dict_gets(ctx, obj, key);
		if (val)
			return val;
		obj = fz_dict_gets(ctx, obj, "Parent");
	}
	return fz_dict_gets(ctx, fz_dict_gets(ctx, fz_dict_gets(ctx, xref->trailer, "Root"), "AcroForm"), key);
}
Exemplo n.º 9
0
fz_outline *
pdf_load_outline(pdf_document *xref)
{
	fz_obj *root, *obj, *first;

	root = fz_dict_gets(xref->trailer, "Root");
	obj = fz_dict_gets(root, "Outlines");
	first = fz_dict_gets(obj, "First");
	if (first)
		return pdf_load_outline_imp(xref, first);

	return NULL;
}
Exemplo n.º 10
0
static void
pdf_load_mesh_params(pdf_xref *xref, fz_obj *dict, struct mesh_params *p)
{
	fz_obj *obj;
	int i, n;
	fz_context *ctx = xref->ctx;

	p->x0 = p->y0 = 0;
	p->x1 = p->y1 = 1;
	for (i = 0; i < FZ_MAX_COLORS; i++)
	{
		p->c0[i] = 0;
		p->c1[i] = 1;
	}

	p->vprow = fz_to_int(ctx, fz_dict_gets(ctx, dict, "VerticesPerRow"));
	p->bpflag = fz_to_int(ctx, fz_dict_gets(ctx, dict, "BitsPerFlag"));
	p->bpcoord = fz_to_int(ctx, fz_dict_gets(ctx, dict, "BitsPerCoordinate"));
	p->bpcomp = fz_to_int(ctx, fz_dict_gets(ctx, dict, "BitsPerComponent"));

	obj = fz_dict_gets(ctx, dict, "Decode");
	if (fz_array_len(ctx, obj) >= 6)
	{
		n = (fz_array_len(ctx, obj) - 4) / 2;
		p->x0 = fz_to_real(ctx, fz_array_get(ctx, obj, 0));
		p->x1 = fz_to_real(ctx, fz_array_get(ctx, obj, 1));
		p->y0 = fz_to_real(ctx, fz_array_get(ctx, obj, 2));
		p->y1 = fz_to_real(ctx, fz_array_get(ctx, obj, 3));

		for (i = 0; i < n; i++)
		{
			p->c0[i] = fz_to_real(ctx, fz_array_get(ctx, obj, 4 + i * 2));
			p->c1[i] = fz_to_real(ctx, fz_array_get(ctx, obj, 5 + i * 2));
		}
	}

	if (p->vprow < 2)
		p->vprow = 2;

	if (p->bpflag != 2 && p->bpflag != 4 && p->bpflag != 8)
		p->bpflag = 8;

	if (p->bpcoord != 1 && p->bpcoord != 2 && p->bpcoord != 4 &&
		p->bpcoord != 8 && p->bpcoord != 12 && p->bpcoord != 16 &&
		p->bpcoord != 24 && p->bpcoord != 32)
		p->bpcoord = 8;

	if (p->bpcomp != 1 && p->bpcomp != 2 && p->bpcomp != 4 &&
		p->bpcomp != 8 && p->bpcomp != 12 && p->bpcomp != 16)
		p->bpcomp = 8;
}
Exemplo n.º 11
0
static const char* _pdf_doc_title(struct _pdf_doc *self)
{
    if (self->xref) {
        fz_obj *info, *obj;
        info = fz_dict_gets(self->xref->trailer, "Info");
        if (info) {
            obj = fz_dict_gets(info, "Title");
            if (obj)
                return pdf_to_utf8(obj);
        }
    }

    return NULL;
}
Exemplo n.º 12
0
fz_outline *
pdf_load_outline(pdf_xref *xref)
{
    fz_obj *root, *obj, *first;
    fz_context *ctx = xref->ctx;

    root = fz_dict_gets(ctx, xref->trailer, "Root");
    obj = fz_dict_gets(ctx, root, "Outlines");
    first = fz_dict_gets(ctx, obj, "First");
    if (first)
        return pdf_load_outline_imp(xref, first);

    return NULL;
}
Exemplo n.º 13
0
static void
pdf_load_axial_shading(fz_shade *shade, pdf_xref *xref, fz_obj *dict, int funcs, pdf_function **func)
{
	fz_obj *obj;
	float d0, d1;
	int e0, e1;
	float x0, y0, x1, y1;
	struct vertex p1, p2;

	obj = fz_dict_gets(dict, "Coords");
	x0 = fz_to_real(fz_array_get(obj, 0));
	y0 = fz_to_real(fz_array_get(obj, 1));
	x1 = fz_to_real(fz_array_get(obj, 2));
	y1 = fz_to_real(fz_array_get(obj, 3));

	d0 = 0;
	d1 = 1;
	obj = fz_dict_gets(dict, "Domain");
	if (fz_array_len(obj) == 2)
	{
		d0 = fz_to_real(fz_array_get(obj, 0));
		d1 = fz_to_real(fz_array_get(obj, 1));
	}

	e0 = e1 = 0;
	obj = fz_dict_gets(dict, "Extend");
	if (fz_array_len(obj) == 2)
	{
		e0 = fz_to_bool(fz_array_get(obj, 0));
		e1 = fz_to_bool(fz_array_get(obj, 1));
	}

	pdf_sample_shade_function(shade, funcs, func, d0, d1);

	shade->type = FZ_LINEAR;

	shade->extend[0] = e0;
	shade->extend[1] = e1;

	p1.x = x0;
	p1.y = y0;
	p1.c[0] = 0;
	pdf_add_vertex(shade, &p1);

	p2.x = x1;
	p2.y = y1;
	p2.c[0] = 0;
	pdf_add_vertex(shade, &p2);
}
Exemplo n.º 14
0
static fz_obj *
pdf_get_ap_stream(pdf_xref *xref, fz_obj *obj)
{
	fz_obj *ap = fz_dict_gets(xref->ctx, obj, "AP");
	if (!fz_is_dict(xref->ctx, ap))
		return NULL;

	ap = fz_dict_gets(xref->ctx, ap, "N");
	if (!pdf_is_stream(xref, fz_to_num(ap), fz_to_gen(ap)))
		ap = fz_dict_get(xref->ctx, ap, fz_dict_gets(xref->ctx, obj, "AS"));
	if (!pdf_is_stream(xref, fz_to_num(ap), fz_to_gen(ap)))
		return NULL;

	return ap;
}
Exemplo n.º 15
0
/*
 * Load raw (compressed but decrypted) contents of a stream into buf.
 */
fz_error
pdf_load_raw_stream(fz_buffer **bufp, pdf_xref *xref, int num, int gen)
{
	fz_error error;
	fz_stream *stm;
	fz_obj *dict;
	int len;

	error = pdf_load_object(&dict, xref, num, gen);
	if (error)
		return fz_rethrow(error, "cannot load stream dictionary (%d %d R)", num, gen);

	len = fz_to_int(fz_dict_gets(dict, "Length"));

	fz_drop_obj(dict);

	error = pdf_open_raw_stream(&stm, xref, num, gen);
	if (error)
		return fz_rethrow(error, "cannot open raw stream (%d %d R)", num, gen);

	error = fz_read_all(bufp, stm, len);
	if (error)
	{
		fz_close(stm);
		return fz_rethrow(error, "cannot read raw stream (%d %d R)", num, gen);
	}

	fz_close(stm);
	return fz_okay;
}
Exemplo n.º 16
0
static fz_obj *
resolve_dest(pdf_xref *xref, fz_obj *dest)
{
	if (fz_is_name(xref->ctx, dest) || fz_is_string(xref->ctx, dest))
	{
		dest = pdf_lookup_dest(xref, dest);
		return resolve_dest(xref, dest);
	}

	else if (fz_is_array(xref->ctx, dest))
	{
		return dest;
	}

	else if (fz_is_dict(xref->ctx, dest))
	{
		dest = fz_dict_gets(xref->ctx, dest, "D");
		return resolve_dest(xref, dest);
	}

	else if (fz_is_indirect(dest))
		return dest;

	return NULL;
}
Exemplo n.º 17
0
static void sweepref(fz_obj *obj)
{
	int num = fz_to_num(obj);
	int gen = fz_to_gen(obj);

	if (num < 0 || num >= xref->len)
		return;
	if (uselist[num])
		return;

	uselist[num] = 1;

	/* Bake in /Length in stream objects */
	fz_try(ctx)
	{
		if (pdf_is_stream(xref, num, gen))
		{
			fz_obj *len = fz_dict_gets(obj, "Length");
			if (fz_is_indirect(len))
			{
				uselist[fz_to_num(len)] = 0;
				len = fz_resolve_indirect(len);
				fz_dict_puts(obj, "Length", len);
			}
		}
	}
	fz_catch(ctx)
	{
		/* Leave broken */
	}

	sweepobj(fz_resolve_indirect(obj));
}
Exemplo n.º 18
0
static void
pdf_get_annot_color(fz_context *ctx, fz_obj *obj, float rgb[3])
{
	int k;
	obj = fz_dict_gets(ctx, obj, "C");
	for (k = 0; k < 3; k++)
		rgb[k] = fz_to_real(ctx, fz_array_get(ctx, obj, k));
}
Exemplo n.º 19
0
static void addhexfilter(fz_obj *dict)
{
	fz_obj *f, *dp, *newf, *newdp;
	fz_obj *ahx, *nullobj;

	ahx = fz_new_name(ctx, "ASCIIHexDecode");
	nullobj = fz_new_null(ctx);
	newf = newdp = NULL;

	f = fz_dict_gets(dict, "Filter");
	dp = fz_dict_gets(dict, "DecodeParms");

	if (fz_is_name(f))
	{
		newf = fz_new_array(ctx, 2);
		fz_array_push(newf, ahx);
		fz_array_push(newf, f);
		f = newf;
		if (fz_is_dict(dp))
		{
			newdp = fz_new_array(ctx, 2);
			fz_array_push(newdp, nullobj);
			fz_array_push(newdp, dp);
			dp = newdp;
		}
	}
	else if (fz_is_array(f))
	{
		fz_array_insert(f, ahx);
		if (fz_is_array(dp))
			fz_array_insert(dp, nullobj);
	}
	else
		f = ahx;

	fz_dict_puts(dict, "Filter", f);
	if (dp)
		fz_dict_puts(dict, "DecodeParms", dp);

	fz_drop_obj(ahx);
	fz_drop_obj(nullobj);
	if (newf)
		fz_drop_obj(newf);
	if (newdp)
		fz_drop_obj(newdp);
}
Exemplo n.º 20
0
static void writexref(void)
{
	fz_obj *trailer;
	fz_obj *obj;
	int startxref;
	int num;

	startxref = ftell(out);

	fprintf(out, "xref\n0 %d\n", xref->len);
	for (num = 0; num < xref->len; num++)
	{
		if (uselist[num])
			fprintf(out, "%010d %05d n \n", ofslist[num], genlist[num]);
		else
			fprintf(out, "%010d %05d f \n", ofslist[num], genlist[num]);
	}
	fprintf(out, "\n");

	trailer = fz_new_dict(ctx, 5);

	obj = fz_new_int(ctx, xref->len);
	fz_dict_puts(trailer, "Size", obj);
	fz_drop_obj(obj);

	obj = fz_dict_gets(xref->trailer, "Info");
	if (obj)
		fz_dict_puts(trailer, "Info", obj);

	obj = fz_dict_gets(xref->trailer, "Root");
	if (obj)
		fz_dict_puts(trailer, "Root", obj);

	obj = fz_dict_gets(xref->trailer, "ID");
	if (obj)
		fz_dict_puts(trailer, "ID", obj);

	fprintf(out, "trailer\n");
	fz_fprint_obj(out, trailer, doexpand == 0);
	fprintf(out, "\n");

	fz_drop_obj(trailer);

	fprintf(out, "startxref\n%d\n%%%%EOF\n", startxref);
}
Exemplo n.º 21
0
/* SumatraPDF: partial support for text icons */
static pdf_annot *
pdf_create_text_annot(pdf_xref *xref, fz_obj *obj)
{
	fz_context *ctx = xref->ctx;
	fz_buffer *content = fz_new_buffer(ctx, 512);
	fz_rect rect = pdf_to_rect(ctx, fz_dict_gets(ctx, obj, "Rect"));
	char *icon_name = fz_to_name(ctx, fz_dict_gets(ctx, obj, "Name"));
	char *content_ap = ANNOT_TEXT_AP_NOTE;
	float rgb[3];

	rect.x1 = rect.x0 + 24;
	rect.y0 = rect.y1 - 24;
	pdf_get_annot_color(ctx, obj, rgb);

	if (!strcmp(icon_name, "Comment"))
		content_ap = ANNOT_TEXT_AP_COMMENT;
	else if (!strcmp(icon_name, "Key"))
		content_ap = ANNOT_TEXT_AP_KEY;
	else if (!strcmp(icon_name, "Help"))
		content_ap = ANNOT_TEXT_AP_HELP;
	else if (!strcmp(icon_name, "Paragraph"))
		content_ap = ANNOT_TEXT_AP_PARAGRAPH;
	else if (!strcmp(icon_name, "NewParagraph"))
		content_ap = ANNOT_TEXT_AP_NEW_PARAGRAPH;
	else if (!strcmp(icon_name, "Insert"))
		content_ap = ANNOT_TEXT_AP_INSERT;
	else if (!strcmp(icon_name, "Cross"))
		content_ap = ANNOT_TEXT_AP_CROSS;
	else if (!strcmp(icon_name, "Circle"))
		content_ap = ANNOT_TEXT_AP_CIRCLE;

	// TODO: make icons semi-transparent (cf. pdf_create_highlight_annot)?
	fz_buffer_printf(ctx, content, "q ");
	fz_buffer_printf(ctx, content, content_ap, 0.5, 0.5, 0.5);
	fz_buffer_printf(ctx, content, " 1 0 0 1 0 1 cm ");
	fz_buffer_printf(ctx, content, content_ap, rgb[0], rgb[1], rgb[2]);
	fz_buffer_printf(ctx, content, " Q", content_ap);

	obj = pdf_clone_for_view_only(xref, obj);
	return pdf_create_annot(ctx, rect, obj, content, NULL, 0);
}
Exemplo n.º 22
0
static fz_outline *
pdf_load_outline_imp(pdf_document *xref, fz_obj *dict)
{
	fz_context *ctx = xref->ctx;
	fz_outline *node, **prev, *first;
	fz_obj *obj;
	fz_obj *odict = dict;

	fz_var(dict);

	fz_try(ctx)
	{
		first = NULL;
		prev = &first;
		while (dict && fz_is_dict(dict))
		{
			if (fz_dict_mark(dict))
				break;
			node = fz_malloc_struct(ctx, fz_outline);
			node->title = NULL;
			node->dest.kind = FZ_LINK_NONE;
			node->down = NULL;
			node->next = NULL;
			*prev = node;
			prev = &node->next;

			obj = fz_dict_gets(dict, "Title");
			if (obj)
				node->title = pdf_to_utf8(ctx, obj);

			if ((obj = fz_dict_gets(dict, "Dest")))
				node->dest = pdf_parse_link_dest(xref, obj);
			else if ((obj = fz_dict_gets(dict, "A")))
				node->dest = pdf_parse_action(xref, obj);

			obj = fz_dict_gets(dict, "First");
			if (obj)
				node->down = pdf_load_outline_imp(xref, obj);

			dict = fz_dict_gets(dict, "Next");
		}
	}
	fz_catch(ctx)
	{
		for (dict = odict; dict && fz_dict_marked(dict); dict = fz_dict_gets(dict, "Next"))
			fz_dict_unmark(dict);
		fz_rethrow(ctx);
	}

	for (dict = odict; dict && fz_dict_marked(dict); dict = fz_dict_gets(dict, "Next"))
		fz_dict_unmark(dict);

	return first;
}
Exemplo n.º 23
0
static fz_error
pdf_read_xref_sections(pdf_xref *xref, int ofs, char *buf, int cap)
{
	fz_error error;
	fz_obj *trailer;
	fz_obj *prev;
	fz_obj *xrefstm;

	error = pdf_read_xref(&trailer, xref, ofs, buf, cap);
	if (error)
		return fz_rethrow(error, "cannot read xref section");

	/* FIXME: do we overwrite free entries properly? */
	xrefstm = fz_dict_gets(trailer, "XRefStm");
	if (xrefstm)
	{
		error = pdf_read_xref_sections(xref, fz_to_int(xrefstm), buf, cap);
		if (error)
		{
			fz_drop_obj(trailer);
			return fz_rethrow(error, "cannot read /XRefStm xref section");
		}
	}

	prev = fz_dict_gets(trailer, "Prev");
	if (prev)
	{
		error = pdf_read_xref_sections(xref, fz_to_int(prev), buf, cap);
		if (error)
		{
			fz_drop_obj(trailer);
			return fz_rethrow(error, "cannot read /Prev xref section");
		}
	}

	fz_drop_obj(trailer);
	return fz_okay;
}
Exemplo n.º 24
0
int
pdf_is_jpx_image(fz_obj *dict)
{
	fz_obj *filter;
	int i;

	filter = fz_dict_gets(dict, "Filter");
	if (!strcmp(fz_to_name(filter), "JPXDecode"))
		return 1;
	for (i = 0; i < fz_array_len(filter); i++)
		if (!strcmp(fz_to_name(fz_array_get(filter, i)), "JPXDecode"))
			return 1;
	return 0;
}
Exemplo n.º 25
0
static fz_error
pdf_load_jpx_image(fz_pixmap **imgp, pdf_xref *xref, fz_obj *dict)
{
	fz_error error;
	fz_buffer *buf;
	fz_colorspace *colorspace;
	fz_pixmap *img;
	fz_obj *obj;

	colorspace = NULL;

	error = pdf_load_stream(&buf, xref, fz_to_num(dict), fz_to_gen(dict));
	if (error)
		return fz_rethrow(error, "cannot load jpx image data");

	obj = fz_dict_gets(dict, "ColorSpace");
	if (obj)
	{
		error = pdf_load_colorspace(&colorspace, xref, obj);
		if (error)
			fz_catch(error, "cannot load image colorspace");
	}

	error = fz_load_jpx_image(&img, buf->data, buf->len, colorspace);
	if (error)
	{
		if (colorspace)
			fz_drop_colorspace(colorspace);
		fz_drop_buffer(buf);
		return fz_rethrow(error, "cannot load jpx image");
	}

	if (colorspace)
		fz_drop_colorspace(colorspace);
	fz_drop_buffer(buf);

	obj = fz_dict_getsa(dict, "SMask", "Mask");
	if (fz_is_dict(obj))
	{
		error = pdf_load_image_imp(&img->mask, xref, NULL, obj, NULL, 1);
		if (error)
		{
			fz_drop_pixmap(img);
			return fz_rethrow(error, "cannot load image mask/softmask");
		}
	}

	*imgp = img;
	return fz_okay;
}
Exemplo n.º 26
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);
}
Exemplo n.º 27
0
static pdf_annot *
pdf_create_markup_annot(pdf_xref *xref, fz_obj *obj, char *type)
{
	fz_context *ctx = xref->ctx;
	fz_buffer *content = fz_new_buffer(ctx, 512);
	fz_rect rect = pdf_to_rect(ctx, fz_dict_gets(ctx, obj, "Rect"));
	fz_obj *quad_points = fz_dict_gets(ctx, obj, "QuadPoints");
	fz_rect a, b;
	float rgb[3];
	int i;

	for (i = 0; i < fz_array_len(ctx, quad_points) / 8; i++)
	{
		pdf_get_quadrilaterals(ctx, quad_points, i, &a, &b);
		b.y0 -= 0.25; a.y1 += 0.25;
		rect = fz_union_rect(rect, fz_union_rect(a, b));
	}
	pdf_get_annot_color(ctx, obj, rgb);

	fz_buffer_printf(ctx, content, "q %.4f %.4f %.4f RG 1 0 0 1 -%.4f -%.4f cm 0.5 w ",
		rgb[0], rgb[1], rgb[2], rect.x0, rect.y0);
	if (!strcmp(type, "Squiggly"))
		fz_buffer_printf(ctx, content, "[1 1] d ");
	for (i = 0; i < fz_array_len(ctx, quad_points) / 8; i++)
	{
		pdf_get_quadrilaterals(ctx, quad_points, i, &a, &b);
		if (!strcmp(type, "StrikeOut"))
			fz_buffer_printf(ctx, content, "%.4f %.4f m %.4f %.4f l ",
				(a.x0 + b.x0) / 2, (a.y0 + b.y0) / 2, (a.x1 + b.x1) / 2, (a.y1 + b.y1) / 2);
		else
			fz_buffer_printf(ctx, content, "%.4f %.4f m %.4f %.4f l ", b.x0, b.y0, a.x1, a.y1);
	}
	fz_buffer_printf(ctx, content, "S Q");

	return pdf_create_annot(ctx, rect, fz_keep_obj(obj), content, NULL, 0);
}
Exemplo n.º 28
0
static fz_error
load_icc_based(fz_colorspace **csp, pdf_xref *xref, fz_obj *dict)
{
	int n;

	n = fz_to_int(fz_dict_gets(dict, "N"));

	switch (n)
	{
	case 1: *csp = fz_device_gray; return fz_okay;
	case 3: *csp = fz_device_rgb; return fz_okay;
	case 4: *csp = fz_device_cmyk; return fz_okay;
	}

	return fz_throw("syntaxerror: ICCBased must have 1, 3 or 4 components");
}
Exemplo n.º 29
0
static fz_colorspace *
load_icc_based(pdf_document *xref, fz_obj *dict)
{
	int n;

	n = fz_to_int(fz_dict_gets(dict, "N"));

	switch (n)
	{
	case 1: return fz_device_gray;
	case 3: return fz_device_rgb;
	case 4: return fz_device_cmyk;
	}

	fz_throw(xref->ctx, "syntaxerror: ICCBased must have 1, 3 or 4 components");
	return NULL; /* Stupid MSVC */
}
Exemplo n.º 30
0
static fz_error
pdf_load_xref(pdf_xref *xref, char *buf, int bufsize)
{
	fz_error error;
	fz_obj *size;
	int i;

	error = pdf_load_version(xref);
	if (error)
		return fz_rethrow(error, "cannot read version marker");

	error = pdf_read_start_xref(xref);
	if (error)
		return fz_rethrow(error, "cannot read startxref");

	error = pdf_read_trailer(xref, buf, bufsize);
	if (error)
		return fz_rethrow(error, "cannot read trailer");

	size = fz_dict_gets(xref->trailer, "Size");
	if (!size)
		return fz_throw("trailer missing Size entry");

	pdf_resize_xref(xref, fz_to_int(size));

	error = pdf_read_xref_sections(xref, xref->startxref, buf, bufsize);
	if (error)
		return fz_rethrow(error, "cannot read xref");

	/* broken pdfs where first object is not free */
	if (xref->table[0].type != 'f')
		return fz_throw("first object in xref is not free");

	/* broken pdfs where object offsets are out of range */
	for (i = 0; i < xref->len; i++)
	{
		if (xref->table[i].type == 'n')
			if (xref->table[i].ofs <= 0 || xref->table[i].ofs >= xref->file_size)
				return fz_throw("object offset out of range: %d (%d 0 R)", xref->table[i].ofs, i);
		if (xref->table[i].type == 'o')
			if (xref->table[i].ofs <= 0 || xref->table[i].ofs >= xref->len || xref->table[xref->table[i].ofs].type != 'n')
				return fz_throw("invalid reference to an objstm that does not exist: %d (%d 0 R)", xref->table[i].ofs, i);
	}

	return fz_okay;
}