Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. #include "fitz.h"
  2. #include "mupdf.h"
  3.  
  4. static fz_obj *
  5. pdf_lookup_name_imp(fz_obj *node, fz_obj *needle)
  6. {
  7.         fz_obj *kids = fz_dict_gets(node, "Kids");
  8.         fz_obj *names = fz_dict_gets(node, "Names");
  9.  
  10.         if (fz_is_array(kids))
  11.         {
  12.                 int l = 0;
  13.                 int r = fz_array_len(kids) - 1;
  14.  
  15.                 while (l <= r)
  16.                 {
  17.                         int m = (l + r) >> 1;
  18.                         fz_obj *kid = fz_array_get(kids, m);
  19.                         fz_obj *limits = fz_dict_gets(kid, "Limits");
  20.                         fz_obj *first = fz_array_get(limits, 0);
  21.                         fz_obj *last = fz_array_get(limits, 1);
  22.  
  23.                         if (fz_objcmp(needle, first) < 0)
  24.                                 r = m - 1;
  25.                         else if (fz_objcmp(needle, last) > 0)
  26.                                 l = m + 1;
  27.                         else
  28.                                 return pdf_lookup_name_imp(kid, needle);
  29.                 }
  30.         }
  31.  
  32.         if (fz_is_array(names))
  33.         {
  34.                 int l = 0;
  35.                 int r = (fz_array_len(names) / 2) - 1;
  36.  
  37.                 while (l <= r)
  38.                 {
  39.                         int m = (l + r) >> 1;
  40.                         int c;
  41.                         fz_obj *key = fz_array_get(names, m * 2);
  42.                         fz_obj *val = fz_array_get(names, m * 2 + 1);
  43.  
  44.                         c = fz_objcmp(needle, key);
  45.                         if (c < 0)
  46.                                 r = m - 1;
  47.                         else if (c > 0)
  48.                                 l = m + 1;
  49.                         else
  50.                                 return val;
  51.                 }
  52.         }
  53.  
  54.         return NULL;
  55. }
  56.  
  57. fz_obj *
  58. pdf_lookup_name(pdf_xref *xref, char *which, fz_obj *needle)
  59. {
  60.         fz_obj *root = fz_dict_gets(xref->trailer, "Root");
  61.         fz_obj *names = fz_dict_gets(root, "Names");
  62.         fz_obj *tree = fz_dict_gets(names, which);
  63.         return pdf_lookup_name_imp(tree, needle);
  64. }
  65.  
  66. fz_obj *
  67. pdf_lookup_dest(pdf_xref *xref, fz_obj *needle)
  68. {
  69.         fz_obj *root = fz_dict_gets(xref->trailer, "Root");
  70.         fz_obj *dests = fz_dict_gets(root, "Dests");
  71.         fz_obj *names = fz_dict_gets(root, "Names");
  72.         fz_obj *dest = NULL;
  73.  
  74.         /* PDF 1.1 has destinations in a dictionary */
  75.         if (dests)
  76.         {
  77.                 if (fz_is_name(needle))
  78.                         return fz_dict_get(dests, needle);
  79.                 else
  80.                         return fz_dict_gets(dests, fz_to_str_buf(needle));
  81.         }
  82.  
  83.         /* PDF 1.2 has destinations in a name tree */
  84.         if (names && !dest)
  85.         {
  86.                 fz_obj *tree = fz_dict_gets(names, "Dests");
  87.                 return pdf_lookup_name_imp(tree, needle);
  88.         }
  89.  
  90.         return NULL;
  91. }
  92.  
  93. static void
  94. pdf_load_name_tree_imp(fz_obj *dict, pdf_xref *xref, fz_obj *node)
  95. {
  96.         fz_obj *kids = fz_dict_gets(node, "Kids");
  97.         fz_obj *names = fz_dict_gets(node, "Names");
  98.         int i;
  99.  
  100.         if (kids)
  101.         {
  102.                 for (i = 0; i < fz_array_len(kids); i++)
  103.                         pdf_load_name_tree_imp(dict, xref, fz_array_get(kids, i));
  104.         }
  105.  
  106.         if (names)
  107.         {
  108.                 for (i = 0; i + 1 < fz_array_len(names); i += 2)
  109.                 {
  110.                         fz_obj *key = fz_array_get(names, i);
  111.                         fz_obj *val = fz_array_get(names, i + 1);
  112.                         if (fz_is_string(key))
  113.                         {
  114.                                 key = pdf_to_utf8_name(key);
  115.                                 fz_dict_put(dict, key, val);
  116.                                 fz_drop_obj(key);
  117.                         }
  118.                         else if (fz_is_name(key))
  119.                         {
  120.                                 fz_dict_put(dict, key, val);
  121.                         }
  122.                 }
  123.         }
  124. }
  125.  
  126. fz_obj *
  127. pdf_load_name_tree(pdf_xref *xref, char *which)
  128. {
  129.         fz_obj *root = fz_dict_gets(xref->trailer, "Root");
  130.         fz_obj *names = fz_dict_gets(root, "Names");
  131.         fz_obj *tree = fz_dict_gets(names, which);
  132.         if (fz_is_dict(tree))
  133.         {
  134.                 fz_obj *dict = fz_new_dict(100);
  135.                 pdf_load_name_tree_imp(dict, xref, tree);
  136.                 return dict;
  137.         }
  138.         return NULL;
  139. }
  140.