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; } }
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; }
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; } } }
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; }
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; } } }
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; }
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; }
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; }
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; }
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); }
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; } }
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; }
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; }
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; }
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(); }
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; }
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; }
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; }
/* ** 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.; }
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)
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)
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; }
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; }
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; }