diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2011-04-04 18:18:16 +0200 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2011-04-04 18:18:16 +0200 |
commit | f81e5ab22ba18963e56aad43c1c7fa9826935f3d (patch) | |
tree | cf3b261e90df51014755a8d1395116f839f73c95 /pdf/pdf_nametree.c | |
parent | c8d226b5bfb5dab2db10ea5175966de7bac9640e (diff) | |
download | mupdf-f81e5ab22ba18963e56aad43c1c7fa9826935f3d.tar.xz |
pdf: Rename mupdf directory.
Diffstat (limited to 'pdf/pdf_nametree.c')
-rw-r--r-- | pdf/pdf_nametree.c | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/pdf/pdf_nametree.c b/pdf/pdf_nametree.c new file mode 100644 index 00000000..6b2314cd --- /dev/null +++ b/pdf/pdf_nametree.c @@ -0,0 +1,139 @@ +#include "fitz.h" +#include "mupdf.h" + +static fz_obj * +pdf_lookupnameimp(fz_obj *node, fz_obj *needle) +{ + fz_obj *kids = fz_dictgets(node, "Kids"); + fz_obj *names = fz_dictgets(node, "Names"); + + if (fz_isarray(kids)) + { + int l = 0; + int r = fz_arraylen(kids) - 1; + + while (l <= r) + { + int m = (l + r) >> 1; + fz_obj *kid = fz_arrayget(kids, m); + fz_obj *limits = fz_dictgets(kid, "Limits"); + fz_obj *first = fz_arrayget(limits, 0); + fz_obj *last = fz_arrayget(limits, 1); + + if (fz_objcmp(needle, first) < 0) + r = m - 1; + else if (fz_objcmp(needle, last) > 0) + l = m + 1; + else + return pdf_lookupnameimp(kid, needle); + } + } + + if (fz_isarray(names)) + { + int l = 0; + int r = (fz_arraylen(names) / 2) - 1; + + while (l <= r) + { + int m = (l + r) >> 1; + int c; + fz_obj *key = fz_arrayget(names, m * 2); + fz_obj *val = fz_arrayget(names, m * 2 + 1); + + c = fz_objcmp(needle, key); + if (c < 0) + r = m - 1; + else if (c > 0) + l = m + 1; + else + return val; + } + } + + return nil; +} + +fz_obj * +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"); + fz_obj *names = fz_dictgets(root, "Names"); + fz_obj *dest = nil; + + /* PDF 1.1 has destinations in a dictionary */ + if (dests) + { + if (fz_isname(needle)) + return fz_dictget(dests, needle); + else + return fz_dictgets(dests, fz_tostrbuf(needle)); + } + + /* PDF 1.2 has destinations in a name tree */ + if (names && !dest) + { + 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 (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; +} |