Exemplo n.º 1
0
static void
gathershadings(int page, pdf_obj *pageref, pdf_obj *pageobj, pdf_obj *dict)
{
	int i, n;

	n = pdf_dict_len(dict);
	for (i = 0; i < n; i++)
	{
		pdf_obj *shade;
		pdf_obj *type;
		int k;

		shade = pdf_dict_get_val(dict, i);
		if (!pdf_is_dict(shade))
		{
			fz_warn(ctx, "not a shading dict (%d %d R)", pdf_to_num(shade), pdf_to_gen(shade));
			continue;
		}

		type = pdf_dict_gets(shade, "ShadingType");
		if (!pdf_is_int(type) || pdf_to_int(type) < 1 || pdf_to_int(type) > 7)
		{
			fz_warn(ctx, "not a shading type (%d %d R)", pdf_to_num(shade), pdf_to_gen(shade));
			type = NULL;
		}

		for (k = 0; k < shadings; k++)
			if (!pdf_objcmp(shading[k].u.shading.obj, shade))
				break;

		if (k < shadings)
			continue;

		shadings++;

		shading = fz_resize_array(ctx, shading, shadings, sizeof(struct info));
		shading[shadings - 1].page = page;
		shading[shadings - 1].pageref = pageref;
		shading[shadings - 1].pageobj = pageobj;
		shading[shadings - 1].u.shading.obj = shade;
		shading[shadings - 1].u.shading.type = type;
	}
}
Exemplo n.º 2
0
decode_params *
pdf_decode_params_load(pdf_obj *obj)
{
    decode_params *dp = pdf_malloc(sizeof(decode_params));

    if (!obj)
        return 0;
    if (!dp)
        return 0;
    memset(dp, 0, sizeof(decode_params));

    dp->predictor = pdf_to_int(pdf_dict_get(obj, "Predictor"));
    dp->colors = pdf_to_int(pdf_dict_get(obj, "Colors"));
    dp->bitspercomponent = pdf_to_int(pdf_dict_get(obj, "BitsPerComponent"));
    dp->columns = pdf_to_int(pdf_dict_get(obj, "Columns"));
    dp->earlychange = pdf_to_int(pdf_dict_get(obj, "EarlyChange"));

    return dp;
}
Exemplo n.º 3
0
int
pdf_count_pages(pdf_document *doc)
{
	if (doc->page_count == 0)
	{
		pdf_obj *count = pdf_dict_getp(pdf_trailer(doc), "Root/Pages/Count");
		doc->page_count = pdf_to_int(count);
	}
	return doc->page_count;
}
Exemplo n.º 4
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)
Exemplo n.º 5
0
ErrorCode juggler_add_pages_from_file(juggler_t *dest, juggler_t *src, int dest_index)
{
	pdf_obj *dest_pages = pdf_dict_getp(dest->ctx, 
		pdf_trailer(dest->ctx, dest->pdf), "Root/Pages");
	int dest_pages_index = pdf_array_len(dest->ctx, 
		pdf_dict_gets(dest->ctx, dest_pages, "Kids"));
		
	/* be aware that this function does not change the two variables if the page
	   index is greater than the number of pages */
	find_destination_pages(dest->ctx, 
		dest_pages, dest_index, &dest_pages, &dest_pages_index);

	pdf_obj *dest_kids = pdf_dict_gets(dest->ctx, dest_pages, "Kids");
	if(!pdf_is_indirect(dest->ctx, dest_pages) || 
		!pdf_is_dict(dest->ctx, dest_pages) || !pdf_is_array(dest->ctx, dest_kids))
	{
		return(ERROR_INVALID_RANGE);
	}
	
	pdf_obj *pages_root = pdf_dict_getp(src->ctx, pdf_trailer(src->ctx, src->pdf), "Root/Pages");
	if(!pdf_is_indirect(src->ctx, pages_root) || !pdf_is_dict(src->ctx, pages_root))
		return(ERROR_NO_PAGES);

	/* if we copy the root pages-node and it's referenced objects, we will copy 
	   all pages and all objects those pages need */
	pdf_obj *new_pages_ref = copy_object_single(dest->ctx, dest->pdf, src->ctx, src->pdf, pages_root);

	/* insert new pages-node */
	pdf_array_insert_drop(dest->ctx, dest_kids, new_pages_ref, dest_pages_index);

	/* update the parent */
	pdf_obj *new_pages_parent = pdf_new_indirect(dest->ctx, dest->pdf, 
		pdf_to_num(dest->ctx, dest_pages), pdf_to_gen(dest->ctx, dest_pages));
	pdf_dict_puts_drop(dest->ctx, new_pages_ref, "Parent", new_pages_parent);

	/* TODO: If dest_pages contains anything inheritable but not the new node
	         we need to insert empty items to prevent this inerhitance */

	/* update count */
	int new_count = pdf_to_int(dest->ctx, 
		pdf_dict_gets(dest->ctx, dest_pages, "Count")) + src->pagecount;
	pdf_dict_puts_drop(dest->ctx, dest_pages, "Count", 
		pdf_new_int(dest->ctx, dest->pdf, new_count));

	/* let MuPDF rebuild the page tree */
	pdf_finish_edit(dest->ctx, dest->pdf);
	dest->pdf->page_count = new_count;

	/* update juggler's state */
	juggler_page_tree_changed_due_to_insert(dest, dest_index, src->pagecount);

	return(NoError);
}
Exemplo n.º 6
0
static fz_buffer *
pdf_load_image_stream(fz_context *ctx, pdf_document *doc, int num, int gen, int orig_num, int orig_gen, fz_compression_params *params, int *truncated)
{
	fz_stream *stm = NULL;
	pdf_obj *dict, *obj;
	int i, len, n;
	fz_buffer *buf;

	fz_var(buf);

	if (num > 0 && num < pdf_xref_len(ctx, doc))
	{
		pdf_xref_entry *entry = pdf_get_xref_entry(ctx, doc, num);
		/* Return ref to existing buffer, but only if uncompressed,
		 * or shortstoppable */
		if (can_reuse_buffer(ctx, entry, params))
			return fz_keep_buffer(ctx, entry->stm_buf);
	}

	dict = pdf_load_object(ctx, doc, num, gen);

	len = pdf_to_int(ctx, pdf_dict_get(ctx, dict, PDF_NAME_Length));
	obj = pdf_dict_get(ctx, dict, PDF_NAME_Filter);
	len = pdf_guess_filter_length(len, pdf_to_name(ctx, obj));
	n = pdf_array_len(ctx, obj);
	for (i = 0; i < n; i++)
		len = pdf_guess_filter_length(len, pdf_to_name(ctx, pdf_array_get(ctx, obj, i)));

	pdf_drop_obj(ctx, dict);

	stm = pdf_open_image_stream(ctx, doc, num, gen, orig_num, orig_gen, params);

	fz_try(ctx)
	{
		if (truncated)
			buf = fz_read_best(ctx, stm, len, truncated);
		else
			buf = fz_read_all(ctx, stm, len);
	}
	fz_always(ctx)
	{
		fz_drop_stream(ctx, stm);
	}
	fz_catch(ctx)
	{
		fz_rethrow_message(ctx, "cannot read raw stream (%d %d R)", num, gen);
	}

	return buf;
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
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;
}
Exemplo n.º 9
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)
Exemplo n.º 10
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)
Exemplo n.º 11
0
static fz_colorspace *
load_icc_based(pdf_document *xref, pdf_obj *dict)
{
	int n;

	n = pdf_to_int(pdf_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.º 12
0
void
pdf_delete_page(pdf_document *doc, int at)
{
	pdf_obj *parent, *kids;
	int i;

	pdf_lookup_page_loc(doc, at, &parent, &i);
	kids = pdf_dict_gets(parent, "Kids");
	pdf_array_delete(kids, i);

	while (parent)
	{
		int count = pdf_to_int(pdf_dict_gets(parent, "Count"));
		pdf_dict_puts_drop(parent, "Count", pdf_new_int(doc, count - 1));
		parent = pdf_dict_gets(parent, "Parent");
	}
}
Exemplo n.º 13
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;
}
Exemplo n.º 14
0
Arquivo: data.c Projeto: 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();
  
}
Exemplo n.º 15
0
fz_buffer *
pdf_load_image_stream(pdf_document *xref, int num, int gen, int orig_num, int orig_gen, pdf_image_params *params)
{
	fz_context *ctx = xref->ctx;
	fz_stream *stm = NULL;
	pdf_obj *dict, *obj;
	int i, len, n;
	fz_buffer *buf;

	fz_var(buf);

	if (num > 0 && num < xref->len && xref->table[num].stm_buf)
		return fz_keep_buffer(xref->ctx, xref->table[num].stm_buf);

	dict = pdf_load_object(xref, num, gen);
	/* RJW: "cannot load stream dictionary (%d %d R)", num, gen */

	len = pdf_to_int(pdf_dict_gets(dict, "Length"));
	obj = pdf_dict_gets(dict, "Filter");
	len = pdf_guess_filter_length(len, pdf_to_name(obj));
	n = pdf_array_len(obj);
	for (i = 0; i < n; i++)
		len = pdf_guess_filter_length(len, pdf_to_name(pdf_array_get(obj, i)));

	pdf_drop_obj(dict);

	stm = pdf_open_image_stream(xref, num, gen, orig_num, orig_gen, params);
	/* RJW: "cannot open stream (%d %d R)", num, gen */

	fz_try(ctx)
	{
		buf = fz_read_all(stm, len);
	}
	fz_always(ctx)
	{
		fz_close(stm);
	}
	fz_catch(ctx)
	{
		fz_throw(ctx, "cannot read raw stream (%d %d R)", num, gen);
	}

	return buf;
}
Exemplo n.º 16
0
static fz_colorspace *
load_icc_based(pdf_document *doc, pdf_obj *dict)
{
	int n;
	pdf_obj *obj;
	fz_context *ctx = doc->ctx;

	n = pdf_to_int(pdf_dict_gets(dict, "N"));
	obj = pdf_dict_gets(dict, "Alternate");

	if (obj)
	{
		fz_colorspace *cs_alt = NULL;

		fz_try(ctx)
		{
			cs_alt = pdf_load_colorspace(doc, obj);
			if (cs_alt->n != n)
			{
				fz_drop_colorspace(ctx, cs_alt);
				fz_throw(ctx, FZ_ERROR_GENERIC, "ICCBased /Alternate colorspace must have %d components", n);
			}
		}
		fz_catch(ctx)
		{
			cs_alt = NULL;
		}

		if (cs_alt)
			return cs_alt;
	}

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

	fz_throw(ctx, FZ_ERROR_GENERIC, "syntaxerror: ICCBased must have 1, 3 or 4 components");
}
Exemplo n.º 17
0
void pdf_set_text_annot_position(fz_context *ctx, pdf_document *doc, pdf_annot *annot, fz_point pt)
{
	fz_matrix ctm;
	fz_rect rect;
	int flags;

	fz_invert_matrix(&ctm, &annot->page->ctm);
	rect.x0 = pt.x;
	rect.x1 = pt.x + TEXT_ANNOT_SIZE;
	rect.y0 = pt.y;
	rect.y1 = pt.y + TEXT_ANNOT_SIZE;
	fz_transform_rect(&rect, &ctm);

	pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_Rect, pdf_new_rect(ctx, doc, &rect));

	flags = pdf_to_int(ctx, pdf_dict_get(ctx, annot->obj, PDF_NAME_F));
	flags |= (F_NoZoom|F_NoRotate);
	pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_F, pdf_new_int(ctx, doc, flags));

	update_rect(ctx, annot);
}
Exemplo n.º 18
0
pdfout_data *
pdfout_page_labels_get (fz_context *ctx, pdf_document *doc)
{
  pdf_obj *trailer = pdf_trailer (ctx, doc);
  pdf_obj *labels_obj = pdf_dict_getp (ctx, trailer, "Root/PageLabels");
  pdf_obj *array = pdf_dict_gets (ctx, labels_obj, "Nums");

  if (array && pdf_is_array (ctx, array) == false)
    pdfout_throw (ctx, "Nums is not an array");
		  
  int length = pdf_array_len (ctx, array);

  pdfout_data *labels = pdfout_data_array_new (ctx);

  for (int i = 0; i < length / 2; ++i)
    {
      pdf_obj *object = pdf_array_get (ctx, array, 2 * i);
      
      if (pdf_is_int (ctx, object) == false)
	pdfout_throw (ctx, "key in number tree not an int");

      pdfout_data *hash = pdfout_data_hash_new (ctx);
      
      int page = pdf_to_int (ctx, object);
      if (page < 0)
	pdfout_throw (ctx, "key in number tree is < 0");

      push_int_key (ctx, hash, "page", page);
      
      pdf_obj *dict = pdf_array_get (ctx, array, 2 * i + 1);
      if (pdf_is_dict (ctx, dict) == false)
	pdfout_throw (ctx, "value in number tree not a dict");

      parse_dict (ctx, dict, hash);
      
      pdfout_data_array_push (ctx, labels, hash);
    }
  
  return labels;
}
Exemplo n.º 19
0
void pdf_set_text_annot_position(fz_context *ctx, pdf_annot *annot, fz_point pt)
{
	pdf_document *doc = annot->page->doc;
	fz_matrix page_ctm, inv_page_ctm;
	fz_rect rect;
	int flags;

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

	rect.x0 = pt.x;
	rect.x1 = pt.x + TEXT_ANNOT_SIZE;
	rect.y0 = pt.y;
	rect.y1 = pt.y + TEXT_ANNOT_SIZE;
	fz_transform_rect(&rect, &inv_page_ctm);

	pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_Rect, pdf_new_rect(ctx, doc, &rect));

	flags = pdf_to_int(ctx, pdf_dict_get(ctx, annot->obj, PDF_NAME_F));
	flags |= (PDF_ANNOT_IS_NO_ZOOM|PDF_ANNOT_IS_NO_ROTATE);
	pdf_dict_put_drop(ctx, annot->obj, PDF_NAME_F, pdf_new_int(ctx, doc, flags));
}
Exemplo n.º 20
0
static void execute_action(fz_context *ctx, pdf_document *doc, pdf_obj *obj, pdf_obj *a)
{
    if (a)
    {
        pdf_obj *type = pdf_dict_get(ctx, a, PDF_NAME_S);

        if (pdf_name_eq(ctx, type, PDF_NAME_JavaScript))
        {
            pdf_obj *js = pdf_dict_get(ctx, a, PDF_NAME_JS);
            if (js)
            {
                char *code = pdf_to_utf8(ctx, doc, js);
                fz_try(ctx)
                {
                    pdf_js_execute(doc->js, code);
                }
                fz_always(ctx)
                {
                    fz_free(ctx, code);
                }
                fz_catch(ctx)
                {
                    fz_rethrow(ctx);
                }
            }
        }
        else if (pdf_name_eq(ctx, type, PDF_NAME_ResetForm))
        {
            reset_form(ctx, doc, pdf_dict_get(ctx, a, PDF_NAME_Fields), pdf_to_int(ctx, pdf_dict_get(ctx, a, PDF_NAME_Flags)) & 1);
        }
        else if (pdf_name_eq(ctx, type, PDF_NAME_Named))
        {
            pdf_obj *name = pdf_dict_get(ctx, a, PDF_NAME_N);

            if (pdf_name_eq(ctx, name, PDF_NAME_Print))
                pdf_event_issue_print(ctx, doc);
        }
    }
Exemplo n.º 21
0
void
pdf_insert_page(pdf_document *doc, pdf_page *page, int at)
{
	int count = pdf_count_pages(doc);
	pdf_obj *parent, *kids;
	int i;

	if (count == 0)
	{
		/* TODO: create new page tree? */
		fz_throw(doc->ctx, FZ_ERROR_GENERIC, "empty page tree, cannot insert page");
	}
	else if (at >= count)
	{
		if (at > count)
			fz_throw(doc->ctx, FZ_ERROR_GENERIC, "cannot insert page beyond end of page tree");

		/* append after last page */
		pdf_lookup_page_loc(doc, count - 1, &parent, &i);
		kids = pdf_dict_gets(parent, "Kids");
		pdf_array_insert_drop(kids, pdf_new_ref(doc, page->me), i + 1);
	}
	else
	{
		/* insert before found page */
		pdf_lookup_page_loc(doc, at, &parent, &i);
		kids = pdf_dict_gets(parent, "Kids");
		pdf_array_insert_drop(kids, pdf_new_ref(doc, page->me), i);
	}

	/* Adjust page counts */
	while (parent)
	{
		int count = pdf_to_int(pdf_dict_gets(parent, "Count"));
		pdf_dict_puts_drop(parent, "Count", pdf_new_int(doc, count + 1));
		parent = pdf_dict_gets(parent, "Parent");
	}
}
Exemplo n.º 22
0
static int
pdf_count_pages_before_kid(pdf_document *doc, pdf_obj *parent, int kid_num)
{
	pdf_obj *kids = pdf_dict_gets(parent, "Kids");
	int i, total = 0, len = pdf_array_len(kids);
	for (i = 0; i < len; i++)
	{
		pdf_obj *kid = pdf_array_get(kids, i);
		if (pdf_to_num(kid) == kid_num)
			return total;
		if (!strcmp(pdf_to_name(pdf_dict_gets(kid, "Type")), "Pages"))
		{
			pdf_obj *count = pdf_dict_gets(kid, "Count");
			int n = pdf_to_int(count);
			if (count == NULL || n <= 0)
				fz_throw(doc->ctx, FZ_ERROR_GENERIC, "illegal or missing count in pages tree");
			total += n;
		}
		else
			total++;
	}
	fz_throw(doc->ctx, FZ_ERROR_GENERIC, "kid not found in parent's kids array");
}
Exemplo n.º 23
0
/*
 * Load raw (compressed but decrypted) contents of a stream into buf.
 */
fz_buffer *
pdf_load_raw_stream(pdf_document *xref, int num, int gen)
{
    fz_stream *stm;
    pdf_obj *dict;
    int len;
    fz_buffer *buf;

    dict = pdf_load_object(xref, num, gen);
    /* RJW: "cannot load stream dictionary (%d %d R)", num, gen */

    len = pdf_to_int(pdf_dict_gets(dict, "Length"));

    pdf_drop_obj(dict);

    stm = pdf_open_raw_stream(xref, num, gen);
    /* RJW: "cannot open raw stream (%d %d R)", num, gen */

    buf = fz_read_all(stm, len);
    /* RJW: "cannot read raw stream (%d %d R)", num, gen */

    fz_close(stm);
    return buf;
}
Exemplo n.º 24
0
static pdf_font_desc *
load_cid_font(pdf_document *xref, pdf_obj *dict, pdf_obj *encoding, pdf_obj *to_unicode)
{
	pdf_obj *widths;
	pdf_obj *descriptor;
	pdf_font_desc *fontdesc = NULL;
	FT_Face face;
	int kind;
	char collection[256];
	char *basefont;
	int i, k, fterr;
	pdf_obj *obj;
	int dw;
	fz_context *ctx = xref->ctx;

	fz_var(fontdesc);

	fz_try(ctx)
	{
		/* Get font name and CID collection */

		basefont = pdf_to_name(pdf_dict_gets(dict, "BaseFont"));

		{
			pdf_obj *cidinfo;
			char tmpstr[64];
			int tmplen;

			cidinfo = pdf_dict_gets(dict, "CIDSystemInfo");
			if (!cidinfo)
				fz_throw(ctx, "cid font is missing info");

			obj = pdf_dict_gets(cidinfo, "Registry");
			tmplen = fz_mini(sizeof tmpstr - 1, pdf_to_str_len(obj));
			memcpy(tmpstr, pdf_to_str_buf(obj), tmplen);
			tmpstr[tmplen] = '\0';
			fz_strlcpy(collection, tmpstr, sizeof collection);

			fz_strlcat(collection, "-", sizeof collection);

			obj = pdf_dict_gets(cidinfo, "Ordering");
			tmplen = fz_mini(sizeof tmpstr - 1, pdf_to_str_len(obj));
			memcpy(tmpstr, pdf_to_str_buf(obj), tmplen);
			tmpstr[tmplen] = '\0';
			fz_strlcat(collection, tmpstr, sizeof collection);
		}

		/* Load font file */

		fontdesc = pdf_new_font_desc(ctx);

		descriptor = pdf_dict_gets(dict, "FontDescriptor");
		if (!descriptor)
			fz_throw(ctx, "syntaxerror: missing font descriptor");
		pdf_load_font_descriptor(fontdesc, xref, descriptor, collection, basefont);

		face = fontdesc->font->ft_face;
		kind = ft_kind(face);

		/* Encoding */

		if (pdf_is_name(encoding))
		{
			if (!strcmp(pdf_to_name(encoding), "Identity-H"))
				fontdesc->encoding = pdf_new_identity_cmap(ctx, 0, 2);
			else if (!strcmp(pdf_to_name(encoding), "Identity-V"))
				fontdesc->encoding = pdf_new_identity_cmap(ctx, 1, 2);
			else
				fontdesc->encoding = pdf_load_system_cmap(ctx, pdf_to_name(encoding));
		}
		else if (pdf_is_indirect(encoding))
		{
			fontdesc->encoding = pdf_load_embedded_cmap(xref, encoding);
		}
		else
		{
			fz_throw(ctx, "syntaxerror: font missing encoding");
		}
		fontdesc->size += pdf_cmap_size(ctx, fontdesc->encoding);

		pdf_set_font_wmode(ctx, fontdesc, pdf_cmap_wmode(ctx, fontdesc->encoding));

		if (kind == TRUETYPE)
		{
			pdf_obj *cidtogidmap;

			cidtogidmap = pdf_dict_gets(dict, "CIDToGIDMap");
			if (pdf_is_indirect(cidtogidmap))
			{
				fz_buffer *buf;

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

				fontdesc->cid_to_gid_len = (buf->len) / 2;
				fontdesc->cid_to_gid = fz_malloc_array(ctx, fontdesc->cid_to_gid_len, sizeof(unsigned short));
				fontdesc->size += fontdesc->cid_to_gid_len * sizeof(unsigned short);
				for (i = 0; i < fontdesc->cid_to_gid_len; i++)
					fontdesc->cid_to_gid[i] = (buf->data[i * 2] << 8) + buf->data[i * 2 + 1];

				fz_drop_buffer(ctx, buf);
			}

			/* if truetype font is external, cidtogidmap should not be identity */
			/* so we map from cid to unicode and then map that through the (3 1) */
			/* unicode cmap to get a glyph id */
			else if (fontdesc->font->ft_substitute)
			{
				fterr = FT_Select_Charmap(face, ft_encoding_unicode);
				if (fterr)
				{
					fz_throw(ctx, "fonterror: no unicode cmap when emulating CID font: %s", ft_error_string(fterr));
				}

				if (!strcmp(collection, "Adobe-CNS1"))
					fontdesc->to_ttf_cmap = pdf_load_system_cmap(ctx, "Adobe-CNS1-UCS2");
				else if (!strcmp(collection, "Adobe-GB1"))
					fontdesc->to_ttf_cmap = pdf_load_system_cmap(ctx, "Adobe-GB1-UCS2");
				else if (!strcmp(collection, "Adobe-Japan1"))
					fontdesc->to_ttf_cmap = pdf_load_system_cmap(ctx, "Adobe-Japan1-UCS2");
				else if (!strcmp(collection, "Adobe-Japan2"))
					fontdesc->to_ttf_cmap = pdf_load_system_cmap(ctx, "Adobe-Japan2-UCS2");
				else if (!strcmp(collection, "Adobe-Korea1"))
					fontdesc->to_ttf_cmap = pdf_load_system_cmap(ctx, "Adobe-Korea1-UCS2");
			}
		}

		pdf_load_to_unicode(xref, fontdesc, NULL, collection, to_unicode);

		/* Horizontal */

		dw = 1000;
		obj = pdf_dict_gets(dict, "DW");
		if (obj)
			dw = pdf_to_int(obj);
		pdf_set_default_hmtx(ctx, fontdesc, dw);

		widths = pdf_dict_gets(dict, "W");
		if (widths)
		{
			int c0, c1, w, n, m;

			n = pdf_array_len(widths);
			for (i = 0; i < n; )
			{
				c0 = pdf_to_int(pdf_array_get(widths, i));
				obj = pdf_array_get(widths, i + 1);
				if (pdf_is_array(obj))
				{
					m = pdf_array_len(obj);
					for (k = 0; k < m; k++)
					{
						w = pdf_to_int(pdf_array_get(obj, k));
						pdf_add_hmtx(ctx, fontdesc, c0 + k, c0 + k, w);
					}
					i += 2;
				}
				else
				{
					c1 = pdf_to_int(obj);
					w = pdf_to_int(pdf_array_get(widths, i + 2));
					pdf_add_hmtx(ctx, fontdesc, c0, c1, w);
					i += 3;
				}
			}
		}

		pdf_end_hmtx(ctx, fontdesc);

		/* Vertical */

		if (pdf_cmap_wmode(ctx, fontdesc->encoding) == 1)
		{
			int dw2y = 880;
			int dw2w = -1000;

			obj = pdf_dict_gets(dict, "DW2");
			if (obj)
			{
				dw2y = pdf_to_int(pdf_array_get(obj, 0));
				dw2w = pdf_to_int(pdf_array_get(obj, 1));
			}

			pdf_set_default_vmtx(ctx, fontdesc, dw2y, dw2w);

			widths = pdf_dict_gets(dict, "W2");
			if (widths)
			{
				int c0, c1, w, x, y, n;

				n = pdf_array_len(widths);
				for (i = 0; i < n; )
				{
					c0 = pdf_to_int(pdf_array_get(widths, i));
					obj = pdf_array_get(widths, i + 1);
					if (pdf_is_array(obj))
					{
						int m = pdf_array_len(obj);
						for (k = 0; k * 3 < m; k ++)
						{
							w = pdf_to_int(pdf_array_get(obj, k * 3 + 0));
							x = pdf_to_int(pdf_array_get(obj, k * 3 + 1));
							y = pdf_to_int(pdf_array_get(obj, k * 3 + 2));
							pdf_add_vmtx(ctx, fontdesc, c0 + k, c0 + k, x, y, w);
						}
						i += 2;
					}
					else
					{
						c1 = pdf_to_int(obj);
						w = pdf_to_int(pdf_array_get(widths, i + 2));
						x = pdf_to_int(pdf_array_get(widths, i + 3));
						y = pdf_to_int(pdf_array_get(widths, i + 4));
						pdf_add_vmtx(ctx, fontdesc, c0, c1, x, y, w);
						i += 5;
					}
				}
			}

			pdf_end_vmtx(ctx, fontdesc);
		}
	}
	fz_catch(ctx)
	{
		pdf_drop_font(ctx, fontdesc);
		fz_throw(ctx, "cannot load cid font (%d %d R)", pdf_to_num(dict), pdf_to_gen(dict));
	}

	return fontdesc;
}
Exemplo n.º 25
0
static pdf_font_desc *
pdf_load_simple_font(pdf_document *xref, pdf_obj *dict)
{
	pdf_obj *descriptor;
	pdf_obj *encoding;
	pdf_obj *widths;
	unsigned short *etable = NULL;
	pdf_font_desc *fontdesc = NULL;
	char *subtype;
	FT_Face face;
	FT_CharMap cmap;
	int symbolic;
	int kind;

	char *basefont;
	char *estrings[256];
	char ebuffer[256][32];
	int i, k, n;
	int fterr;
	fz_context *ctx = xref->ctx;

	fz_var(fontdesc);
	fz_var(etable);

	basefont = pdf_to_name(pdf_dict_gets(dict, "BaseFont"));

	/* Load font file */
	fz_try(ctx)
	{
		fontdesc = pdf_new_font_desc(ctx);

		descriptor = pdf_dict_gets(dict, "FontDescriptor");
		if (descriptor)
			pdf_load_font_descriptor(fontdesc, xref, descriptor, NULL, basefont);
		else
			pdf_load_builtin_font(ctx, fontdesc, basefont);

		/* Some chinese documents mistakenly consider WinAnsiEncoding to be codepage 936 */
		if (descriptor && pdf_is_string(pdf_dict_gets(descriptor, "FontName")) &&
			!pdf_dict_gets(dict, "ToUnicode") &&
			!strcmp(pdf_to_name(pdf_dict_gets(dict, "Encoding")), "WinAnsiEncoding") &&
			pdf_to_int(pdf_dict_gets(descriptor, "Flags")) == 4)
		{
			char *cp936fonts[] = {
				"\xCB\xCE\xCC\xE5", "SimSun,Regular",
				"\xBA\xDA\xCC\xE5", "SimHei,Regular",
				"\xBF\xAC\xCC\xE5_GB2312", "SimKai,Regular",
				"\xB7\xC2\xCB\xCE_GB2312", "SimFang,Regular",
				"\xC1\xA5\xCA\xE9", "SimLi,Regular",
				NULL
			};
			for (i = 0; cp936fonts[i]; i += 2)
				if (!strcmp(basefont, cp936fonts[i]))
					break;
			if (cp936fonts[i])
			{
				fz_warn(ctx, "workaround for S22PDF lying about chinese font encodings");
				pdf_drop_font(ctx, fontdesc);
				fontdesc = pdf_new_font_desc(ctx);
				pdf_load_font_descriptor(fontdesc, xref, descriptor, "Adobe-GB1", cp936fonts[i+1]);
				fontdesc->encoding = pdf_load_system_cmap(ctx, "GBK-EUC-H");
				fontdesc->to_unicode = pdf_load_system_cmap(ctx, "Adobe-GB1-UCS2");
				fontdesc->to_ttf_cmap = pdf_load_system_cmap(ctx, "Adobe-GB1-UCS2");

				face = fontdesc->font->ft_face;
				kind = ft_kind(face);
				goto skip_encoding;
			}
		}

		face = fontdesc->font->ft_face;
		kind = ft_kind(face);

		/* Encoding */

		symbolic = fontdesc->flags & 4;

		if (face->num_charmaps > 0)
			cmap = face->charmaps[0];
		else
			cmap = NULL;

		for (i = 0; i < face->num_charmaps; i++)
		{
			FT_CharMap test = face->charmaps[i];

			if (kind == TYPE1)
			{
				if (test->platform_id == 7)
					cmap = test;
			}

			if (kind == TRUETYPE)
			{
				if (test->platform_id == 1 && test->encoding_id == 0)
					cmap = test;
				if (test->platform_id == 3 && test->encoding_id == 1)
					cmap = test;
				if (symbolic && test->platform_id == 3 && test->encoding_id == 0)
					cmap = test;
			}
		}

		if (cmap)
		{
			fterr = FT_Set_Charmap(face, cmap);
			if (fterr)
				fz_warn(ctx, "freetype could not set cmap: %s", ft_error_string(fterr));
		}
		else
			fz_warn(ctx, "freetype could not find any cmaps");

		etable = fz_malloc_array(ctx, 256, sizeof(unsigned short));
		fontdesc->size += 256 * sizeof(unsigned short);
		for (i = 0; i < 256; i++)
		{
			estrings[i] = NULL;
			etable[i] = 0;
		}

		encoding = pdf_dict_gets(dict, "Encoding");
		if (encoding)
		{
			if (pdf_is_name(encoding))
				pdf_load_encoding(estrings, pdf_to_name(encoding));

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

				base = pdf_dict_gets(encoding, "BaseEncoding");
				if (pdf_is_name(base))
					pdf_load_encoding(estrings, pdf_to_name(base));
				else if (!fontdesc->is_embedded && !symbolic)
					pdf_load_encoding(estrings, "StandardEncoding");

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

		/* start with the builtin encoding */
		for (i = 0; i < 256; i++)
			etable[i] = ft_char_index(face, i);

		fz_lock(ctx, FZ_LOCK_FREETYPE);

		/* built-in and substitute fonts may be a different type than what the document expects */
		subtype = pdf_to_name(pdf_dict_gets(dict, "Subtype"));
		if (!strcmp(subtype, "Type1"))
			kind = TYPE1;
		else if (!strcmp(subtype, "MMType1"))
			kind = TYPE1;
		else if (!strcmp(subtype, "TrueType"))
			kind = TRUETYPE;
		else if (!strcmp(subtype, "CIDFontType0"))
			kind = TYPE1;
		else if (!strcmp(subtype, "CIDFontType2"))
			kind = TRUETYPE;

		/* encode by glyph name where we can */
		if (kind == TYPE1)
		{
			for (i = 0; i < 256; i++)
			{
				if (estrings[i])
				{
					etable[i] = FT_Get_Name_Index(face, estrings[i]);
					if (etable[i] == 0)
					{
						int aglcode = pdf_lookup_agl(estrings[i]);
						const char **dupnames = pdf_lookup_agl_duplicates(aglcode);
						while (*dupnames)
						{
							etable[i] = FT_Get_Name_Index(face, (char*)*dupnames);
							if (etable[i])
								break;
							dupnames++;
						}
					}
				}
			}
		}

		/* encode by glyph name where we can */
		if (kind == TRUETYPE)
		{
			/* Unicode cmap */
			if (!symbolic && face->charmap && face->charmap->platform_id == 3)
			{
				for (i = 0; i < 256; i++)
				{
					if (estrings[i])
					{
						int aglcode = pdf_lookup_agl(estrings[i]);
						if (!aglcode)
							etable[i] = FT_Get_Name_Index(face, estrings[i]);
						else
							etable[i] = ft_char_index(face, aglcode);
					}
				}
			}

			/* MacRoman cmap */
			else if (!symbolic && face->charmap && face->charmap->platform_id == 1)
			{
				for (i = 0; i < 256; i++)
				{
					if (estrings[i])
					{
						k = lookup_mre_code(estrings[i]);
						if (k <= 0)
							etable[i] = FT_Get_Name_Index(face, estrings[i]);
						else
							etable[i] = ft_char_index(face, k);
					}
				}
			}

			/* Symbolic cmap */
			else if (!face->charmap || face->charmap->encoding != FT_ENCODING_MS_SYMBOL)
			{
				for (i = 0; i < 256; i++)
				{
					if (estrings[i])
					{
						etable[i] = FT_Get_Name_Index(face, estrings[i]);
						if (etable[i] == 0)
							etable[i] = ft_char_index(face, i);
					}
				}
			}
		}

		/* try to reverse the glyph names from the builtin encoding */
		for (i = 0; i < 256; i++)
		{
			if (etable[i] && !estrings[i])
			{
				if (FT_HAS_GLYPH_NAMES(face))
				{
					fterr = FT_Get_Glyph_Name(face, etable[i], ebuffer[i], 32);
					if (fterr)
						fz_warn(ctx, "freetype get glyph name (gid %d): %s", etable[i], ft_error_string(fterr));
					if (ebuffer[i][0])
						estrings[i] = ebuffer[i];
				}
				else
				{
					estrings[i] = (char*) pdf_win_ansi[i]; /* discard const */
				}
			}
		}

		/* symbolic Type 1 fonts with an implicit encoding and non-standard glyph names */
		if (kind == TYPE1 && symbolic)
		{
			for (i = 0; i < 256; i++)
				if (etable[i] && estrings[i] && !pdf_lookup_agl(estrings[i]))
					estrings[i] = (char*) pdf_standard[i];
		}

		fz_unlock(ctx, FZ_LOCK_FREETYPE);

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

		fz_try(ctx)
		{
			pdf_load_to_unicode(xref, fontdesc, estrings, NULL, pdf_dict_gets(dict, "ToUnicode"));
		}
		fz_catch(ctx)
		{
			fz_warn(ctx, "cannot load ToUnicode CMap");
		}

	skip_encoding:

		/* Widths */

		pdf_set_default_hmtx(ctx, fontdesc, fontdesc->missing_width);

		widths = pdf_dict_gets(dict, "Widths");
		if (widths)
		{
			int first, last;

			first = pdf_to_int(pdf_dict_gets(dict, "FirstChar"));
			last = pdf_to_int(pdf_dict_gets(dict, "LastChar"));

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

			for (i = 0; i < last - first + 1; i++)
			{
				int wid = pdf_to_int(pdf_array_get(widths, i));
				pdf_add_hmtx(ctx, fontdesc, i + first, i + first, wid);
			}
		}
		else
		{
			fz_lock(ctx, FZ_LOCK_FREETYPE);
			fterr = FT_Set_Char_Size(face, 1000, 1000, 72, 72);
			if (fterr)
				fz_warn(ctx, "freetype set character size: %s", ft_error_string(fterr));
			for (i = 0; i < 256; i++)
			{
				pdf_add_hmtx(ctx, fontdesc, i, i, ft_width(ctx, fontdesc, i));
			}
			fz_unlock(ctx, FZ_LOCK_FREETYPE);
		}

		pdf_end_hmtx(ctx, fontdesc);
	}
	fz_catch(ctx)
	{
		if (fontdesc && etable != fontdesc->cid_to_gid)
			fz_free(ctx, etable);
		pdf_drop_font(ctx, fontdesc);
		fz_throw(ctx, "cannot load simple font (%d %d R)", pdf_to_num(dict), pdf_to_gen(dict));
	}
	return fontdesc;
}
Exemplo n.º 26
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;
}
Exemplo n.º 27
0
static fz_colorspace *
load_indexed(pdf_document *xref, pdf_obj *array)
{
	struct indexed *idx = NULL;
	fz_context *ctx = xref->ctx;
	pdf_obj *baseobj = pdf_array_get(array, 1);
	pdf_obj *highobj = pdf_array_get(array, 2);
	pdf_obj *lookup = pdf_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)", pdf_to_num(baseobj), pdf_to_gen(baseobj) */

		idx = fz_malloc_struct(ctx, struct indexed);
		idx->lookup = NULL;
		idx->base = base;
		idx->high = pdf_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 (pdf_is_string(lookup) && pdf_to_str_len(lookup) == n)
		{
			unsigned char *buf = (unsigned char *) pdf_to_str_buf(lookup);
			for (i = 0; i < n; i++)
				idx->lookup[i] = buf[i];
		}
		else if (pdf_is_indirect(lookup))
		{
			fz_stream *file = NULL;

			fz_try(ctx)
			{
				file = pdf_open_stream(xref, pdf_to_num(lookup), pdf_to_gen(lookup));
			}
			fz_catch(ctx)
			{
				fz_throw(ctx, "cannot open colorspace lookup table (%d 0 R)", pdf_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)", pdf_to_num(lookup));
			}

			fz_close(file);
		}
		else
		{
			fz_throw(ctx, "cannot parse colorspace lookup table");
		}
	}
Exemplo n.º 28
0
				{
					pdf_js_execute(doc->js, code);
				}
				fz_always(ctx)
				{
					fz_free(ctx, code);
				}
				fz_catch(ctx)
				{
					fz_rethrow(ctx);
				}
			}
		}
		else if (!strcmp(type, "ResetForm"))
		{
			reset_form(doc, pdf_dict_gets(a, "Fields"), pdf_to_int(pdf_dict_gets(a, "Flags")) & 1);
		}
		else if (!strcmp(type, "Named"))
		{
			char *name = pdf_to_name(pdf_dict_gets(a, "N"));

			if (!strcmp(name, "Print"))
				pdf_event_issue_print(doc);
		}
	}
}

void pdf_update_appearance(pdf_document *doc, pdf_annot *annot)
{
	pdf_obj *obj = annot->obj;
	if (!pdf_dict_gets(obj, "AP") || pdf_obj_is_dirty(obj))
Exemplo n.º 29
0
pdf_err
pdf_encrypt_load(pdf_obj *o, pdf_encrypt **encrypt)
{
    pdf_obj *a;
    pdf_encrypt *e;
    if (!o)
        return pdf_ok;
    pdf_obj_resolve(o);
    if (!o)
        return pdf_ok;
    *encrypt = pdf_malloc(sizeof(pdf_encrypt));
    if (!*encrypt)
        return pdf_mem_err;
    memset(*encrypt, 0, sizeof(pdf_encrypt));
    e = *encrypt;
    e->v = 0;
    a = pdf_dict_get(o, "Filter");
    if (a)
    {
        pdf_obj_resolve(a);
        (*encrypt)->filter = pdf_malloc(strlen(a->value.k)+1);
        memcpy((*encrypt)->filter, a->value.k, strlen(a->value.k));
        (*encrypt)->filter[strlen(a->value.k)] = 0;
    }
    a = pdf_dict_get(o, "SubFilter");
    if (a)
    {
        pdf_obj_resolve(a);
        (*encrypt)->subfilter = pdf_malloc(strlen(a->value.k)+1);
        memcpy((*encrypt)->subfilter, a->value.k, strlen(a->value.k));
        (*encrypt)->subfilter[strlen(a->value.k)] = 0;
    }
    a = pdf_dict_get(o, "V");
    if (a)
    {
        (*encrypt)->v = pdf_to_int(a);
    }
    e->length = 40;
    a = pdf_dict_get(o, "Length");
    if (a)
    {
        (*encrypt)->length = pdf_to_int(a);
    }
    if (e->v == 4)
    {
        pdf_obj *cf = pdf_dict_get(o, "CF");
        if (cf)
        {
            a = pdf_dict_get(o, "StmF");
            if (a)
            {
                pdf_obj_resolve(a);
                pdf_cf_load(e, cf, a->value.k, &e->stmf);
            }
            a = pdf_dict_get(o, "StrF");
            if (a)
            {
                pdf_obj_resolve(a);
                pdf_cf_load(e, cf, a->value.k, &e->strf);
            }
            a = pdf_dict_get(o, "EFF");
            if (a)
            {
                pdf_obj_resolve(a);
                pdf_cf_load(e, cf, a->value.k, &e->eff);
            }
        }
    }

    // standard encryption dictionary (items)
    a = pdf_dict_get(o, "R");
    if (a)
    {
        (*encrypt)->r = pdf_to_int(a);
    }
    a = pdf_dict_get(o, "O"); // owner password
    if (a)
    {
        // should verify length to 32 bytes
        pdf_obj_resolve(a);
        memcpy((*encrypt)->o, a->value.s.buf, a->value.s.len);
    }
    a = pdf_dict_get(o, "U"); // user password
    if (a)
    {
        // should verify length to 32 bytes
        pdf_obj_resolve(a);
        memcpy((*encrypt)->u, a->value.s.buf, a->value.s.len);
    }
    a = pdf_dict_get(o, "P"); // permission flags
    if (a)
    {
        (*encrypt)->p = pdf_to_int(a);
    }
    a = pdf_dict_get(o, "EncryptMetadata");
    if (a)
    {
        pdf_obj_resolve(a);
        (*encrypt)->encrypt_metadata = a->value.b;
    }

    return pdf_ok;
}
Exemplo n.º 30
0
pdf_err pdf_page_load(pdf_doc *doc, pdf_obj *o, pdf_page **page)
{
    pdf_page *p;
    pdf_obj *mediabox;
    pdf_obj *v;

    if (o->t != eRef)
        return pdf_syntax_err;
    *page = pdf_malloc(sizeof(pdf_page));
    p = *page;
    memset(p, 0, sizeof(pdf_page));
    p->ref = *o;
    // parse tree dict
    p->parent = pdf_dict_get(o, "Parent");
    mediabox = pdf_dict_get(o, "MediaBox");
    if (mediabox)
        p->mediabox = pdf_rect_get(mediabox);
    else
    {
        gs_rect *r = doc->get_mediabox(doc);
        if (r)
            p->mediabox = *r;
    }
    p->resources = pdf_resources_load(pdf_dict_get(o, "Resources"));
    // optionals
    p->contents = pdf_dict_get(o, "Contents");
    v = (pdf_obj*)pdf_dict_get(o, "Rotate");
    if (v)
    {
        p->rotate = v->value.i;
        if (p->rotate < 0)
            p->rotate = 360 - ((-p->rotate) % 360);
        if (p->rotate >= 360)
            p->rotate = p->rotate % 360;
        p->rotate = 90*((p->rotate + 45)/90);
        if (p->rotate > 360)
            p->rotate = 0;
        if (p->rotate == 90 || p->rotate == 270)
        {
            float x = p->mediabox.y1;
            p->mediabox.y1 =  p->mediabox.x1;
            p->mediabox.x1 = x;
        }
    }
    p->group = pdf_group_load(pdf_dict_get(o, "Group"));
    p->cropbox = pdf_dict_get(o, "CropBox");
    p->bleedbox = pdf_dict_get(o, "BleedBox");
    p->trimbox = pdf_dict_get(o, "TrimBox");
    p->artbox = pdf_dict_get(o, "ArtBox");
    p->boxcolorinfo = pdf_dict_get(o, "BoxColorInfo");
    p->thumb = pdf_dict_get(o, "Thumb");
    p->b = pdf_dict_get(o, "b");
    p->dur = pdf_to_float(pdf_dict_get(o, "Dur"));
    p->trans = pdf_dict_get(o, "Trans");

    p->annots = pdf_annots_load(pdf_dict_get(o, "Annots"));
    p->aa = pdf_dict_get(o, "AA");

    p->metadata = pdf_dict_get(o, "Metadata");
    p->pieceinfo = pdf_dict_get(o, "PieceInfo");
    p->structparents = pdf_to_int(pdf_dict_get(o, "StructParents"));
    p->id = pdf_to_int(pdf_dict_get(o, "ID"));
    p->pz = pdf_to_float(pdf_dict_get(o, "PZ"));
    p->separationinfo = pdf_dict_get(o, "SeparationInfo");
    p->tabs = pdf_dict_get(o, "Tabs");
    p->templateinstantiated = pdf_dict_get(o, "TemplateInstantiated");
    p->pressteps = pdf_dict_get(o, "PresSteps");
    p->userunit = pdf_to_float(pdf_dict_get(o, "UserUnit"));
    p->vp = pdf_dict_get(o, "VP");
    // required depends
    p->lastmodified = pdf_dict_get(o, "LastModified");
    return pdf_ok;
}