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 | /* |
||
5 | * Load CMap stream in PDF file |
||
6 | */ |
||
7 | fz_error |
||
8 | pdf_load_embedded_cmap(pdf_cmap **cmapp, pdf_xref *xref, fz_obj *stmobj) |
||
9 | { |
||
10 | fz_error error = fz_okay; |
||
11 | fz_stream *file = NULL; |
||
12 | pdf_cmap *cmap = NULL; |
||
13 | pdf_cmap *usecmap; |
||
14 | fz_obj *wmode; |
||
15 | fz_obj *obj; |
||
16 | |||
17 | if ((*cmapp = pdf_find_item(xref->store, pdf_drop_cmap, stmobj))) |
||
18 | { |
||
19 | pdf_keep_cmap(*cmapp); |
||
20 | return fz_okay; |
||
21 | } |
||
22 | |||
23 | error = pdf_open_stream(&file, xref, fz_to_num(stmobj), fz_to_gen(stmobj)); |
||
24 | if (error) |
||
25 | { |
||
26 | error = fz_rethrow(error, "cannot open cmap stream (%d %d R)", fz_to_num(stmobj), fz_to_gen(stmobj)); |
||
27 | goto cleanup; |
||
28 | } |
||
29 | |||
30 | error = pdf_parse_cmap(&cmap, file); |
||
31 | if (error) |
||
32 | { |
||
33 | error = fz_rethrow(error, "cannot parse cmap stream (%d %d R)", fz_to_num(stmobj), fz_to_gen(stmobj)); |
||
34 | goto cleanup; |
||
35 | } |
||
36 | |||
37 | fz_close(file); |
||
38 | |||
39 | wmode = fz_dict_gets(stmobj, "WMode"); |
||
40 | if (fz_is_int(wmode)) |
||
41 | pdf_set_wmode(cmap, fz_to_int(wmode)); |
||
42 | |||
43 | obj = fz_dict_gets(stmobj, "UseCMap"); |
||
44 | if (fz_is_name(obj)) |
||
45 | { |
||
46 | error = pdf_load_system_cmap(&usecmap, fz_to_name(obj)); |
||
47 | if (error) |
||
48 | { |
||
49 | error = fz_rethrow(error, "cannot load system usecmap '%s'", fz_to_name(obj)); |
||
50 | goto cleanup; |
||
51 | } |
||
52 | pdf_set_usecmap(cmap, usecmap); |
||
53 | pdf_drop_cmap(usecmap); |
||
54 | } |
||
55 | else if (fz_is_indirect(obj)) |
||
56 | { |
||
57 | error = pdf_load_embedded_cmap(&usecmap, xref, obj); |
||
58 | if (error) |
||
59 | { |
||
60 | error = fz_rethrow(error, "cannot load embedded usecmap (%d %d R)", fz_to_num(obj), fz_to_gen(obj)); |
||
61 | goto cleanup; |
||
62 | } |
||
63 | pdf_set_usecmap(cmap, usecmap); |
||
64 | pdf_drop_cmap(usecmap); |
||
65 | } |
||
66 | |||
67 | pdf_store_item(xref->store, pdf_keep_cmap, pdf_drop_cmap, stmobj, cmap); |
||
68 | |||
69 | *cmapp = cmap; |
||
70 | return fz_okay; |
||
71 | |||
72 | cleanup: |
||
73 | if (file) |
||
74 | fz_close(file); |
||
75 | if (cmap) |
||
76 | pdf_drop_cmap(cmap); |
||
77 | return error; /* already rethrown */ |
||
78 | } |
||
79 | |||
80 | /* |
||
81 | * Create an Identity-* CMap (for both 1 and 2-byte encodings) |
||
82 | */ |
||
83 | pdf_cmap * |
||
84 | pdf_new_identity_cmap(int wmode, int bytes) |
||
85 | { |
||
86 | pdf_cmap *cmap = pdf_new_cmap(); |
||
87 | sprintf(cmap->cmap_name, "Identity-%c", wmode ? 'V' : 'H'); |
||
88 | pdf_add_codespace(cmap, 0x0000, 0xffff, bytes); |
||
89 | pdf_map_range_to_range(cmap, 0x0000, 0xffff, 0); |
||
90 | pdf_sort_cmap(cmap); |
||
91 | pdf_set_wmode(cmap, wmode); |
||
92 | return cmap; |
||
93 | } |
||
94 | |||
95 | /* |
||
96 | * Load predefined CMap from system. |
||
97 | */ |
||
98 | fz_error |
||
99 | pdf_load_system_cmap(pdf_cmap **cmapp, char *cmap_name) |
||
100 | { |
||
101 | pdf_cmap *usecmap; |
||
102 | pdf_cmap *cmap; |
||
103 | |||
104 | cmap = pdf_find_builtin_cmap(cmap_name); |
||
105 | if (!cmap) |
||
106 | return fz_throw("no builtin cmap file: %s", cmap_name); |
||
107 | |||
108 | if (cmap->usecmap_name[0] && !cmap->usecmap) |
||
109 | { |
||
110 | usecmap = pdf_find_builtin_cmap(cmap->usecmap_name); |
||
111 | if (!usecmap) |
||
112 | return fz_throw("nu builtin cmap file: %s", cmap->usecmap_name); |
||
113 | pdf_set_usecmap(cmap, usecmap); |
||
114 | } |
||
115 | |||
116 | *cmapp = cmap; |
||
117 | return fz_okay; |
||
118 | } |