diff options
author | Tor Andersson <tor@ghostscript.com> | 2010-09-13 15:43:19 +0000 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2010-09-13 15:43:19 +0000 |
commit | ee9b6616000a896ead315c1bf61de22bf92a3fa4 (patch) | |
tree | ea4dc01d821f225cbe0a78c50622204d730f45c2 | |
parent | ffa9e9c23e1d4b64774a9f2cc37a8584ad20459f (diff) | |
download | mupdf-ee9b6616000a896ead315c1bf61de22bf92a3fa4.tar.xz |
Generalise name tree parsing to work for all types of name trees.
-rw-r--r-- | mupdf/mupdf.h | 7 | ||||
-rw-r--r-- | mupdf/pdf_nametree.c | 89 | ||||
-rw-r--r-- | mupdf/pdf_parse.c | 9 |
3 files changed, 84 insertions, 21 deletions
diff --git a/mupdf/mupdf.h b/mupdf/mupdf.h index 359e01fd..dc86ecfd 100644 --- a/mupdf/mupdf.h +++ b/mupdf/mupdf.h @@ -45,6 +45,8 @@ fz_rect pdf_torect(fz_obj *array); fz_matrix pdf_tomatrix(fz_obj *array); char * pdf_toutf8(fz_obj *src); unsigned short * pdf_toucs2(fz_obj *src); +fz_obj * pdf_toutf8name(fz_obj *src); + /* * Encryption @@ -475,7 +477,10 @@ struct pdf_outline_s pdf_outline *next; }; -fz_obj *pdf_lookupdest(pdf_xref *xref, fz_obj *nameddest); +fz_obj *pdf_lookupdest(pdf_xref *xref, fz_obj *needle); +fz_obj *pdf_lookupname(pdf_xref *xref, char *which, fz_obj *needle); +fz_obj *pdf_loadnametree(pdf_xref *xref, char *which); + pdf_outline *pdf_loadoutline(pdf_xref *xref); void pdf_debugoutline(pdf_outline *outline, int level); diff --git a/mupdf/pdf_nametree.c b/mupdf/pdf_nametree.c index b64db71b..6b2314cd 100644 --- a/mupdf/pdf_nametree.c +++ b/mupdf/pdf_nametree.c @@ -2,12 +2,10 @@ #include "mupdf.h" static fz_obj * -pdf_lookupdestimp(fz_obj *node, fz_obj *nameddest) +pdf_lookupnameimp(fz_obj *node, fz_obj *needle) { - fz_obj *kids, *names; - - kids = fz_dictgets(node, "Kids"); - names = fz_dictgets(node, "Names"); + fz_obj *kids = fz_dictgets(node, "Kids"); + fz_obj *names = fz_dictgets(node, "Names"); if (fz_isarray(kids)) { @@ -22,12 +20,12 @@ pdf_lookupdestimp(fz_obj *node, fz_obj *nameddest) fz_obj *first = fz_arrayget(limits, 0); fz_obj *last = fz_arrayget(limits, 1); - if (fz_objcmp(nameddest, first) < 0) + if (fz_objcmp(needle, first) < 0) r = m - 1; - else if (fz_objcmp(nameddest, last) > 0) + else if (fz_objcmp(needle, last) > 0) l = m + 1; else - return pdf_lookupdestimp(kid, nameddest); + return pdf_lookupnameimp(kid, needle); } } @@ -43,7 +41,7 @@ pdf_lookupdestimp(fz_obj *node, fz_obj *nameddest) fz_obj *key = fz_arrayget(names, m * 2); fz_obj *val = fz_arrayget(names, m * 2 + 1); - c = fz_objcmp(nameddest, key); + c = fz_objcmp(needle, key); if (c < 0) r = m - 1; else if (c > 0) @@ -57,7 +55,16 @@ pdf_lookupdestimp(fz_obj *node, fz_obj *nameddest) } fz_obj * -pdf_lookupdest(pdf_xref *xref, fz_obj *nameddest) +pdf_lookupname(pdf_xref *xref, char *which, fz_obj *needle) +{ + fz_obj *root = fz_dictgets(xref->trailer, "Root"); + fz_obj *names = fz_dictgets(root, "Names"); + fz_obj *tree = fz_dictgets(names, which); + return pdf_lookupnameimp(tree, needle); +} + +fz_obj * +pdf_lookupdest(pdf_xref *xref, fz_obj *needle) { fz_obj *root = fz_dictgets(xref->trailer, "Root"); fz_obj *dests = fz_dictgets(root, "Dests"); @@ -67,24 +74,66 @@ pdf_lookupdest(pdf_xref *xref, fz_obj *nameddest) /* PDF 1.1 has destinations in a dictionary */ if (dests) { - if (fz_isname(nameddest)) - dest = fz_dictget(dests, nameddest); + if (fz_isname(needle)) + return fz_dictget(dests, needle); else - dest = fz_dictgets(dests, fz_tostrbuf(nameddest)); + return fz_dictgets(dests, fz_tostrbuf(needle)); } /* PDF 1.2 has destinations in a name tree */ if (names && !dest) { - fz_obj *desttree = fz_dictgets(names, "Dests"); - if (desttree) - dest = pdf_lookupdestimp(desttree, nameddest); + fz_obj *tree = fz_dictgets(names, "Dests"); + return pdf_lookupnameimp(tree, needle); + } + + return nil; +} + +static void +pdf_loadnametreeimp(fz_obj *dict, pdf_xref *xref, fz_obj *node) +{ + fz_obj *kids = fz_dictgets(node, "Kids"); + fz_obj *names = fz_dictgets(node, "Names"); + int i; + + if (kids) + { + for (i = 0; i < fz_arraylen(kids); i++) + pdf_loadnametreeimp(dict, xref, fz_arrayget(kids, i)); } - if (fz_isdict(dest)) - return dest; - if (fz_isarray(dest)) - return dest; + if (names) + { + for (i = 0; i + 1 < fz_arraylen(names); i += 2) + { + fz_obj *key = fz_arrayget(names, i); + fz_obj *val = fz_arrayget(names, i + 1); + if (fz_isstring(key)) + { + key = pdf_toutf8name(key); + fz_dictput(dict, key, val); + fz_dropobj(key); + } + else if (fz_isname(key)) + { + fz_dictput(dict, key, val); + } + } + } +} +fz_obj * +pdf_loadnametree(pdf_xref *xref, char *which) +{ + fz_obj *root = fz_dictgets(xref->trailer, "Root"); + fz_obj *names = fz_dictgets(root, "Names"); + fz_obj *tree = fz_dictgets(names, which); + if (fz_isdict(tree)) + { + fz_obj *dict = fz_newdict(100); + pdf_loadnametreeimp(dict, xref, tree); + return dict; + } return nil; } diff --git a/mupdf/pdf_parse.c b/mupdf/pdf_parse.c index 942c5d33..bfd0804f 100644 --- a/mupdf/pdf_parse.c +++ b/mupdf/pdf_parse.c @@ -98,6 +98,15 @@ pdf_toucs2(fz_obj *src) return dst; } +fz_obj * +pdf_toutf8name(fz_obj *src) +{ + char *buf = pdf_toutf8(src); + fz_obj *dst = fz_newname(buf); + fz_free(buf); + return dst; +} + fz_error pdf_parsearray(fz_obj **op, pdf_xref *xref, fz_stream *file, char *buf, int cap) { |