static pdf_obj* pdf_get_page_content (pdf_obj* page) { pdf_obj *contents, *content_new; contents = pdf_deref_obj(pdf_lookup_dict(page, "Contents")); if (!contents) return NULL; if (pdf_obj_typeof(contents) == PDF_NULL) { /* empty page */ pdf_release_obj(contents); /* TODO: better don't include anything if the page is empty */ contents = pdf_new_stream(0); } else if (PDF_OBJ_ARRAYTYPE(contents)) { /* * Concatenate all content streams. */ pdf_obj *content_seg; int idx = 0; content_new = pdf_new_stream(STREAM_COMPRESS); for (;;) { content_seg = pdf_deref_obj(pdf_get_array(contents, idx)); if (!content_seg) break; else if (PDF_OBJ_NULLTYPE(content_seg)) { /* Silently ignore. */ } else if (!PDF_OBJ_STREAMTYPE(content_seg)) { WARN("Page content not a stream object. Broken PDF file?"); pdf_release_obj(content_seg); pdf_release_obj(content_new); pdf_release_obj(contents); return NULL; } else if (pdf_concat_stream(content_new, content_seg) < 0) { WARN("Could not handle content stream with multiple segments."); pdf_release_obj(content_seg); pdf_release_obj(content_new); pdf_release_obj(contents); return NULL; } pdf_release_obj(content_seg); idx++; } pdf_release_obj(contents); contents = content_new; } else { if (!PDF_OBJ_STREAMTYPE(contents)) { WARN("Page content not a stream object. Broken PDF file?"); pdf_release_obj(contents); return NULL; } /* Flate the contents if necessary. */ content_new = pdf_new_stream(STREAM_COMPRESS); if (pdf_concat_stream(content_new, contents) < 0) { WARN("Could not handle a content stream."); pdf_release_obj(contents); pdf_release_obj(content_new); return NULL; } pdf_release_obj(contents); contents = content_new; } return contents; }
static int CIDFont_base_open (CIDFont *font, const char *name, CIDSysInfo *cmap_csi, cid_opt *opt) { pdf_obj *fontdict, *descriptor; char *fontname = NULL; int idx; ASSERT(font); for (idx = 0; cid_basefont[idx].fontname != NULL; idx++) { if (!strcmp(name, cid_basefont[idx].fontname) || (strlen(name) == strlen(cid_basefont[idx].fontname) - strlen("-Acro") && !strncmp(name, cid_basefont[idx].fontname, strlen(cid_basefont[idx].fontname)-strlen("-Acro"))) ) break; } if (cid_basefont[idx].fontname == NULL) return -1; fontname = NEW(strlen(name)+12, char); memset(fontname, 0, strlen(name)+12); strcpy(fontname, name); switch (opt->style) { case FONT_STYLE_BOLD: strcat(fontname, ",Bold"); break; case FONT_STYLE_ITALIC: strcat(fontname, ",Italic"); break; case FONT_STYLE_BOLDITALIC: strcat(fontname, ",BoldItalic"); break; } { const char *start; const char *end; start = cid_basefont[idx].fontdict; end = start + strlen(start); fontdict = parse_pdf_dict(&start, end, NULL); start = cid_basefont[idx].descriptor; end = start + strlen(start); descriptor = parse_pdf_dict(&start, end, NULL); ASSERT(fontdict && descriptor); } font->fontname = fontname; font->flags |= FONT_FLAG_BASEFONT; { char *registry, *ordering; int supplement; pdf_obj *tmp; tmp = pdf_lookup_dict(fontdict, "CIDSystemInfo"); ASSERT( tmp && pdf_obj_typeof(tmp) == PDF_DICT ); registry = pdf_string_value(pdf_lookup_dict(tmp, "Registry")); ordering = pdf_string_value(pdf_lookup_dict(tmp, "Ordering")); supplement = pdf_number_value(pdf_lookup_dict(tmp, "Supplement")); if (cmap_csi) { /* NULL for accept any */ if (strcmp(registry, cmap_csi->registry) || strcmp(ordering, cmap_csi->ordering)) ERROR("Inconsistent CMap used for CID-keyed font %s.", cid_basefont[idx].fontname); else if (supplement < cmap_csi->supplement) { WARN("CMap has higher supplement number than CIDFont: %s", fontname); WARN("Some chracters may not be displayed or printed."); } } font->csi = NEW(1, CIDSysInfo); font->csi->registry = NEW(strlen(registry)+1, char); font->csi->ordering = NEW(strlen(ordering)+1, char); strcpy(font->csi->registry, registry); strcpy(font->csi->ordering, ordering); font->csi->supplement = supplement; } { pdf_obj *tmp; char *type; tmp = pdf_lookup_dict(fontdict, "Subtype"); ASSERT( tmp != NULL && pdf_obj_typeof(tmp) == PDF_NAME ); type = pdf_name_value(tmp); if (!strcmp(type, "CIDFontType0")) font->subtype = CIDFONT_TYPE0; else if (!strcmp(type, "CIDFontType2")) font->subtype = CIDFONT_TYPE2; else { ERROR("Unknown CIDFontType \"%s\"", type); } } if (cidoptflags & CIDFONT_FORCE_FIXEDPITCH) { if (pdf_lookup_dict(fontdict, "W")) { pdf_remove_dict(fontdict, "W"); } if (pdf_lookup_dict(fontdict, "W2")) { pdf_remove_dict(fontdict, "W2"); } } pdf_add_dict(fontdict, pdf_new_name("Type"), pdf_new_name("Font")); pdf_add_dict(fontdict, pdf_new_name("BaseFont"), pdf_new_name(fontname)); pdf_add_dict(descriptor, pdf_new_name("Type"), pdf_new_name("FontDescriptor")); pdf_add_dict(descriptor, pdf_new_name("FontName"), pdf_new_name(fontname)); font->fontdict = fontdict; font->descriptor = descriptor; opt->embed = 0; return 0; }