8 pdf_code_from_string(char *buf, int len)
12 a = (a << 8) | *(unsigned char *)buf++;
17 pdf_parse_cmap_name(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_lexbuf *buf)
21 tok = pdf_lex(file, buf);
23 if (tok == PDF_TOK_NAME)
24 fz_strlcpy(cmap->cmap_name, buf->scratch, sizeof(cmap->cmap_name));
26 fz_warn(ctx, "expected name after CMapName in cmap");
30 pdf_parse_wmode(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_lexbuf *buf)
34 tok = pdf_lex(file, buf);
36 if (tok == PDF_TOK_INT)
37 pdf_set_cmap_wmode(ctx, cmap, buf->i);
39 fz_warn(ctx, "expected integer after WMode in cmap");
43 pdf_parse_codespace_range(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_lexbuf *buf)
50 tok = pdf_lex(file, buf);
52 if (tok == PDF_TOK_KEYWORD && !strcmp(buf->scratch, "endcodespacerange"))
55 else if (tok == PDF_TOK_STRING)
57 lo = pdf_code_from_string(buf->scratch, buf->len);
58 tok = pdf_lex(file, buf);
59 if (tok == PDF_TOK_STRING)
61 hi = pdf_code_from_string(buf->scratch, buf->len);
62 pdf_add_codespace(ctx, cmap, lo, hi, buf->len);
70 fz_throw(ctx, FZ_ERROR_GENERIC, "expected string or endcodespacerange");
74 pdf_parse_cid_range(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_lexbuf *buf)
81 tok = pdf_lex(file, buf);
83 if (tok == PDF_TOK_KEYWORD && !strcmp(buf->scratch, "endcidrange"))
86 else if (tok != PDF_TOK_STRING)
87 fz_throw(ctx, FZ_ERROR_GENERIC, "expected string or endcidrange");
89 lo = pdf_code_from_string(buf->scratch, buf->len);
91 tok = pdf_lex(file, buf);
92 if (tok != PDF_TOK_STRING)
93 fz_throw(ctx, FZ_ERROR_GENERIC, "expected string");
95 hi = pdf_code_from_string(buf->scratch, buf->len);
97 tok = pdf_lex(file, buf);
98 if (tok != PDF_TOK_INT)
99 fz_throw(ctx, FZ_ERROR_GENERIC, "expected integer");
103 pdf_map_range_to_range(ctx, cmap, lo, hi, dst);
108 pdf_parse_cid_char(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_lexbuf *buf)
115 tok = pdf_lex(file, buf);
117 if (tok == PDF_TOK_KEYWORD && !strcmp(buf->scratch, "endcidchar"))
120 else if (tok != PDF_TOK_STRING)
121 fz_throw(ctx, FZ_ERROR_GENERIC, "expected string or endcidchar");
123 src = pdf_code_from_string(buf->scratch, buf->len);
125 tok = pdf_lex(file, buf);
126 if (tok != PDF_TOK_INT)
127 fz_throw(ctx, FZ_ERROR_GENERIC, "expected integer");
131 pdf_map_range_to_range(ctx, cmap, src, src, dst);
136 pdf_parse_bf_range_array(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_lexbuf *buf, int lo, int hi)
144 tok = pdf_lex(file, buf);
146 if (tok == PDF_TOK_CLOSE_ARRAY)
149 /* Note: does not handle [ /Name /Name ... ] */
150 else if (tok != PDF_TOK_STRING)
151 fz_throw(ctx, FZ_ERROR_GENERIC, "expected string or ]");
155 int len = fz_mini(buf->len / 2, nelem(dst));
156 for (i = 0; i < len; i++)
157 dst[i] = pdf_code_from_string(&buf->scratch[i * 2], 2);
159 pdf_map_one_to_many(ctx, cmap, lo, dst, buf->len / 2);
167 pdf_parse_bf_range(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_lexbuf *buf)
174 tok = pdf_lex(file, buf);
176 if (tok == PDF_TOK_KEYWORD && !strcmp(buf->scratch, "endbfrange"))
179 else if (tok != PDF_TOK_STRING)
180 fz_throw(ctx, FZ_ERROR_GENERIC, "expected string or endbfrange");
182 lo = pdf_code_from_string(buf->scratch, buf->len);
184 tok = pdf_lex(file, buf);
185 if (tok != PDF_TOK_STRING)
186 fz_throw(ctx, FZ_ERROR_GENERIC, "expected string");
188 hi = pdf_code_from_string(buf->scratch, buf->len);
189 if (lo < 0 || lo > 65535 || hi < 0 || hi > 65535 || lo > hi)
191 fz_warn(ctx, "bf_range limits out of range in cmap %s", cmap->cmap_name);
195 tok = pdf_lex(file, buf);
197 if (tok == PDF_TOK_STRING)
201 dst = pdf_code_from_string(buf->scratch, buf->len);
202 pdf_map_range_to_range(ctx, cmap, lo, hi, dst);
211 int len = fz_mini(buf->len / 2, nelem(dststr));
212 for (i = 0; i < len; i++)
213 dststr[i] = pdf_code_from_string(&buf->scratch[i * 2], 2);
218 pdf_map_one_to_many(ctx, cmap, lo, dststr, i);
225 else if (tok == PDF_TOK_OPEN_ARRAY)
227 pdf_parse_bf_range_array(ctx, cmap, file, buf, lo, hi);
232 fz_throw(ctx, FZ_ERROR_GENERIC, "expected string or array or endbfrange");
238 pdf_parse_bf_char(fz_context *ctx, pdf_cmap *cmap, fz_stream *file, pdf_lexbuf *buf)
247 tok = pdf_lex(file, buf);
249 if (tok == PDF_TOK_KEYWORD && !strcmp(buf->scratch, "endbfchar"))
252 else if (tok != PDF_TOK_STRING)
253 fz_throw(ctx, FZ_ERROR_GENERIC, "expected string or endbfchar");
255 src = pdf_code_from_string(buf->scratch, buf->len);
257 tok = pdf_lex(file, buf);
258 /* Note: does not handle /dstName */
259 if (tok != PDF_TOK_STRING)
260 fz_throw(ctx, FZ_ERROR_GENERIC, "expected string");
264 int len = fz_mini(buf->len / 2, nelem(dst));
265 for (i = 0; i < len; i++)
266 dst[i] = pdf_code_from_string(&buf->scratch[i * 2], 2);
267 pdf_map_one_to_many(ctx, cmap, src, dst, i);
273 pdf_load_cmap(fz_context *ctx, fz_stream *file)
280 pdf_lexbuf_init(ctx, &buf, PDF_LEXBUF_SMALL);
281 cmap = pdf_new_cmap(ctx);
283 strcpy(key, ".notdef");
289 tok = pdf_lex(file, &buf);
291 if (tok == PDF_TOK_EOF)
294 else if (tok == PDF_TOK_NAME)
296 if (!strcmp(buf.scratch, "CMapName"))
297 pdf_parse_cmap_name(ctx, cmap, file, &buf);
298 else if (!strcmp(buf.scratch, "WMode"))
299 pdf_parse_wmode(ctx, cmap, file, &buf);
301 fz_strlcpy(key, buf.scratch, sizeof key);
304 else if (tok == PDF_TOK_KEYWORD)
306 if (!strcmp(buf.scratch, "endcmap"))
309 else if (!strcmp(buf.scratch, "usecmap"))
310 fz_strlcpy(cmap->usecmap_name, key, sizeof(cmap->usecmap_name));
312 else if (!strcmp(buf.scratch, "begincodespacerange"))
313 pdf_parse_codespace_range(ctx, cmap, file, &buf);
315 else if (!strcmp(buf.scratch, "beginbfchar"))
316 pdf_parse_bf_char(ctx, cmap, file, &buf);
318 else if (!strcmp(buf.scratch, "begincidchar"))
319 pdf_parse_cid_char(ctx, cmap, file, &buf);
321 else if (!strcmp(buf.scratch, "beginbfrange"))
322 pdf_parse_bf_range(ctx, cmap, file, &buf);
324 else if (!strcmp(buf.scratch, "begincidrange"))
325 pdf_parse_cid_range(ctx, cmap, file, &buf);
328 /* ignore everything else */
331 pdf_sort_cmap(ctx, cmap);
335 pdf_lexbuf_fin(&buf);
339 pdf_drop_cmap(ctx, cmap);
340 fz_rethrow_message(ctx, "syntaxerror in cmap");