diff options
Diffstat (limited to 'Build/source/texk/dvipdfmx/src/pdfdoc.c')
-rw-r--r-- | Build/source/texk/dvipdfmx/src/pdfdoc.c | 227 |
1 files changed, 114 insertions, 113 deletions
diff --git a/Build/source/texk/dvipdfmx/src/pdfdoc.c b/Build/source/texk/dvipdfmx/src/pdfdoc.c index 6b226ed08d6..087ca41e1ee 100644 --- a/Build/source/texk/dvipdfmx/src/pdfdoc.c +++ b/Build/source/texk/dvipdfmx/src/pdfdoc.c @@ -1,4 +1,4 @@ -/* $Header: /home/cvsroot/dvipdfmx/src/pdfdoc.c,v 1.65 2008/12/11 16:03:05 matthias Exp $ +/* $Header: /home/cvsroot/dvipdfmx/src/pdfdoc.c,v 1.70 2009/05/04 00:41:42 matthias Exp $ This is dvipdfmx, an eXtended version of dvipdfm by Mark A. Wicks. @@ -373,7 +373,7 @@ static void pdf_doc_close_page_tree (pdf_doc *p); static void pdf_doc_init_names (pdf_doc *p, int check_gotos); static void pdf_doc_close_names (pdf_doc *p); -static void pdf_doc_add_gotos (pdf_obj *annot_dict); +static void pdf_doc_add_goto (pdf_obj *annot_dict); static void pdf_doc_init_docinfo (pdf_doc *p); static void pdf_doc_close_docinfo (pdf_doc *p); @@ -929,33 +929,16 @@ pdf_doc_close_page_tree (pdf_doc *p) */ pdf_obj * -pdf_doc_get_page (pdf_obj *trailer, long *page_p, long *count_p, - pdf_rect *bbox, pdf_obj **resources_p, - pdf_obj **markinfo_p) { +pdf_doc_get_page (pdf_file *pf, long *page_p, long *count_p, + pdf_rect *bbox, pdf_obj **resources_p) { pdf_obj *page_tree = NULL; pdf_obj *resources = NULL, *box = NULL, *rotate = NULL; pdf_obj *catalog; long page_no = *page_p, page_idx; - if (pdf_lookup_dict(trailer, "Encrypt")) { - WARN("This PDF document is encrypted."); - pdf_release_obj(trailer); - goto error_silent; - } - - catalog = pdf_deref_obj(pdf_lookup_dict(trailer, "Root")); - pdf_release_obj(trailer); - if (!PDF_OBJ_DICTTYPE(catalog)) { - if (catalog) - pdf_release_obj(catalog); - goto error; - } - - if (markinfo_p) - *markinfo_p = pdf_deref_obj(pdf_lookup_dict(catalog, "MarkInfo")); + catalog = pdf_file_get_catalog(pf); page_tree = pdf_deref_obj(pdf_lookup_dict(catalog, "Pages")); - pdf_release_obj(catalog); if (!PDF_OBJ_DICTTYPE(page_tree)) goto error; @@ -1094,7 +1077,7 @@ pdf_doc_get_page (pdf_obj *trailer, long *page_p, long *count_p, { int i; - for (i = 4; --i; ) { + for (i = 4; i--; ) { double x; pdf_obj *tmp = pdf_deref_obj(pdf_get_array(box, i)); if (!PDF_OBJ_NUMBERTYPE(tmp)) { @@ -1382,7 +1365,7 @@ pdf_doc_bookmarks_add (pdf_obj *dict, int is_open) p->outlines.current = item; - pdf_doc_add_gotos(dict); + pdf_doc_add_goto(dict); return; } @@ -1475,63 +1458,54 @@ pdf_doc_add_names (const char *category, } static void -pdf_doc_add_gotos (pdf_obj *annot_dict) +pdf_doc_add_goto (pdf_obj *annot_dict) { - pdf_obj *subtype, *A, *S, *D = NULL, *tmp; - char *dest; + pdf_obj *subtype = NULL, *A = NULL, *S = NULL, *D = NULL, *D_new, *dict; + char *dest, *key; if (!pdoc.check_gotos) return; /* - * We cannot use pdf_deref_obj because if it return NULL - * we don't know whether a dictionary does not exist - * or has been declared as @foo and not yet defined. (As - * long as @foo is undefined, it is stored as "null" object.) - */ - - /* * An annotation dictionary coming from an annotation special * must have a "Subtype". An annotation dictionary coming from * an outline special has none. */ - subtype = pdf_lookup_dict(annot_dict, "Subtype"); - if (PDF_OBJ_INDIRECTTYPE(subtype)) - goto indirect; - else if (subtype && !PDF_OBJ_NULLTYPE(subtype)) { - if (!PDF_OBJ_NAMETYPE(subtype)) + subtype = pdf_deref_obj(pdf_lookup_dict(annot_dict, "Subtype")); + if (subtype) { + if (PDF_OBJ_UNDEFINED(subtype)) + goto undefined; + else if (!PDF_OBJ_NAMETYPE(subtype)) goto error; else if (strcmp(pdf_name_value(subtype), "Link")) - return; + goto cleanup; } - A = pdf_lookup_dict(annot_dict, "A"); - if (PDF_OBJ_DICTTYPE(A)) { - S = pdf_lookup_dict(A, "S"); - if (PDF_OBJ_INDIRECTTYPE(S)) - goto indirect; - else if (!PDF_OBJ_NAMETYPE(S)) - goto error; - else if (strcmp(pdf_name_value(S), "GoTo")) - return; - - D = pdf_lookup_dict(A, "D"); - if (PDF_OBJ_NULLTYPE(D)) - D = NULL; - } else if (PDF_OBJ_INDIRECTTYPE(A)) - goto indirect; - else if (A && !PDF_OBJ_NULLTYPE(A)) - goto error; - - tmp = pdf_lookup_dict(annot_dict, "Dest"); - if (PDF_OBJ_NULLTYPE(tmp)) - tmp = NULL; + dict = annot_dict; + key = "Dest"; + D = pdf_deref_obj(pdf_lookup_dict(annot_dict, key)); + if (PDF_OBJ_UNDEFINED(D)) + goto undefined; - if (tmp) { - if (D) + A = pdf_deref_obj(pdf_lookup_dict(annot_dict, "A")); + if (A) { + if (PDF_OBJ_UNDEFINED(A)) + goto undefined; + else if (D || !PDF_OBJ_DICTTYPE(A)) goto error; - else - D = tmp; + else { + S = pdf_deref_obj(pdf_lookup_dict(A, "S")); + if (PDF_OBJ_UNDEFINED(S)) + goto undefined; + else if (!PDF_OBJ_NAMETYPE(S)) + goto error; + else if (strcmp(pdf_name_value(S), "GoTo")) + goto cleanup; + + dict = A; + key = "D"; + D = pdf_deref_obj(pdf_lookup_dict(A, key)); + } } if (PDF_OBJ_STRINGTYPE(D)) @@ -1542,26 +1516,51 @@ pdf_doc_add_gotos (pdf_obj *annot_dict) dest = pdf_name_value(D); #endif else if (PDF_OBJ_ARRAYTYPE(D)) - return; - else if (PDF_OBJ_INDIRECTTYPE(D)) - goto indirect; + goto cleanup; + else if (PDF_OBJ_UNDEFINED(D)) + goto undefined; else goto error; - ht_insert_table(&pdoc.gotos, dest, strlen(dest), NULL+1, NULL); - /* NULL+1 is just some non-null pointer */ - return; + D_new = ht_lookup_table(&pdoc.gotos, dest, strlen(dest)); + if (!D_new) { + char buf[10]; + + /* We use hexadecimal notation for our numeric destinations. + * Other bases (e.g., 10+26 or 10+2*26) would be more efficient. + */ + sprintf(buf, "%lx", ht_table_size(&pdoc.gotos)); + D_new = pdf_new_string(buf, strlen(buf)); + ht_insert_table(&pdoc.gotos, dest, strlen(dest), + D_new, (void (*) (void *)) pdf_release_obj); + } + + { + pdf_obj *key_obj = pdf_new_name(key); + if (!pdf_add_dict(dict, key_obj, pdf_link_obj(D_new))) + pdf_release_obj(key_obj); + } + + cleanup: + if (subtype) + pdf_release_obj(subtype); + if (A) + pdf_release_obj(A); + if (S) + pdf_release_obj(S); + if (D) + pdf_release_obj(D); - indirect: - pdoc.check_gotos = 0; - if (verbose) - MESG("\nFound unexpected annotation format." - " Will not remove PDF destinations\n"); return; error: - WARN("Unknown PDF annotation format."); - return; + WARN("Unknown PDF annotation format. Output file may be broken."); + goto cleanup; + + undefined: + WARN("Cannot optimize PDF annotations. Output file may be broken." + " Please restart with option \"-C 0x10\"\n"); + goto cleanup; } static void @@ -1645,57 +1644,57 @@ pdf_doc_close_names (pdf_doc *p) RELEASE(p->names); p->names = NULL; - ht_clear_table(&p->gotos, NULL); + ht_clear_table(&p->gotos, (void (*) (void *)) pdf_release_obj); return; } void -pdf_doc_add_annot (unsigned page_no, const pdf_rect *rect, pdf_obj *annot_dict) +pdf_doc_add_annot (unsigned page_no, const pdf_rect *rect, + pdf_obj *annot_dict, int new_annot) { pdf_doc *p = &pdoc; pdf_page *page; pdf_obj *rect_array; double annot_grow = p->opt.annot_grow; + double xpos, ypos; + pdf_rect mediabox, annbox; page = doc_get_page_entry(p, page_no); if (!page->annots) page->annots = pdf_new_array(); -#if 1 - { - pdf_rect mediabox; - - pdf_doc_get_mediabox(page_no, &mediabox); - if (rect->llx < mediabox.llx || - rect->urx > mediabox.urx || - rect->lly < mediabox.lly || - rect->ury > mediabox.ury) { - WARN("Annotation out of page boundary."); - WARN("Current page's MediaBox: [%g %g %g %g]", - mediabox.llx, mediabox.lly, mediabox.urx, mediabox.ury); - WARN("Annotation: [%g %g %g %g]", - rect->llx, rect->lly, rect->urx, rect->ury); - WARN("Maybe incorrect paper size specified."); - } - if (rect->llx > rect->urx || rect->lly > rect->ury) { - WARN("Rectangle with negative width/height: [%g %g %g %g]", - rect->llx, rect->lly, rect->urx, rect->ury); - } + pdf_doc_get_mediabox(page_no, &mediabox); + pdf_dev_get_coord(&xpos, &ypos); + annbox.llx = rect->llx - xpos; annbox.lly = rect->lly - ypos; + annbox.urx = rect->urx - xpos; annbox.ury = rect->ury - ypos; + + if (annbox.llx < mediabox.llx || annbox.urx > mediabox.urx || + annbox.lly < mediabox.lly || annbox.ury > mediabox.ury) { + WARN("Annotation out of page boundary."); + WARN("Current page's MediaBox: [%g %g %g %g]", + mediabox.llx, mediabox.lly, mediabox.urx, mediabox.ury); + WARN("Annotation: [%g %g %g %g]", + annbox.llx, annbox.lly, annbox.urx, annbox.ury); + WARN("Maybe incorrect paper size specified."); + } + if (annbox.llx > annbox.urx || annbox.lly > annbox.ury) { + WARN("Rectangle with negative width/height: [%g %g %g %g]", + annbox.llx, annbox.lly, annbox.urx, annbox.ury); } -#endif rect_array = pdf_new_array(); - pdf_add_array(rect_array, pdf_new_number(ROUND(rect->llx - annot_grow, 0.001))); - pdf_add_array(rect_array, pdf_new_number(ROUND(rect->lly - annot_grow, 0.001))); - pdf_add_array(rect_array, pdf_new_number(ROUND(rect->urx + annot_grow, 0.001))); - pdf_add_array(rect_array, pdf_new_number(ROUND(rect->ury + annot_grow, 0.001))); + pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.llx - annot_grow, 0.001))); + pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.lly - annot_grow, 0.001))); + pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.urx + annot_grow, 0.001))); + pdf_add_array(rect_array, pdf_new_number(ROUND(annbox.ury + annot_grow, 0.001))); pdf_add_dict (annot_dict, pdf_new_name("Rect"), rect_array); pdf_add_array(page->annots, pdf_ref_obj(annot_dict)); - pdf_doc_add_gotos(annot_dict); + if (new_annot) + pdf_doc_add_goto(annot_dict); return; } @@ -2653,17 +2652,16 @@ pdf_doc_end_grabbing (pdf_obj *attrib) static struct { int dirty; + int broken; pdf_obj *annot_dict; pdf_rect rect; -} breaking_state = {0, NULL, {0.0, 0.0, 0.0, 0.0}}; +} breaking_state = {0, 0, NULL, {0.0, 0.0, 0.0, 0.0}}; static void reset_box (void) { - breaking_state.rect.llx = 10000.0; /* large value */ - breaking_state.rect.lly = 10000.0; /* large value */ - breaking_state.rect.urx = 0.0; /* small value */ - breaking_state.rect.ury = 0.0; /* small value */ + breaking_state.rect.llx = breaking_state.rect.lly = HUGE_VAL; + breaking_state.rect.urx = breaking_state.rect.ury = -HUGE_VAL; breaking_state.dirty = 0; } @@ -2671,6 +2669,7 @@ void pdf_doc_begin_annot (pdf_obj *dict) { breaking_state.annot_dict = dict; + breaking_state.broken = 0; reset_box(); } @@ -2690,9 +2689,11 @@ pdf_doc_break_annot (void) /* Copy dict */ annot_dict = pdf_new_dict(); pdf_merge_dict(annot_dict, breaking_state.annot_dict); - pdf_doc_add_annot(pdf_doc_current_page_number(), - &(breaking_state.rect), annot_dict); + pdf_doc_add_annot(pdf_doc_current_page_number(), &(breaking_state.rect), + annot_dict, !breaking_state.broken); pdf_release_obj(annot_dict); + + breaking_state.broken = 1; } reset_box(); } |