void
pdf_annot_quad_point(fz_context *ctx, pdf_annot *annot, int idx, float v[8])
{
	pdf_obj *quad_points;
	pdf_obj *quad_point;
	fz_matrix page_ctm;
	int i;

	check_allowed_subtypes(ctx, annot, PDF_NAME_QuadPoints, quad_point_subtypes);

	quad_points = pdf_dict_get(ctx, annot->obj, PDF_NAME_QuadPoints);
	quad_point = pdf_array_get(ctx, quad_points, idx);

	pdf_page_transform(ctx, annot->page, NULL, &page_ctm);

	for (i = 0; i < 8; i += 2)
	{
		fz_point point;
		point.x = pdf_to_real(ctx, pdf_array_get(ctx, quad_point, i+0));
		point.y = pdf_to_real(ctx, pdf_array_get(ctx, quad_point, i+1));
		fz_transform_point(&point, &page_ctm);
		v[i+0] = point.x;
		v[i+1] = point.y;
	}
}
Example #2
0
static void
intersect_box(fz_context *ctx, pdf_document *doc, pdf_obj *page, pdf_obj *box_name, const fz_rect *mb)
{
	pdf_obj *box = pdf_dict_get(ctx, page, box_name);
	pdf_obj *newbox;
	fz_rect old_rect;

	if (box == NULL)
		return;

	old_rect.x0 = pdf_to_real(ctx, pdf_array_get(ctx, box, 0));
	old_rect.y0 = pdf_to_real(ctx, pdf_array_get(ctx, box, 1));
	old_rect.x1 = pdf_to_real(ctx, pdf_array_get(ctx, box, 2));
	old_rect.y1 = pdf_to_real(ctx, pdf_array_get(ctx, box, 3));

	if (old_rect.x0 < mb->x0)
		old_rect.x0 = mb->x0;
	if (old_rect.y0 < mb->y0)
		old_rect.y0 = mb->y0;
	if (old_rect.x1 > mb->x1)
		old_rect.x1 = mb->x1;
	if (old_rect.y1 > mb->y1)
		old_rect.y1 = mb->y1;

	newbox = pdf_new_array(ctx, doc, 4);
	pdf_array_push(ctx, newbox, pdf_new_real(ctx, doc, old_rect.x0));
	pdf_array_push(ctx, newbox, pdf_new_real(ctx, doc, old_rect.y0));
	pdf_array_push(ctx, newbox, pdf_new_real(ctx, doc, old_rect.x1));
	pdf_array_push(ctx, newbox, pdf_new_real(ctx, doc, old_rect.y1));
	pdf_dict_put(ctx, page, box_name, newbox);
}
void
pdf_annot_ink_list_stroke_vertex(fz_context *ctx, pdf_annot *annot, int i, int k, float v[2])
{
	pdf_obj *ink_list;
	pdf_obj *stroke;
	fz_matrix page_ctm;
	fz_point point = { 0, 0 };

	check_allowed_subtypes(ctx, annot, PDF_NAME_InkList, ink_list_subtypes);

	ink_list = pdf_dict_get(ctx, annot->obj, PDF_NAME_InkList);
	stroke = pdf_array_get(ctx, ink_list, i);

	if (v)
	{
		pdf_page_transform(ctx, annot->page, NULL, &page_ctm);

		point.x = pdf_to_real(ctx, pdf_array_get(ctx, stroke, k * 2 + 0));
		point.y = pdf_to_real(ctx, pdf_array_get(ctx, stroke, k * 2 + 1));
		fz_transform_point(&point, &page_ctm);

		v[0] = point.x;
		v[1] = point.y;
	}
}
fz_rect *
pdf_to_rect(fz_context *ctx, pdf_obj *array, fz_rect *r)
{
    float a = pdf_to_real(pdf_array_get(array, 0));
    float b = pdf_to_real(pdf_array_get(array, 1));
    float c = pdf_to_real(pdf_array_get(array, 2));
    float d = pdf_to_real(pdf_array_get(array, 3));
    r->x0 = fz_min(a, c);
    r->y0 = fz_min(b, d);
    r->x1 = fz_max(a, c);
    r->y1 = fz_max(b, d);
    return r;
}
Example #5
0
static void
pdf_annot_color_imp(fz_context *ctx, pdf_annot *annot, pdf_obj *key, int *n, float color[4])
{
	pdf_obj *obj = pdf_dict_get(ctx, annot->obj, key);
	*n = 0;
	if (pdf_is_array(ctx, obj))
	{
		switch (pdf_array_len(ctx, obj))
		{
		case 1:
			*n = 1;
			color[0] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 0));
			break;
		case 3:
			*n = 3;
			color[0] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 0));
			color[1] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 1));
			color[2] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 2));
			break;
		case 4:
			*n = 4;
			color[0] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 0));
			color[1] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 1));
			color[2] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 2));
			color[3] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 3));
			break;
		}
	}
}
Example #6
0
fz_rect
pdf_to_rect(fz_context *ctx, pdf_obj *array)
{
    fz_rect r;
    float a = pdf_to_real(pdf_array_get(array, 0));
    float b = pdf_to_real(pdf_array_get(array, 1));
    float c = pdf_to_real(pdf_array_get(array, 2));
    float d = pdf_to_real(pdf_array_get(array, 3));
    r.x0 = MIN(a, c);
    r.y0 = MIN(b, d);
    r.x1 = MAX(a, c);
    r.y1 = MAX(b, d);
    return r;
}
Example #7
0
static void
pdf_load_function_based_shading(fz_shade *shade, pdf_document *xref, pdf_obj *dict, pdf_function *func)
{
	pdf_obj *obj;
	float x0, y0, x1, y1;
	float fv[2];
	fz_matrix matrix;
	int xx, yy;
	fz_context *ctx = xref->ctx;
	float *p;

	x0 = y0 = 0;
	x1 = y1 = 1;
	obj = pdf_dict_gets(dict, "Domain");
	if (obj)
	{
		x0 = pdf_to_real(pdf_array_get(obj, 0));
		x1 = pdf_to_real(pdf_array_get(obj, 1));
		y0 = pdf_to_real(pdf_array_get(obj, 2));
		y1 = pdf_to_real(pdf_array_get(obj, 3));
	}

	obj = pdf_dict_gets(dict, "Matrix");
	if (obj)
		pdf_to_matrix(ctx, obj, &matrix);
	else
		matrix = fz_identity;
	shade->u.f.matrix = matrix;
	shade->u.f.xdivs = FUNSEGS;
	shade->u.f.ydivs = FUNSEGS;
	shade->u.f.fn_vals = fz_malloc(ctx, (FUNSEGS+1)*(FUNSEGS+1)*shade->colorspace->n*sizeof(float));
	shade->u.f.domain[0][0] = x0;
	shade->u.f.domain[0][1] = y0;
	shade->u.f.domain[1][0] = x1;
	shade->u.f.domain[1][1] = y1;

	p = shade->u.f.fn_vals;
	for (yy = 0; yy <= FUNSEGS; yy++)
	{
		fv[1] = y0 + (y1 - y0) * yy / FUNSEGS;

		for (xx = 0; xx <= FUNSEGS; xx++)
		{
			fv[0] = x0 + (x1 - x0) * xx / FUNSEGS;

			pdf_eval_function(ctx, func, fv, 2, p, shade->colorspace->n);
			p += shade->colorspace->n;
		}
	}
}
Example #8
0
pdf_pattern *
pdf_load_pattern(fz_context *ctx, pdf_document *doc, pdf_obj *dict)
{
	pdf_pattern *pat;
	pdf_obj *obj;

	if ((pat = pdf_find_item(ctx, pdf_drop_pattern_imp, dict)) != NULL)
	{
		return pat;
	}

	pat = fz_malloc_struct(ctx, pdf_pattern);
	FZ_INIT_STORABLE(pat, 1, pdf_drop_pattern_imp);
	pat->document = doc;
	pat->resources = NULL;
	pat->contents = NULL;

	fz_try(ctx)
	{
		/* Store pattern now, to avoid possible recursion if objects refer back to this one */
		pdf_store_item(ctx, dict, pat, pdf_pattern_size(pat));

		pat->ismask = pdf_to_int(ctx, pdf_dict_get(ctx, dict, PDF_NAME_PaintType)) == 2;
		pat->xstep = pdf_to_real(ctx, pdf_dict_get(ctx, dict, PDF_NAME_XStep));
		pat->ystep = pdf_to_real(ctx, pdf_dict_get(ctx, dict, PDF_NAME_YStep));

		obj = pdf_dict_gets(ctx, dict, "BBox");
		pdf_to_rect(ctx, obj, &pat->bbox);

		obj = pdf_dict_gets(ctx, dict, "Matrix");
		if (obj)
			pdf_to_matrix(ctx, obj, &pat->matrix);
		else
			pat->matrix = fz_identity;

		pat->resources = pdf_dict_get(ctx, dict, PDF_NAME_Resources);
		if (pat->resources)
			pdf_keep_obj(ctx, pat->resources);

		pat->contents = pdf_keep_obj(ctx, dict);
	}
	fz_catch(ctx)
	{
		pdf_remove_item(ctx, pdf_drop_pattern_imp, dict);
		pdf_drop_pattern(ctx, pat);
		fz_rethrow_message(ctx, "cannot load pattern (%d %d R)", pdf_to_num(ctx, dict), pdf_to_gen(ctx, dict));
	}
	return pat;
}
Example #9
0
pdf_pattern *
pdf_load_pattern(pdf_document *xref, pdf_obj *dict)
{
	pdf_pattern *pat;
	pdf_obj *obj;
	fz_context *ctx = xref->ctx;

	if ((pat = pdf_find_item(ctx, pdf_free_pattern_imp, dict)))
	{
		return pat;
	}

	pat = fz_malloc_struct(ctx, pdf_pattern);
	FZ_INIT_STORABLE(pat, 1, pdf_free_pattern_imp);
	pat->resources = NULL;
	pat->contents = NULL;

	/* Store pattern now, to avoid possible recursion if objects refer back to this one */
	pdf_store_item(ctx, dict, pat, pdf_pattern_size(pat));

	pat->ismask = pdf_to_int(pdf_dict_gets(dict, "PaintType")) == 2;
	pat->xstep = pdf_to_real(pdf_dict_gets(dict, "XStep"));
	pat->ystep = pdf_to_real(pdf_dict_gets(dict, "YStep"));

	obj = pdf_dict_gets(dict, "BBox");
	pdf_to_rect(ctx, obj, &pat->bbox);

	obj = pdf_dict_gets(dict, "Matrix");
	if (obj)
		pdf_to_matrix(ctx, obj, &pat->matrix);
	else
		pat->matrix = fz_identity;

	pat->resources = pdf_dict_gets(dict, "Resources");
	if (pat->resources)
		pdf_keep_obj(pat->resources);

	fz_try(ctx)
	{
		pat->contents = pdf_keep_obj(dict);
	}
	fz_catch(ctx)
	{
		pdf_remove_item(ctx, pdf_free_pattern_imp, dict);
		pdf_drop_pattern(ctx, pat);
		fz_throw(ctx, "cannot load pattern stream (%d %d R)", pdf_to_num(dict), pdf_to_gen(dict));
	}
	return pat;
}
Example #10
0
float pdf_annot_opacity(fz_context *ctx, pdf_annot *annot)
{
	pdf_obj *ca = pdf_dict_get(ctx, annot->obj, PDF_NAME(CA));
	if (pdf_is_number(ctx, ca))
		return pdf_to_real(ctx, ca);
	return 1;
}
float
pdf_annot_border(fz_context *ctx, pdf_annot *annot)
{
	pdf_obj *border = pdf_dict_get(ctx, annot->obj, PDF_NAME_Border);
	if (pdf_is_array(ctx, border))
		return pdf_to_real(ctx, pdf_array_get(ctx, border, 2));
	return 1;
}
void
pdf_annot_vertex(fz_context *ctx, pdf_annot *annot, int i, float v[2])
{
	pdf_obj *vertices;
	fz_matrix page_ctm;
	fz_point point;

	check_allowed_subtypes(ctx, annot, PDF_NAME_Vertices, vertices_subtypes);

	vertices = pdf_dict_get(ctx, annot->obj, PDF_NAME_Vertices);

	pdf_page_transform(ctx, annot->page, NULL, &page_ctm);

	point.x = pdf_to_real(ctx, pdf_array_get(ctx, vertices, i * 2));
	point.y = pdf_to_real(ctx, pdf_array_get(ctx, vertices, i * 2 + 1));
	fz_transform_point(&point, &page_ctm);
	v[0] = point.x;
	v[1] = point.y;
}
Example #13
0
float
pdf_annot_border(fz_context *ctx, pdf_annot *annot)
{
	pdf_obj *bs, *bs_w;
	bs = pdf_dict_get(ctx, annot->obj, PDF_NAME(BS));
	bs_w = pdf_dict_get(ctx, bs, PDF_NAME(W));
	if (pdf_is_number(ctx, bs_w))
		return pdf_to_real(ctx, bs_w);
	return 1;
}
Example #14
0
static void
pdf_load_radial_shading(fz_shade *shade, pdf_document *xref, pdf_obj *dict, int funcs, pdf_function **func)
{
	pdf_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 = pdf_dict_gets(dict, "Coords");
	x0 = pdf_to_real(pdf_array_get(obj, 0));
	y0 = pdf_to_real(pdf_array_get(obj, 1));
	r0 = pdf_to_real(pdf_array_get(obj, 2));
	x1 = pdf_to_real(pdf_array_get(obj, 3));
	y1 = pdf_to_real(pdf_array_get(obj, 4));
	r1 = pdf_to_real(pdf_array_get(obj, 5));

	d0 = 0;
	d1 = 1;
	obj = pdf_dict_gets(dict, "Domain");
	if (pdf_array_len(obj) == 2)
	{
		d0 = pdf_to_real(pdf_array_get(obj, 0));
		d1 = pdf_to_real(pdf_array_get(obj, 1));
	}

	e0 = e1 = 0;
	obj = pdf_dict_gets(dict, "Extend");
	if (pdf_array_len(obj) == 2)
	{
		e0 = pdf_to_bool(pdf_array_get(obj, 0));
		e1 = pdf_to_bool(pdf_array_get(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);
}
Example #15
0
static void
pdf_load_linear_shading(fz_context *ctx, pdf_document *doc, fz_shade *shade, pdf_obj *dict, int funcs, fz_function **func)
{
	pdf_obj *obj;
	float d0, d1;
	int e0, e1;

	obj = pdf_dict_gets(ctx, dict, "Coords");
	shade->u.l_or_r.coords[0][0] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 0));
	shade->u.l_or_r.coords[0][1] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 1));
	shade->u.l_or_r.coords[1][0] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 2));
	shade->u.l_or_r.coords[1][1] = pdf_to_real(ctx, pdf_array_get(ctx, obj, 3));

	d0 = 0;
	d1 = 1;
	obj = pdf_dict_gets(ctx, dict, "Domain");
	if (obj)
	{
		d0 = pdf_to_real(ctx, pdf_array_get(ctx, obj, 0));
		d1 = pdf_to_real(ctx, pdf_array_get(ctx, obj, 1));
	}

	e0 = e1 = 0;
	obj = pdf_dict_gets(ctx, dict, "Extend");
	if (obj)
	{
		e0 = pdf_to_bool(ctx, pdf_array_get(ctx, obj, 0));
		e1 = pdf_to_bool(ctx, pdf_array_get(ctx, obj, 1));
	}

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

	shade->u.l_or_r.extend[0] = e0;
	shade->u.l_or_r.extend[1] = e1;
}
static void pdf_annot_color_imp(fz_context *ctx, pdf_annot *annot, pdf_obj *key, int *n, float color[4], pdf_obj **allowed)
{
	pdf_obj *arr;
	int len;

	if (allowed)
		check_allowed_subtypes(ctx, annot, key, allowed);

	arr = pdf_dict_get(ctx, annot->obj, key);
	len = pdf_array_len(ctx, arr);

	switch (len)
	{
	case 0:
		if (n)
			*n = 0;
		break;
	case 1:
	case 2:
		if (n)
			*n = 1;
		if (color)
			color[0] = pdf_to_real(ctx, pdf_array_get(ctx, arr, 0));
		break;
	case 3:
		if (n)
			*n = 3;
		if (color)
		{
			color[0] = pdf_to_real(ctx, pdf_array_get(ctx, arr, 0));
			color[1] = pdf_to_real(ctx, pdf_array_get(ctx, arr, 1));
			color[2] = pdf_to_real(ctx, pdf_array_get(ctx, arr, 2));
		}
		break;
	case 4:
	default:
		if (n)
			*n = 4;
		if (color)
		{
			color[0] = pdf_to_real(ctx, pdf_array_get(ctx, arr, 0));
			color[1] = pdf_to_real(ctx, pdf_array_get(ctx, arr, 1));
			color[2] = pdf_to_real(ctx, pdf_array_get(ctx, arr, 2));
			color[3] = pdf_to_real(ctx, pdf_array_get(ctx, arr, 3));
		}
		break;
	}
}
Example #17
0
static void
pdf_load_font_descriptor(pdf_font_desc *fontdesc, pdf_document *doc, pdf_obj *dict, char *collection, char *basefont, int iscidfont, int has_encoding)
{
	pdf_obj *obj1, *obj2, *obj3, *obj;
	char *fontname, *origname;
	FT_Face face;
	fz_context *ctx = doc->ctx;

	/* Prefer BaseFont; don't bother with FontName */
	origname = basefont;

	/* SumatraPDF: handle /BaseFont /Arial,Bold+000041 /FontName /Arial,Bold */
	if (strchr(basefont, '+') && pdf_is_name(pdf_dict_gets(dict, "FontName")))
		origname = pdf_to_name(pdf_dict_gets(dict, "FontName"));

	/* cf. http://code.google.com/p/sumatrapdf/issues/detail?id=1616 */
	if (strlen(origname) > 7 && origname[6] == '+')
		origname += 7;

	/* Look through list of alternate names for built in fonts */
	fontname = clean_font_name(origname);

	fontdesc->flags = pdf_to_int(pdf_dict_gets(dict, "Flags"));
	fontdesc->italic_angle = pdf_to_real(pdf_dict_gets(dict, "ItalicAngle"));
	fontdesc->ascent = pdf_to_real(pdf_dict_gets(dict, "Ascent"));
	fontdesc->descent = pdf_to_real(pdf_dict_gets(dict, "Descent"));
	fontdesc->cap_height = pdf_to_real(pdf_dict_gets(dict, "CapHeight"));
	fontdesc->x_height = pdf_to_real(pdf_dict_gets(dict, "XHeight"));
	fontdesc->missing_width = pdf_to_real(pdf_dict_gets(dict, "MissingWidth"));

	obj1 = pdf_dict_gets(dict, "FontFile");
	obj2 = pdf_dict_gets(dict, "FontFile2");
	obj3 = pdf_dict_gets(dict, "FontFile3");
	obj = obj1 ? obj1 : obj2 ? obj2 : obj3;

	if (pdf_is_indirect(obj))
	{
		fz_try(ctx)
		{
			pdf_load_embedded_font(doc, fontdesc, fontname, obj);
		}
		fz_catch(ctx)
		{
			fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
			fz_warn(ctx, "ignored error when loading embedded font; attempting to load system font");
			if (origname != fontname && !iscidfont)
				pdf_load_builtin_font(ctx, fontdesc, fontname);
			else
				pdf_load_system_font(ctx, fontdesc, fontname, collection, has_encoding);
		}
	}
	else
	{
		if (origname != fontname && !iscidfont)
fz_matrix *
pdf_to_matrix(fz_context *ctx, pdf_obj *array, fz_matrix *m)
{
    m->a = pdf_to_real(pdf_array_get(array, 0));
    m->b = pdf_to_real(pdf_array_get(array, 1));
    m->c = pdf_to_real(pdf_array_get(array, 2));
    m->d = pdf_to_real(pdf_array_get(array, 3));
    m->e = pdf_to_real(pdf_array_get(array, 4));
    m->f = pdf_to_real(pdf_array_get(array, 5));
    return m;
}
Example #19
0
fz_matrix
pdf_to_matrix(fz_context *ctx, pdf_obj *array)
{
    fz_matrix m;
    m.a = pdf_to_real(pdf_array_get(array, 0));
    m.b = pdf_to_real(pdf_array_get(array, 1));
    m.c = pdf_to_real(pdf_array_get(array, 2));
    m.d = pdf_to_real(pdf_array_get(array, 3));
    m.e = pdf_to_real(pdf_array_get(array, 4));
    m.f = pdf_to_real(pdf_array_get(array, 5));
    return m;
}
Example #20
0
static void
pdf_load_transition(pdf_document *doc, pdf_page *page, pdf_obj *transdict)
{
	char *name;
	pdf_obj *obj;
	int type;

	obj = pdf_dict_gets(transdict, "D");
	page->transition.duration = (obj ? pdf_to_real(obj) : 1);

	page->transition.vertical = (pdf_to_name(pdf_dict_gets(transdict, "Dm"))[0] != 'H');
	page->transition.outwards = (pdf_to_name(pdf_dict_gets(transdict, "M"))[0] != 'I');
	/* FIXME: If 'Di' is None, it should be handled differently, but
	 * this only affects Fly, and we don't implement that currently. */
	page->transition.direction = (pdf_to_int(pdf_dict_gets(transdict, "Di")));
	/* FIXME: Read SS for Fly when we implement it */
	/* FIXME: Read B for Fly when we implement it */

	name = pdf_to_name(pdf_dict_gets(transdict, "S"));
	if (!strcmp(name, "Split"))
		type = FZ_TRANSITION_SPLIT;
	else if (!strcmp(name, "Blinds"))
		type = FZ_TRANSITION_BLINDS;
	else if (!strcmp(name, "Box"))
		type = FZ_TRANSITION_BOX;
	else if (!strcmp(name, "Wipe"))
		type = FZ_TRANSITION_WIPE;
	else if (!strcmp(name, "Dissolve"))
		type = FZ_TRANSITION_DISSOLVE;
	else if (!strcmp(name, "Glitter"))
		type = FZ_TRANSITION_GLITTER;
	else if (!strcmp(name, "Fly"))
		type = FZ_TRANSITION_FLY;
	else if (!strcmp(name, "Push"))
		type = FZ_TRANSITION_PUSH;
	else if (!strcmp(name, "Cover"))
		type = FZ_TRANSITION_COVER;
	else if (!strcmp(name, "Uncover"))
		type = FZ_TRANSITION_UNCOVER;
	else if (!strcmp(name, "Fade"))
		type = FZ_TRANSITION_FADE;
	else
		type = FZ_TRANSITION_NONE;
	page->transition.type = type;
}
Example #21
0
File: data.c Project: amba/pdfout
pdfout_data *
pdfout_data_scalar_from_pdf (fz_context *ctx, pdf_obj *obj)
{
  const char *s;
  if (pdf_is_null (ctx, obj))
    return pdfout_data_scalar_new (ctx, "null", strlen ("null"));
  else if (pdf_is_bool (ctx, obj))
    {
      if (pdf_to_bool (ctx, obj))
	s = "true";
      else
	s = "false";
      return pdfout_data_scalar_new (ctx, s, strlen (s));
    }
  else if (pdf_is_name (ctx, obj))
    {
      s = pdf_to_name (ctx, obj);
      return pdfout_data_scalar_new (ctx, s, strlen (s));
    }
  else if (pdf_is_string (ctx, obj))
    {
      int len;
      char *str = pdfout_str_obj_to_utf8 (ctx, obj, &len);
      pdfout_data *result =  pdfout_data_scalar_new (ctx, str, len);
      free (str);
      return result;
    }
  else if (pdf_is_int (ctx, obj))
    {
      int n = pdf_to_int (ctx, obj);
      char buf[200];
      int len = pdfout_snprintf (ctx, buf, "%d", n);
      return pdfout_data_scalar_new (ctx, buf, len);
    }
  else if (pdf_is_real (ctx, obj))
    {
      float f = pdf_to_real (ctx, obj);
      char buf[200];
      int len = pdfout_snprintf (ctx, buf, "%g", f);
      return pdfout_data_scalar_new (ctx, buf, len);
    }
  else
    abort();
  
}
Example #22
0
static void
pdf_load_mesh_params(pdf_document *xref, pdf_obj *dict, struct mesh_params *p)
{
	pdf_obj *obj;
	int i, n;

	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 = pdf_to_int(pdf_dict_gets(dict, "VerticesPerRow"));
	p->bpflag = pdf_to_int(pdf_dict_gets(dict, "BitsPerFlag"));
	p->bpcoord = pdf_to_int(pdf_dict_gets(dict, "BitsPerCoordinate"));
	p->bpcomp = pdf_to_int(pdf_dict_gets(dict, "BitsPerComponent"));

	obj = pdf_dict_gets(dict, "Decode");
	if (pdf_array_len(obj) >= 6)
	{
		n = (pdf_array_len(obj) - 4) / 2;
		p->x0 = pdf_to_real(pdf_array_get(obj, 0));
		p->x1 = pdf_to_real(pdf_array_get(obj, 1));
		p->y0 = pdf_to_real(pdf_array_get(obj, 2));
		p->y1 = pdf_to_real(pdf_array_get(obj, 3));
		for (i = 0; i < n; i++)
		{
			p->c0[i] = pdf_to_real(pdf_array_get(obj, 4 + i * 2));
			p->c1[i] = pdf_to_real(pdf_array_get(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;
}
Example #23
0
static void
gatherdimensions(int page, pdf_obj *pageref, pdf_obj *pageobj)
{
	fz_rect bbox;
	pdf_obj *obj;
	int j;

	obj = pdf_dict_gets(pageobj, "MediaBox");
	if (!pdf_is_array(obj))
		return;

	pdf_to_rect(ctx, obj, &bbox);

	obj = pdf_dict_gets(pageobj, "UserUnit");
	if (pdf_is_real(obj))
	{
		float unit = pdf_to_real(obj);
		bbox.x0 *= unit;
		bbox.y0 *= unit;
		bbox.x1 *= unit;
		bbox.y1 *= unit;
	}

	for (j = 0; j < dims; j++)
		if (!memcmp(dim[j].u.dim.bbox, &bbox, sizeof (fz_rect)))
			break;

	if (j < dims)
		return;

	dim = fz_resize_array(ctx, dim, dims+1, sizeof(struct info));
	dims++;

	dim[dims - 1].page = page;
	dim[dims - 1].pageref = pageref;
	dim[dims - 1].pageobj = pageobj;
	dim[dims - 1].u.dim.bbox = fz_malloc(ctx, sizeof(fz_rect));
	memcpy(dim[dims - 1].u.dim.bbox, &bbox, sizeof (fz_rect));

	return;
}
Example #24
0
static int
shownum(fz_context *ctx, fz_output *out, pdf_obj *page, char *text, pdf_obj *name)
{
	pdf_obj *obj;
	int failed = 0;

	fz_try(ctx)
	{
		obj = pdf_dict_get(ctx, page, name);
		if (!pdf_is_number(ctx, obj))
			break;

		fz_printf(ctx, out, "<%s v=\"%g\" />\n", text, pdf_to_real(ctx, obj));
	}
	fz_catch(ctx)
	{
		failed = 1;
	}

	return failed;
}
Example #25
0
/*
** Look at CropBox and MediaBox entries to determine visible page origin.
*/
static void wmupdf_page_bbox(pdf_obj *srcpage,double *bbox_array)

    {
    int i;

    bbox_array[0] = bbox_array[1] = -1e10;
    bbox_array[2] = bbox_array[3] = 1e10;
    for (i=0;i<2;i++)
        {
        static char *boxname[] = {"MediaBox","CropBox"};
        pdf_obj *box;

        box=pdf_dict_gets(srcpage,boxname[i]);
        if (box!=NULL)
            {
            int j;
            for (j=0;j<4;j++)
                {
                pdf_obj *obj;

                obj=pdf_array_get(box,j);
                if (obj!=NULL)
                    {
                    double x;
                    x=pdf_to_real(obj);
                    if ((j<2 && x>bbox_array[j]) || (j>=2 && x<bbox_array[j]))
                        bbox_array[j]=x;
                    }
                }
            }
        }
    if (bbox_array[0] < -9e9)
        bbox_array[0] = 0.;
    if (bbox_array[1] < -9e9)
        bbox_array[1] = 0.;
    if (bbox_array[2] > 9e9)
        bbox_array[2] = 612.;
    if (bbox_array[3] > 9e9)
        bbox_array[3] = 792.;
    }
Example #26
0
static void
pdf_load_font_descriptor(pdf_font_desc *fontdesc, pdf_document *xref, pdf_obj *dict, char *collection, char *basefont)
{
	pdf_obj *obj1, *obj2, *obj3, *obj;
	char *fontname;
	char *origname;
	FT_Face face;
	fz_context *ctx = xref->ctx;

	if (!strchr(basefont, ',') || strchr(basefont, '+'))
		origname = pdf_to_name(pdf_dict_gets(dict, "FontName"));
	else
		origname = basefont;
	fontname = clean_font_name(origname);

	fontdesc->flags = pdf_to_int(pdf_dict_gets(dict, "Flags"));
	fontdesc->italic_angle = pdf_to_real(pdf_dict_gets(dict, "ItalicAngle"));
	fontdesc->ascent = pdf_to_real(pdf_dict_gets(dict, "Ascent"));
	fontdesc->descent = pdf_to_real(pdf_dict_gets(dict, "Descent"));
	fontdesc->cap_height = pdf_to_real(pdf_dict_gets(dict, "CapHeight"));
	fontdesc->x_height = pdf_to_real(pdf_dict_gets(dict, "XHeight"));
	fontdesc->missing_width = pdf_to_real(pdf_dict_gets(dict, "MissingWidth"));

	obj1 = pdf_dict_gets(dict, "FontFile");
	obj2 = pdf_dict_gets(dict, "FontFile2");
	obj3 = pdf_dict_gets(dict, "FontFile3");
	obj = obj1 ? obj1 : obj2 ? obj2 : obj3;

	if (pdf_is_indirect(obj))
	{
		fz_try(ctx)
		{
			pdf_load_embedded_font(fontdesc, xref, obj);
		}
		fz_catch(ctx)
		{
			fz_warn(ctx, "ignored error when loading embedded font; attempting to load system font");
			if (origname != fontname)
				pdf_load_builtin_font(ctx, fontdesc, fontname);
			else
				pdf_load_system_font(ctx, fontdesc, fontname, collection);
			/* RJW: "cannot load font descriptor (%d %d R)", pdf_to_num(dict), pdf_to_gen(dict) */
		}
	}
	else
	{
		if (origname != fontname)
Example #27
0
static void
pdf_load_font_descriptor(pdf_font_desc *fontdesc, pdf_document *doc, pdf_obj *dict, char *collection, char *basefont, int iscidfont)
{
	pdf_obj *obj1, *obj2, *obj3, *obj;
	char *fontname, *origname;
	FT_Face face;
	fz_context *ctx = doc->ctx;

	/* Prefer BaseFont; don't bother with FontName */
	origname = basefont;

	/* Look through list of alternate names for built in fonts */
	fontname = clean_font_name(origname);

	fontdesc->flags = pdf_to_int(pdf_dict_gets(dict, "Flags"));
	fontdesc->italic_angle = pdf_to_real(pdf_dict_gets(dict, "ItalicAngle"));
	fontdesc->ascent = pdf_to_real(pdf_dict_gets(dict, "Ascent"));
	fontdesc->descent = pdf_to_real(pdf_dict_gets(dict, "Descent"));
	fontdesc->cap_height = pdf_to_real(pdf_dict_gets(dict, "CapHeight"));
	fontdesc->x_height = pdf_to_real(pdf_dict_gets(dict, "XHeight"));
	fontdesc->missing_width = pdf_to_real(pdf_dict_gets(dict, "MissingWidth"));

	obj1 = pdf_dict_gets(dict, "FontFile");
	obj2 = pdf_dict_gets(dict, "FontFile2");
	obj3 = pdf_dict_gets(dict, "FontFile3");
	obj = obj1 ? obj1 : obj2 ? obj2 : obj3;

	if (pdf_is_indirect(obj))
	{
		fz_try(ctx)
		{
			pdf_load_embedded_font(doc, fontdesc, fontname, obj);
		}
		fz_catch(ctx)
		{
			fz_rethrow_if(ctx, FZ_ERROR_TRYLATER);
			fz_warn(ctx, "ignored error when loading embedded font; attempting to load system font");
			if (origname != fontname && !iscidfont)
				pdf_load_builtin_font(ctx, fontdesc, fontname);
			else
				pdf_load_system_font(ctx, fontdesc, fontname, collection);
		}
	}
	else
	{
		if (origname != fontname && !iscidfont)
Example #28
0
static void
pdf_load_jpx(pdf_document *xref, pdf_obj *dict, pdf_image *image, int forcemask)
{
	fz_buffer *buf = NULL;
	fz_colorspace *colorspace = NULL;
	fz_pixmap *img = NULL;
	pdf_obj *obj;
	fz_context *ctx = xref->ctx;
	int indexed = 0;

	fz_var(img);
	fz_var(buf);
	fz_var(colorspace);

	buf = pdf_load_stream(xref, pdf_to_num(dict), pdf_to_gen(dict));

	/* FIXME: We can't handle decode arrays for indexed images currently */
	fz_try(ctx)
	{
		obj = pdf_dict_gets(dict, "ColorSpace");
		if (obj)
		{
			colorspace = pdf_load_colorspace(xref, obj);
			indexed = !strcmp(colorspace->name, "Indexed");
		}

		img = fz_load_jpx(ctx, buf->data, buf->len, colorspace, indexed);

		if (img && colorspace == NULL)
			colorspace = fz_keep_colorspace(ctx, img->colorspace);

		fz_drop_buffer(ctx, buf);
		buf = NULL;

		obj = pdf_dict_getsa(dict, "SMask", "Mask");
		if (pdf_is_dict(obj))
		{
			if (forcemask)
				fz_warn(ctx, "Ignoring recursive JPX soft mask");
			else
				image->base.mask = (fz_image *)pdf_load_image_imp(xref, NULL, obj, NULL, 1);
		}

		obj = pdf_dict_getsa(dict, "Decode", "D");
		if (obj && !indexed)
		{
			float decode[FZ_MAX_COLORS * 2];
			int i;

			for (i = 0; i < img->n * 2; i++)
				decode[i] = pdf_to_real(pdf_array_get(obj, i));

			fz_decode_tile(img, decode);
		}
	}
	fz_catch(ctx)
	{
		if (colorspace)
			fz_drop_colorspace(ctx, colorspace);
		fz_drop_buffer(ctx, buf);
		fz_drop_pixmap(ctx, img);
		fz_rethrow(ctx);
	}
	FZ_INIT_STORABLE(&image->base, 1, pdf_free_image);
	image->base.get_pixmap = pdf_image_get_pixmap;
	image->base.w = img->w;
	image->base.h = img->h;
	image->base.bpc = 8;
	image->base.colorspace = colorspace;
	image->buffer = NULL;
	image->tile = img;
	image->n = img->n;
	image->interpolate = 0;
	image->imagemask = 0;
	image->usecolorkey = 0;
}
Example #29
0
static pdf_image *
pdf_load_image_imp(pdf_document *xref, pdf_obj *rdb, pdf_obj *dict, fz_stream *cstm, int forcemask)
{
	fz_stream *stm = NULL;
	pdf_image *image = NULL;
	pdf_obj *obj, *res;

	int w, h, bpc, n;
	int imagemask;
	int interpolate;
	int indexed;
	fz_image *mask = NULL; /* explicit mask/soft mask image */
	int usecolorkey;

	int i;
	fz_context *ctx = xref->ctx;

	fz_var(stm);
	fz_var(mask);

	image = fz_malloc_struct(ctx, pdf_image);

	fz_try(ctx)
	{
		/* special case for JPEG2000 images */
		if (pdf_is_jpx_image(ctx, dict))
		{
			pdf_load_jpx(xref, dict, image, forcemask);

			if (forcemask)
			{
				fz_pixmap *mask_pixmap;
				if (image->n != 2)
					fz_throw(ctx, "soft mask must be grayscale");
				mask_pixmap = fz_alpha_from_gray(ctx, image->tile, 1);
				fz_drop_pixmap(ctx, image->tile);
				image->tile = mask_pixmap;
			}
			break; /* Out of fz_try */
		}

		w = pdf_to_int(pdf_dict_getsa(dict, "Width", "W"));
		h = pdf_to_int(pdf_dict_getsa(dict, "Height", "H"));
		bpc = pdf_to_int(pdf_dict_getsa(dict, "BitsPerComponent", "BPC"));
		if (bpc == 0)
			bpc = 8;
		imagemask = pdf_to_bool(pdf_dict_getsa(dict, "ImageMask", "IM"));
		interpolate = pdf_to_bool(pdf_dict_getsa(dict, "Interpolate", "I"));

		indexed = 0;
		usecolorkey = 0;
		mask = NULL;

		if (imagemask)
			bpc = 1;

		if (w <= 0)
			fz_throw(ctx, "image width is zero (or less)");
		if (h <= 0)
			fz_throw(ctx, "image height is zero (or less)");
		if (bpc <= 0)
			fz_throw(ctx, "image depth is zero (or less)");
		if (bpc > 16)
			fz_throw(ctx, "image depth is too large: %d", bpc);
		if (w > (1 << 16))
			fz_throw(ctx, "image is too wide");
		if (h > (1 << 16))
			fz_throw(ctx, "image is too high");

		obj = pdf_dict_getsa(dict, "ColorSpace", "CS");
		if (obj && !imagemask && !forcemask)
		{
			/* colorspace resource lookup is only done for inline images */
			if (pdf_is_name(obj))
			{
				res = pdf_dict_get(pdf_dict_gets(rdb, "ColorSpace"), obj);
				if (res)
					obj = res;
			}

			image->base.colorspace = pdf_load_colorspace(xref, obj);

			if (!strcmp(image->base.colorspace->name, "Indexed"))
				indexed = 1;

			n = image->base.colorspace->n;
		}
		else
		{
			n = 1;
		}

		obj = pdf_dict_getsa(dict, "Decode", "D");
		if (obj)
		{
			for (i = 0; i < n * 2; i++)
				image->decode[i] = pdf_to_real(pdf_array_get(obj, i));
		}
		else
		{
			float maxval = indexed ? (1 << bpc) - 1 : 1;
			for (i = 0; i < n * 2; i++)
				image->decode[i] = i & 1 ? maxval : 0;
		}

		obj = pdf_dict_getsa(dict, "SMask", "Mask");
		if (pdf_is_dict(obj))
		{
			/* Not allowed for inline images or soft masks */
			if (cstm)
				fz_warn(ctx, "Ignoring invalid inline image soft mask");
			else if (forcemask)
				fz_warn(ctx, "Ignoring recursive image soft mask");
			else
				mask = (fz_image *)pdf_load_image_imp(xref, rdb, obj, NULL, 1);
		}
		else if (pdf_is_array(obj))
		{
			usecolorkey = 1;
			for (i = 0; i < n * 2; i++)
			{
				if (!pdf_is_int(pdf_array_get(obj, i)))
				{
					fz_warn(ctx, "invalid value in color key mask");
					usecolorkey = 0;
				}
				image->colorkey[i] = pdf_to_int(pdf_array_get(obj, i));
			}
		}

		/* Now, do we load a ref, or do we load the actual thing? */
		FZ_INIT_STORABLE(&image->base, 1, pdf_free_image);
		image->base.get_pixmap = pdf_image_get_pixmap;
		image->base.w = w;
		image->base.h = h;
		image->base.bpc = bpc;
		image->n = n;
		image->interpolate = interpolate;
		image->imagemask = imagemask;
		image->usecolorkey = usecolorkey;
		image->base.mask = mask;
		if (!cstm)
		{
			/* Just load the compressed image data now and we can
			 * decode it on demand. */
			int num = pdf_to_num(dict);
			int gen = pdf_to_gen(dict);
			image->buffer = pdf_load_compressed_stream(xref, num, gen);
			break; /* Out of fz_try */
		}

		/* We need to decompress the image now */
		if (cstm)
		{
			int stride = (w * image->n * image->base.bpc + 7) / 8;
			stm = pdf_open_inline_stream(xref, dict, stride * h, cstm, NULL);
		}
		else
		{
			stm = pdf_open_stream(xref, pdf_to_num(dict), pdf_to_gen(dict));
		}

		image->tile = decomp_image_from_stream(ctx, stm, image, cstm != NULL, indexed, 0, 0, 0);
	}
	fz_catch(ctx)
	{
		pdf_free_image(ctx, (fz_storable *) image);
		fz_rethrow(ctx);
	}
	return image;
}
Example #30
0
pdf_font_desc *
pdf_load_type3_font(fz_context *ctx, pdf_document *doc, pdf_obj *rdb, pdf_obj *dict)
{
	char buf[256];
	char *estrings[256];
	pdf_font_desc *fontdesc = NULL;
	pdf_obj *encoding;
	pdf_obj *widths;
	pdf_obj *charprocs;
	pdf_obj *obj;
	int first, last;
	int i, k, n;
	fz_rect bbox;
	fz_matrix matrix;
	fz_font *font;

	fz_var(fontdesc);

	/* Make a new type3 font entry in the document */
	if (doc->num_type3_fonts == doc->max_type3_fonts)
	{
		int new_max = doc->max_type3_fonts * 2;

		if (new_max == 0)
			new_max = 4;
		doc->type3_fonts = fz_resize_array(ctx, doc->type3_fonts, new_max, sizeof(*doc->type3_fonts));
		doc->max_type3_fonts = new_max;
	}

	fz_try(ctx)
	{
		obj = pdf_dict_get(ctx, dict, PDF_NAME_Name);
		if (pdf_is_name(ctx, obj))
			fz_strlcpy(buf, pdf_to_name(ctx, obj), sizeof buf);
		else
			fz_strlcpy(buf, "Unnamed-T3", sizeof buf);

		fontdesc = pdf_new_font_desc(ctx);

		obj = pdf_dict_get(ctx, dict, PDF_NAME_FontMatrix);
		pdf_to_matrix(ctx, obj, &matrix);

		obj = pdf_dict_get(ctx, dict, PDF_NAME_FontBBox);
		fz_transform_rect(pdf_to_rect(ctx, obj, &bbox), &matrix);

		font = fz_new_type3_font(ctx, buf, &matrix);
		fontdesc->font = font;
		fontdesc->size += sizeof(fz_font) + 256 * (sizeof(fz_buffer*) + sizeof(float));

		fz_set_font_bbox(ctx, font, bbox.x0, bbox.y0, bbox.x1, bbox.y1);

		/* Encoding */

		for (i = 0; i < 256; i++)
			estrings[i] = NULL;

		encoding = pdf_dict_get(ctx, dict, PDF_NAME_Encoding);
		if (!encoding)
		{
			fz_throw(ctx, FZ_ERROR_GENERIC, "syntaxerror: Type3 font missing Encoding");
		}

		if (pdf_is_name(ctx, encoding))
			pdf_load_encoding(estrings, pdf_to_name(ctx, encoding));

		if (pdf_is_dict(ctx, encoding))
		{
			pdf_obj *base, *diff, *item;

			base = pdf_dict_get(ctx, encoding, PDF_NAME_BaseEncoding);
			if (pdf_is_name(ctx, base))
				pdf_load_encoding(estrings, pdf_to_name(ctx, base));

			diff = pdf_dict_get(ctx, encoding, PDF_NAME_Differences);
			if (pdf_is_array(ctx, diff))
			{
				n = pdf_array_len(ctx, diff);
				k = 0;
				for (i = 0; i < n; i++)
				{
					item = pdf_array_get(ctx, diff, i);
					if (pdf_is_int(ctx, item))
						k = pdf_to_int(ctx, item);
					if (pdf_is_name(ctx, item) && k >= 0 && k < nelem(estrings))
						estrings[k++] = pdf_to_name(ctx, item);
				}
			}
		}

		fontdesc->encoding = pdf_new_identity_cmap(ctx, 0, 1);
		fontdesc->size += pdf_cmap_size(ctx, fontdesc->encoding);

		pdf_load_to_unicode(ctx, doc, fontdesc, estrings, NULL, pdf_dict_get(ctx, dict, PDF_NAME_ToUnicode));

		/* Widths */

		pdf_set_default_hmtx(ctx, fontdesc, 0);

		first = pdf_to_int(ctx, pdf_dict_get(ctx, dict, PDF_NAME_FirstChar));
		last = pdf_to_int(ctx, pdf_dict_get(ctx, dict, PDF_NAME_LastChar));

		if (first < 0 || last > 255 || first > last)
			first = last = 0;

		widths = pdf_dict_get(ctx, dict, PDF_NAME_Widths);
		if (!widths)
		{
			fz_throw(ctx, FZ_ERROR_GENERIC, "syntaxerror: Type3 font missing Widths");
		}

		for (i = first; i <= last; i++)
		{
			float w = pdf_to_real(ctx, pdf_array_get(ctx, widths, i - first));
			w = font->t3matrix.a * w * 1000;
			font->t3widths[i] = w * 0.001f;
			pdf_add_hmtx(ctx, fontdesc, i, i, w);
		}

		pdf_end_hmtx(ctx, fontdesc);

		/* Resources -- inherit page resources if the font doesn't have its own */

		font->t3freeres = pdf_t3_free_resources;
		font->t3resources = pdf_dict_get(ctx, dict, PDF_NAME_Resources);
		if (!font->t3resources)
			font->t3resources = rdb;
		if (font->t3resources)
			pdf_keep_obj(ctx, font->t3resources);
		if (!font->t3resources)
			fz_warn(ctx, "no resource dictionary for type 3 font!");

		font->t3doc = doc;
		font->t3run = pdf_run_glyph_func;

		/* CharProcs */

		charprocs = pdf_dict_get(ctx, dict, PDF_NAME_CharProcs);
		if (!charprocs)
		{
			fz_throw(ctx, FZ_ERROR_GENERIC, "syntaxerror: Type3 font missing CharProcs");
		}

		for (i = 0; i < 256; i++)
		{
			if (estrings[i])
			{
				obj = pdf_dict_gets(ctx, charprocs, estrings[i]);
				if (pdf_is_stream(ctx, obj))
				{
					font->t3procs[i] = pdf_load_stream(ctx, obj);
					fz_trim_buffer(ctx, font->t3procs[i]);
					fontdesc->size += fz_buffer_storage(ctx, font->t3procs[i], NULL);
					fontdesc->size += 0; // TODO: display list size calculation
				}
			}
		}
	}
	fz_catch(ctx)
	{
		pdf_drop_font(ctx, fontdesc);
		fz_rethrow(ctx);
	}

	doc->type3_fonts[doc->num_type3_fonts++] = fz_keep_font(ctx, font);

	return fontdesc;
}