Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4680 right-hear 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
}