pdf-interpret.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383
  1. // Copyright (C) 2004-2025 Artifex Software, Inc.
  2. //
  3. // This file is part of MuPDF.
  4. //
  5. // MuPDF is free software: you can redistribute it and/or modify it under the
  6. // terms of the GNU Affero General Public License as published by the Free
  7. // Software Foundation, either version 3 of the License, or (at your option)
  8. // any later version.
  9. //
  10. // MuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
  11. // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  12. // FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  13. // details.
  14. //
  15. // You should have received a copy of the GNU Affero General Public License
  16. // along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>
  17. //
  18. // Alternative licensing terms are available from the licensor.
  19. // For commercial licensing, see <https://www.artifex.com/> or contact
  20. // Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
  21. // CA 94129, USA, for further information.
  22. #include "mupdf/fitz.h"
  23. #include "pdf-annot-imp.h"
  24. #include <string.h>
  25. #include <math.h>
  26. /* Maximum number of errors before aborting */
  27. #define MAX_SYNTAX_ERRORS 100
  28. void *
  29. pdf_new_processor(fz_context *ctx, int size)
  30. {
  31. pdf_processor *ret = Memento_label(fz_calloc(ctx, 1, size), "pdf_processor");
  32. ret->refs = 1;
  33. return ret;
  34. }
  35. pdf_processor *
  36. pdf_keep_processor(fz_context *ctx, pdf_processor *proc)
  37. {
  38. return fz_keep_imp(ctx, proc, &proc->refs);
  39. }
  40. void
  41. pdf_close_processor(fz_context *ctx, pdf_processor *proc)
  42. {
  43. void (*close_processor)(fz_context *ctx, pdf_processor *proc);
  44. if (!proc || proc->closed)
  45. return;
  46. proc->closed = 1;
  47. close_processor = proc->close_processor;
  48. if (!close_processor)
  49. return;
  50. close_processor(ctx, proc); /* Tail recursion */
  51. }
  52. void
  53. pdf_drop_processor(fz_context *ctx, pdf_processor *proc)
  54. {
  55. if (fz_drop_imp(ctx, proc, &proc->refs))
  56. {
  57. if (!proc->closed)
  58. fz_warn(ctx, "dropping unclosed PDF processor");
  59. if (proc->drop_processor)
  60. proc->drop_processor(ctx, proc);
  61. fz_free(ctx, proc);
  62. }
  63. }
  64. void pdf_reset_processor(fz_context *ctx, pdf_processor *proc)
  65. {
  66. if (proc == NULL)
  67. return;
  68. proc->closed = 0;
  69. if (proc->reset_processor == NULL)
  70. fz_throw(ctx, FZ_ERROR_ARGUMENT, "Cannot reset PDF processor");
  71. proc->reset_processor(ctx, proc);
  72. }
  73. static void
  74. pdf_init_csi(fz_context *ctx, pdf_csi *csi, pdf_document *doc, pdf_obj *rdb, pdf_lexbuf *buf, fz_cookie *cookie)
  75. {
  76. memset(csi, 0, sizeof *csi);
  77. csi->doc = doc;
  78. csi->rdb = rdb;
  79. csi->buf = buf;
  80. csi->cookie = cookie;
  81. }
  82. static void
  83. pdf_clear_stack(fz_context *ctx, pdf_csi *csi)
  84. {
  85. int i;
  86. pdf_drop_obj(ctx, csi->obj);
  87. csi->obj = NULL;
  88. csi->name[0] = 0;
  89. csi->string_len = 0;
  90. for (i = 0; i < csi->top; i++)
  91. csi->stack[i] = 0;
  92. csi->top = 0;
  93. }
  94. static pdf_font_desc *
  95. pdf_try_load_font(fz_context *ctx, pdf_document *doc, pdf_obj *rdb, pdf_obj *font, fz_cookie *cookie)
  96. {
  97. pdf_font_desc *desc = NULL;
  98. fz_try(ctx)
  99. desc = pdf_load_font(ctx, doc, rdb, font);
  100. fz_catch(ctx)
  101. {
  102. if (fz_caught(ctx) == FZ_ERROR_TRYLATER)
  103. {
  104. fz_ignore_error(ctx);
  105. if (cookie)
  106. cookie->incomplete++;
  107. }
  108. else
  109. {
  110. fz_rethrow_if(ctx, FZ_ERROR_SYSTEM);
  111. fz_report_error(ctx);
  112. }
  113. }
  114. if (desc == NULL)
  115. desc = pdf_load_hail_mary_font(ctx, doc);
  116. return desc;
  117. }
  118. static fz_image *
  119. parse_inline_image(fz_context *ctx, pdf_csi *csi, fz_stream *stm, char *csname, int cslen)
  120. {
  121. pdf_document *doc = csi->doc;
  122. pdf_obj *rdb = csi->rdb;
  123. pdf_obj *obj = NULL;
  124. pdf_obj *cs;
  125. fz_image *img = NULL;
  126. int ch, found;
  127. fz_var(obj);
  128. fz_var(img);
  129. fz_try(ctx)
  130. {
  131. obj = pdf_parse_dict(ctx, doc, stm, &doc->lexbuf.base);
  132. if (csname)
  133. {
  134. cs = pdf_dict_get(ctx, obj, PDF_NAME(CS));
  135. if (!pdf_is_indirect(ctx, cs) && pdf_is_name(ctx, cs))
  136. fz_strlcpy(csname, pdf_to_name(ctx, cs), cslen);
  137. else
  138. csname[0] = 0;
  139. }
  140. /* read whitespace after ID keyword */
  141. ch = fz_read_byte(ctx, stm);
  142. if (ch == '\r')
  143. if (fz_peek_byte(ctx, stm) == '\n')
  144. fz_read_byte(ctx, stm);
  145. img = pdf_load_inline_image(ctx, doc, rdb, obj, stm);
  146. /* find EI */
  147. found = 0;
  148. ch = fz_read_byte(ctx, stm);
  149. do
  150. {
  151. while (ch != 'E' && ch != EOF)
  152. ch = fz_read_byte(ctx, stm);
  153. if (ch == 'E')
  154. {
  155. ch = fz_read_byte(ctx, stm);
  156. if (ch == 'I')
  157. {
  158. ch = fz_peek_byte(ctx, stm);
  159. if (ch == ' ' || ch <= 32 || ch == '<' || ch == '/')
  160. {
  161. found = 1;
  162. break;
  163. }
  164. }
  165. }
  166. } while (ch != EOF);
  167. if (!found)
  168. fz_throw(ctx, FZ_ERROR_SYNTAX, "syntax error after inline image");
  169. }
  170. fz_always(ctx)
  171. {
  172. pdf_drop_obj(ctx, obj);
  173. }
  174. fz_catch(ctx)
  175. {
  176. fz_drop_image(ctx, img);
  177. fz_rethrow(ctx);
  178. }
  179. return img;
  180. }
  181. static void
  182. pdf_process_extgstate(fz_context *ctx, pdf_processor *proc, pdf_csi *csi, pdf_obj *dict)
  183. {
  184. pdf_obj *obj;
  185. obj = pdf_dict_get(ctx, dict, PDF_NAME(LW));
  186. if (pdf_is_number(ctx, obj) && proc->op_w)
  187. proc->op_w(ctx, proc, pdf_to_real(ctx, obj));
  188. obj = pdf_dict_get(ctx, dict, PDF_NAME(LC));
  189. if (pdf_is_int(ctx, obj) && proc->op_J)
  190. proc->op_J(ctx, proc, fz_clampi(pdf_to_int(ctx, obj), 0, 2));
  191. obj = pdf_dict_get(ctx, dict, PDF_NAME(LJ));
  192. if (pdf_is_int(ctx, obj) && proc->op_j)
  193. proc->op_j(ctx, proc, fz_clampi(pdf_to_int(ctx, obj), 0, 2));
  194. obj = pdf_dict_get(ctx, dict, PDF_NAME(ML));
  195. if (pdf_is_number(ctx, obj) && proc->op_M)
  196. proc->op_M(ctx, proc, pdf_to_real(ctx, obj));
  197. obj = pdf_dict_get(ctx, dict, PDF_NAME(D));
  198. if (pdf_is_array(ctx, obj) && proc->op_d)
  199. {
  200. pdf_obj *dash_array = pdf_array_get(ctx, obj, 0);
  201. pdf_obj *dash_phase = pdf_array_get(ctx, obj, 1);
  202. proc->op_d(ctx, proc, dash_array, pdf_to_real(ctx, dash_phase));
  203. }
  204. obj = pdf_dict_get(ctx, dict, PDF_NAME(RI));
  205. if (pdf_is_name(ctx, obj) && proc->op_ri)
  206. proc->op_ri(ctx, proc, pdf_to_name(ctx, obj));
  207. obj = pdf_dict_get(ctx, dict, PDF_NAME(FL));
  208. if (pdf_is_number(ctx, obj) && proc->op_i)
  209. proc->op_i(ctx, proc, pdf_to_real(ctx, obj));
  210. obj = pdf_dict_get(ctx, dict, PDF_NAME(Font));
  211. if (pdf_is_array(ctx, obj) && proc->op_Tf)
  212. {
  213. pdf_obj *font_ref = pdf_array_get(ctx, obj, 0);
  214. pdf_obj *font_size = pdf_array_get(ctx, obj, 1);
  215. pdf_font_desc *font;
  216. if (pdf_is_dict(ctx, font_ref))
  217. font = pdf_try_load_font(ctx, csi->doc, csi->rdb, font_ref, csi->cookie);
  218. else
  219. font = pdf_load_hail_mary_font(ctx, csi->doc);
  220. fz_try(ctx)
  221. proc->op_Tf(ctx, proc, "ExtGState", font, pdf_to_real(ctx, font_size));
  222. fz_always(ctx)
  223. pdf_drop_font(ctx, font);
  224. fz_catch(ctx)
  225. fz_rethrow(ctx);
  226. }
  227. /* overprint and color management */
  228. obj = pdf_dict_get(ctx, dict, PDF_NAME(OP));
  229. if (pdf_is_bool(ctx, obj) && proc->op_gs_OP)
  230. proc->op_gs_OP(ctx, proc, pdf_to_bool(ctx, obj));
  231. obj = pdf_dict_get(ctx, dict, PDF_NAME(op));
  232. if (pdf_is_bool(ctx, obj) && proc->op_gs_op)
  233. proc->op_gs_op(ctx, proc, pdf_to_bool(ctx, obj));
  234. obj = pdf_dict_get(ctx, dict, PDF_NAME(OPM));
  235. if (pdf_is_int(ctx, obj) && proc->op_gs_OPM)
  236. proc->op_gs_OPM(ctx, proc, pdf_to_int(ctx, obj));
  237. obj = pdf_dict_get(ctx, dict, PDF_NAME(UseBlackPtComp));
  238. if (pdf_is_name(ctx, obj) && proc->op_gs_UseBlackPtComp)
  239. proc->op_gs_UseBlackPtComp(ctx, proc, obj);
  240. /* transfer functions */
  241. obj = pdf_dict_get(ctx, dict, PDF_NAME(TR2));
  242. if (pdf_is_name(ctx, obj))
  243. if (!pdf_name_eq(ctx, obj, PDF_NAME(Identity)) && !pdf_name_eq(ctx, obj, PDF_NAME(Default)))
  244. fz_warn(ctx, "ignoring transfer function");
  245. if (!obj) /* TR is ignored in the presence of TR2 */
  246. {
  247. pdf_obj *tr = pdf_dict_get(ctx, dict, PDF_NAME(TR));
  248. if (pdf_is_name(ctx, tr))
  249. if (!pdf_name_eq(ctx, tr, PDF_NAME(Identity)))
  250. fz_warn(ctx, "ignoring transfer function");
  251. }
  252. /* transparency state */
  253. obj = pdf_dict_get(ctx, dict, PDF_NAME(CA));
  254. if (pdf_is_number(ctx, obj) && proc->op_gs_CA)
  255. proc->op_gs_CA(ctx, proc, pdf_to_real(ctx, obj));
  256. obj = pdf_dict_get(ctx, dict, PDF_NAME(ca));
  257. if (pdf_is_number(ctx, obj) && proc->op_gs_ca)
  258. proc->op_gs_ca(ctx, proc, pdf_to_real(ctx, obj));
  259. obj = pdf_dict_get(ctx, dict, PDF_NAME(BM));
  260. if (pdf_is_array(ctx, obj))
  261. obj = pdf_array_get(ctx, obj, 0);
  262. if (pdf_is_name(ctx, obj) && proc->op_gs_BM)
  263. proc->op_gs_BM(ctx, proc, pdf_to_name(ctx, obj));
  264. obj = pdf_dict_get(ctx, dict, PDF_NAME(SMask));
  265. if (proc->op_gs_SMask)
  266. {
  267. if (pdf_is_dict(ctx, obj))
  268. {
  269. pdf_obj *xobj, *s, *bc, *tr;
  270. float softmask_bc[FZ_MAX_COLORS];
  271. fz_colorspace *softmask_cs;
  272. int colorspace_n = 1;
  273. int k, luminosity;
  274. xobj = pdf_dict_get(ctx, obj, PDF_NAME(G));
  275. softmask_cs = pdf_xobject_colorspace(ctx, xobj);
  276. fz_try(ctx)
  277. {
  278. if (softmask_cs)
  279. colorspace_n = fz_colorspace_n(ctx, softmask_cs);
  280. /* Default background color is black. */
  281. for (k = 0; k < colorspace_n; k++)
  282. softmask_bc[k] = 0;
  283. /* Which in CMYK means not all zeros! This should really be
  284. * a test for subtractive color spaces, but this will have
  285. * to do for now. */
  286. if (fz_colorspace_is_cmyk(ctx, softmask_cs))
  287. {
  288. /* Default background color is black. */
  289. for (k = 0; k < colorspace_n; k++)
  290. softmask_bc[k] = 0;
  291. /* Which in CMYK means not all zeros! This should really be
  292. * a test for subtractive color spaces, but this will have
  293. * to do for now. */
  294. if (fz_colorspace_is_cmyk(ctx, softmask_cs))
  295. softmask_bc[3] = 1.0f;
  296. }
  297. bc = pdf_dict_get(ctx, obj, PDF_NAME(BC));
  298. if (pdf_is_array(ctx, bc))
  299. {
  300. for (k = 0; k < colorspace_n; k++)
  301. softmask_bc[k] = pdf_array_get_real(ctx, bc, k);
  302. }
  303. s = pdf_dict_get(ctx, obj, PDF_NAME(S));
  304. if (pdf_name_eq(ctx, s, PDF_NAME(Luminosity)))
  305. luminosity = 1;
  306. else
  307. luminosity = 0;
  308. tr = pdf_dict_get(ctx, obj, PDF_NAME(TR));
  309. if (tr && pdf_name_eq(ctx, tr, PDF_NAME(Identity)))
  310. tr = NULL;
  311. proc->op_gs_SMask(ctx, proc, xobj, softmask_cs, softmask_bc, luminosity, tr);
  312. }
  313. fz_always(ctx)
  314. fz_drop_colorspace(ctx, softmask_cs);
  315. fz_catch(ctx)
  316. fz_rethrow(ctx);
  317. }
  318. else if (pdf_is_name(ctx, obj) && pdf_name_eq(ctx, obj, PDF_NAME(None)))
  319. {
  320. proc->op_gs_SMask(ctx, proc, NULL, NULL, NULL, 0, NULL);
  321. }
  322. }
  323. }
  324. static void
  325. pdf_process_Do(fz_context *ctx, pdf_processor *proc, pdf_csi *csi)
  326. {
  327. pdf_obj *xres, *xobj, *subtype;
  328. xres = pdf_dict_get(ctx, csi->rdb, PDF_NAME(XObject));
  329. xobj = pdf_dict_gets(ctx, xres, csi->name);
  330. if (!xobj)
  331. fz_throw(ctx, FZ_ERROR_SYNTAX, "cannot find XObject resource '%s'", csi->name);
  332. subtype = pdf_dict_get(ctx, xobj, PDF_NAME(Subtype));
  333. if (pdf_name_eq(ctx, subtype, PDF_NAME(Form)))
  334. {
  335. pdf_obj *st = pdf_dict_get(ctx, xobj, PDF_NAME(Subtype2));
  336. if (st)
  337. subtype = st;
  338. }
  339. if (!pdf_is_name(ctx, subtype))
  340. fz_throw(ctx, FZ_ERROR_SYNTAX, "no XObject subtype specified");
  341. if (pdf_is_ocg_hidden(ctx, csi->doc, csi->rdb, proc->usage, pdf_dict_get(ctx, xobj, PDF_NAME(OC))))
  342. return;
  343. if (pdf_name_eq(ctx, subtype, PDF_NAME(Form)))
  344. {
  345. if (proc->op_Do_form)
  346. proc->op_Do_form(ctx, proc, csi->name, xobj);
  347. }
  348. else if (pdf_name_eq(ctx, subtype, PDF_NAME(Image)))
  349. {
  350. if (proc->op_Do_image)
  351. {
  352. fz_image *image = NULL;
  353. if (proc->requirements && PDF_PROCESSOR_REQUIRES_DECODED_IMAGES)
  354. image = pdf_load_image(ctx, csi->doc, xobj);
  355. fz_try(ctx)
  356. proc->op_Do_image(ctx, proc, csi->name, image);
  357. fz_always(ctx)
  358. fz_drop_image(ctx, image);
  359. fz_catch(ctx)
  360. fz_rethrow(ctx);
  361. }
  362. }
  363. else if (!strcmp(pdf_to_name(ctx, subtype), "PS"))
  364. fz_warn(ctx, "ignoring XObject with subtype PS");
  365. else
  366. fz_warn(ctx, "ignoring XObject with unknown subtype: '%s'", pdf_to_name(ctx, subtype));
  367. }
  368. static void
  369. pdf_process_CS(fz_context *ctx, pdf_processor *proc, pdf_csi *csi, int stroke)
  370. {
  371. fz_colorspace *cs;
  372. if (!proc->op_CS || !proc->op_cs)
  373. return;
  374. if (!strcmp(csi->name, "Pattern"))
  375. {
  376. if (stroke)
  377. proc->op_CS(ctx, proc, "Pattern", NULL);
  378. else
  379. proc->op_cs(ctx, proc, "Pattern", NULL);
  380. return;
  381. }
  382. if (!strcmp(csi->name, "DeviceGray"))
  383. cs = fz_keep_colorspace(ctx, fz_device_gray(ctx));
  384. else if (!strcmp(csi->name, "DeviceRGB"))
  385. cs = fz_keep_colorspace(ctx, fz_device_rgb(ctx));
  386. else if (!strcmp(csi->name, "DeviceCMYK"))
  387. cs = fz_keep_colorspace(ctx, fz_device_cmyk(ctx));
  388. else
  389. {
  390. pdf_obj *csres, *csobj;
  391. csres = pdf_dict_get(ctx, csi->rdb, PDF_NAME(ColorSpace));
  392. csobj = pdf_dict_gets(ctx, csres, csi->name);
  393. if (!csobj)
  394. fz_throw(ctx, FZ_ERROR_SYNTAX, "cannot find ColorSpace resource '%s'", csi->name);
  395. if (pdf_is_array(ctx, csobj) && pdf_array_len(ctx, csobj) == 1 && pdf_name_eq(ctx, pdf_array_get(ctx, csobj, 0), PDF_NAME(Pattern)))
  396. {
  397. if (stroke)
  398. proc->op_CS(ctx, proc, "Pattern", NULL);
  399. else
  400. proc->op_cs(ctx, proc, "Pattern", NULL);
  401. return;
  402. }
  403. cs = pdf_load_colorspace(ctx, csobj);
  404. }
  405. fz_try(ctx)
  406. {
  407. if (stroke)
  408. proc->op_CS(ctx, proc, csi->name, cs);
  409. else
  410. proc->op_cs(ctx, proc, csi->name, cs);
  411. }
  412. fz_always(ctx)
  413. fz_drop_colorspace(ctx, cs);
  414. fz_catch(ctx)
  415. fz_rethrow(ctx);
  416. }
  417. static void
  418. pdf_process_SC(fz_context *ctx, pdf_processor *proc, pdf_csi *csi, int stroke)
  419. {
  420. if (csi->name[0])
  421. {
  422. pdf_obj *patres, *patobj;
  423. int type;
  424. patres = pdf_dict_get(ctx, csi->rdb, PDF_NAME(Pattern));
  425. patobj = pdf_dict_gets(ctx, patres, csi->name);
  426. if (!patobj)
  427. fz_throw(ctx, FZ_ERROR_SYNTAX, "cannot find Pattern resource '%s'", csi->name);
  428. type = pdf_dict_get_int(ctx, patobj, PDF_NAME(PatternType));
  429. if (type == 1)
  430. {
  431. if (proc->op_SC_pattern && proc->op_sc_pattern)
  432. {
  433. pdf_pattern *pat = pdf_load_pattern(ctx, csi->doc, patobj);
  434. fz_try(ctx)
  435. {
  436. if (stroke)
  437. proc->op_SC_pattern(ctx, proc, csi->name, pat, csi->top, csi->stack);
  438. else
  439. proc->op_sc_pattern(ctx, proc, csi->name, pat, csi->top, csi->stack);
  440. }
  441. fz_always(ctx)
  442. pdf_drop_pattern(ctx, pat);
  443. fz_catch(ctx)
  444. fz_rethrow(ctx);
  445. }
  446. }
  447. else if (type == 2)
  448. {
  449. if (proc->op_SC_shade && proc->op_sc_shade)
  450. {
  451. fz_shade *shade = pdf_load_shading(ctx, csi->doc, patobj);
  452. fz_try(ctx)
  453. {
  454. if (stroke)
  455. proc->op_SC_shade(ctx, proc, csi->name, shade);
  456. else
  457. proc->op_sc_shade(ctx, proc, csi->name, shade);
  458. }
  459. fz_always(ctx)
  460. fz_drop_shade(ctx, shade);
  461. fz_catch(ctx)
  462. fz_rethrow(ctx);
  463. }
  464. }
  465. else
  466. {
  467. fz_throw(ctx, FZ_ERROR_SYNTAX, "unknown pattern type: %d", type);
  468. }
  469. }
  470. else
  471. {
  472. if (proc->op_SC_color && proc->op_sc_color)
  473. {
  474. if (stroke)
  475. proc->op_SC_color(ctx, proc, csi->top, csi->stack);
  476. else
  477. proc->op_sc_color(ctx, proc, csi->top, csi->stack);
  478. }
  479. }
  480. }
  481. static pdf_obj *
  482. resolve_properties(fz_context *ctx, pdf_csi *csi, pdf_obj *obj)
  483. {
  484. if (pdf_is_name(ctx, obj))
  485. return pdf_dict_get(ctx, pdf_dict_get(ctx, csi->rdb, PDF_NAME(Properties)), obj);
  486. else
  487. return obj;
  488. }
  489. static void
  490. pdf_process_BDC(fz_context *ctx, pdf_processor *proc, pdf_csi *csi)
  491. {
  492. if (proc->op_BDC)
  493. proc->op_BDC(ctx, proc, csi->name, csi->obj, resolve_properties(ctx, csi, csi->obj));
  494. /* Already hidden, no need to look further */
  495. if (proc->hidden > 0)
  496. {
  497. ++proc->hidden;
  498. return;
  499. }
  500. /* We only look at OC groups here */
  501. if (strcmp(csi->name, "OC"))
  502. return;
  503. if (pdf_is_ocg_hidden(ctx, csi->doc, csi->rdb, proc->usage, csi->obj))
  504. ++proc->hidden;
  505. }
  506. static void
  507. pdf_process_BMC(fz_context *ctx, pdf_processor *proc, pdf_csi *csi, const char *name)
  508. {
  509. if (proc->op_BMC)
  510. proc->op_BMC(ctx, proc, name);
  511. if (proc->hidden > 0)
  512. ++proc->hidden;
  513. }
  514. static void
  515. pdf_process_EMC(fz_context *ctx, pdf_processor *proc, pdf_csi *csi)
  516. {
  517. if (proc->op_EMC)
  518. proc->op_EMC(ctx, proc);
  519. if (proc->hidden > 0)
  520. --proc->hidden;
  521. }
  522. static void
  523. pdf_process_gsave(fz_context *ctx, pdf_processor *proc, pdf_csi *csi)
  524. {
  525. ++csi->gstate;
  526. if (proc->op_q)
  527. proc->op_q(ctx, proc);
  528. }
  529. static void
  530. pdf_process_grestore(fz_context *ctx, pdf_processor *proc, pdf_csi *csi)
  531. {
  532. --csi->gstate;
  533. if (proc->op_Q)
  534. proc->op_Q(ctx, proc);
  535. }
  536. static void
  537. pdf_process_end(fz_context *ctx, pdf_processor *proc, pdf_csi *csi)
  538. {
  539. if (proc->op_EOD)
  540. proc->op_EOD(ctx, proc);
  541. while (csi->gstate > 0)
  542. pdf_process_grestore(ctx, proc, csi);
  543. if (proc->op_END)
  544. proc->op_END(ctx, proc);
  545. }
  546. static int is_known_bad_word(const char *word)
  547. {
  548. switch (*word)
  549. {
  550. case 'I': return !strcmp(word, "Infinity");
  551. case 'N': return !strcmp(word, "NaN");
  552. case 'i': return !strcmp(word, "inf");
  553. case 'n': return !strcmp(word, "nan");
  554. }
  555. return 0;
  556. }
  557. #define A(a) (a)
  558. #define B(a,b) (a | b << 8)
  559. #define C(a,b,c) (a | b << 8 | c << 16)
  560. static void
  561. pdf_process_keyword(fz_context *ctx, pdf_processor *proc, pdf_csi *csi, fz_stream *stm, char *word)
  562. {
  563. float *s = csi->stack;
  564. char csname[40];
  565. int key;
  566. key = word[0];
  567. if (word[1])
  568. {
  569. key |= word[1] << 8;
  570. if (word[2])
  571. {
  572. key |= word[2] << 16;
  573. if (word[3])
  574. key = 0;
  575. }
  576. }
  577. switch (key)
  578. {
  579. default:
  580. if (!csi->xbalance)
  581. {
  582. if (is_known_bad_word(word))
  583. fz_warn(ctx, "unknown keyword: '%s'", word);
  584. else
  585. fz_throw(ctx, FZ_ERROR_SYNTAX, "unknown keyword: '%s'", word);
  586. }
  587. break;
  588. /* general graphics state */
  589. case A('w'): if (proc->op_w) proc->op_w(ctx, proc, s[0]); break;
  590. case A('j'): if (proc->op_j) proc->op_j(ctx, proc, fz_clampi(s[0], 0, 2)); break;
  591. case A('J'): if (proc->op_J) proc->op_J(ctx, proc, fz_clampi(s[0], 0, 2)); break;
  592. case A('M'): if (proc->op_M) proc->op_M(ctx, proc, s[0]); break;
  593. case A('d'): if (proc->op_d) proc->op_d(ctx, proc, csi->obj, s[0]); break;
  594. case B('r','i'): if (proc->op_ri) proc->op_ri(ctx, proc, csi->name); break;
  595. case A('i'): if (proc->op_i) proc->op_i(ctx, proc, s[0]); break;
  596. case B('g','s'):
  597. {
  598. pdf_obj *gsres, *gsobj;
  599. gsres = pdf_dict_get(ctx, csi->rdb, PDF_NAME(ExtGState));
  600. gsobj = pdf_dict_gets(ctx, gsres, csi->name);
  601. if (!gsobj)
  602. fz_throw(ctx, FZ_ERROR_SYNTAX, "cannot find ExtGState resource '%s'", csi->name);
  603. if (proc->op_gs_begin)
  604. proc->op_gs_begin(ctx, proc, csi->name, gsobj);
  605. pdf_process_extgstate(ctx, proc, csi, gsobj);
  606. if (proc->op_gs_end)
  607. proc->op_gs_end(ctx, proc);
  608. }
  609. break;
  610. /* special graphics state */
  611. case A('q'): pdf_process_gsave(ctx, proc, csi); break;
  612. case A('Q'): pdf_process_grestore(ctx, proc, csi); break;
  613. case B('c','m'): if (proc->op_cm) proc->op_cm(ctx, proc, s[0], s[1], s[2], s[3], s[4], s[5]); break;
  614. /* path construction */
  615. case A('m'): if (proc->op_m) proc->op_m(ctx, proc, s[0], s[1]); break;
  616. case A('l'): if (proc->op_l) proc->op_l(ctx, proc, s[0], s[1]); break;
  617. case A('c'): if (proc->op_c) proc->op_c(ctx, proc, s[0], s[1], s[2], s[3], s[4], s[5]); break;
  618. case A('v'): if (proc->op_v) proc->op_v(ctx, proc, s[0], s[1], s[2], s[3]); break;
  619. case A('y'): if (proc->op_y) proc->op_y(ctx, proc, s[0], s[1], s[2], s[3]); break;
  620. case A('h'): if (proc->op_h) proc->op_h(ctx, proc); break;
  621. case B('r','e'): if (proc->op_re) proc->op_re(ctx, proc, s[0], s[1], s[2], s[3]); break;
  622. /* path painting */
  623. case A('S'): if (proc->op_S) proc->op_S(ctx, proc); break;
  624. case A('s'): if (proc->op_s) proc->op_s(ctx, proc); break;
  625. case A('F'): if (proc->op_F) proc->op_F(ctx, proc); break;
  626. case A('f'): if (proc->op_f) proc->op_f(ctx, proc); break;
  627. case B('f','*'): if (proc->op_fstar) proc->op_fstar(ctx, proc); break;
  628. case A('B'): if (proc->op_B) proc->op_B(ctx, proc); break;
  629. case B('B','*'): if (proc->op_Bstar) proc->op_Bstar(ctx, proc); break;
  630. case A('b'): if (proc->op_b) proc->op_b(ctx, proc); break;
  631. case B('b','*'): if (proc->op_bstar) proc->op_bstar(ctx, proc); break;
  632. case A('n'): if (proc->op_n) proc->op_n(ctx, proc); break;
  633. /* path clipping */
  634. case A('W'): if (proc->op_W) proc->op_W(ctx, proc); break;
  635. case B('W','*'): if (proc->op_Wstar) proc->op_Wstar(ctx, proc); break;
  636. /* text objects */
  637. case B('B','T'): csi->in_text = 1; if (proc->op_BT) proc->op_BT(ctx, proc); break;
  638. case B('E','T'): csi->in_text = 0; if (proc->op_ET) proc->op_ET(ctx, proc); break;
  639. /* text state */
  640. case B('T','c'): if (proc->op_Tc) proc->op_Tc(ctx, proc, s[0]); break;
  641. case B('T','w'): if (proc->op_Tw) proc->op_Tw(ctx, proc, s[0]); break;
  642. case B('T','z'): if (proc->op_Tz) proc->op_Tz(ctx, proc, s[0]); break;
  643. case B('T','L'): if (proc->op_TL) proc->op_TL(ctx, proc, s[0]); break;
  644. case B('T','r'): if (proc->op_Tr) proc->op_Tr(ctx, proc, s[0]); break;
  645. case B('T','s'): if (proc->op_Ts) proc->op_Ts(ctx, proc, s[0]); break;
  646. case B('T','f'):
  647. if (proc->op_Tf)
  648. {
  649. pdf_obj *fontres, *fontobj;
  650. pdf_font_desc *font;
  651. fontres = pdf_dict_get(ctx, csi->rdb, PDF_NAME(Font));
  652. fontobj = pdf_dict_gets(ctx, fontres, csi->name);
  653. if (pdf_is_dict(ctx, fontobj))
  654. font = pdf_try_load_font(ctx, csi->doc, csi->rdb, fontobj, csi->cookie);
  655. else
  656. font = pdf_load_hail_mary_font(ctx, csi->doc);
  657. fz_try(ctx)
  658. proc->op_Tf(ctx, proc, csi->name, font, s[0]);
  659. fz_always(ctx)
  660. pdf_drop_font(ctx, font);
  661. fz_catch(ctx)
  662. fz_rethrow(ctx);
  663. }
  664. break;
  665. /* text positioning */
  666. case B('T','d'): if (proc->op_Td) proc->op_Td(ctx, proc, s[0], s[1]); break;
  667. case B('T','D'): if (proc->op_TD) proc->op_TD(ctx, proc, s[0], s[1]); break;
  668. case B('T','m'): if (proc->op_Tm) proc->op_Tm(ctx, proc, s[0], s[1], s[2], s[3], s[4], s[5]); break;
  669. case B('T','*'): if (proc->op_Tstar) proc->op_Tstar(ctx, proc); break;
  670. /* text showing */
  671. case B('T','J'): if (proc->op_TJ) proc->op_TJ(ctx, proc, csi->obj); break;
  672. case B('T','j'):
  673. if (proc->op_Tj)
  674. {
  675. if (csi->string_len > 0)
  676. proc->op_Tj(ctx, proc, csi->string, csi->string_len);
  677. else
  678. proc->op_Tj(ctx, proc, pdf_to_str_buf(ctx, csi->obj), pdf_to_str_len(ctx, csi->obj));
  679. }
  680. break;
  681. case A('\''):
  682. if (proc->op_squote)
  683. {
  684. if (csi->string_len > 0)
  685. proc->op_squote(ctx, proc, csi->string, csi->string_len);
  686. else
  687. proc->op_squote(ctx, proc, pdf_to_str_buf(ctx, csi->obj), pdf_to_str_len(ctx, csi->obj));
  688. }
  689. break;
  690. case A('"'):
  691. if (proc->op_dquote)
  692. {
  693. if (csi->string_len > 0)
  694. proc->op_dquote(ctx, proc, s[0], s[1], csi->string, csi->string_len);
  695. else
  696. proc->op_dquote(ctx, proc, s[0], s[1], pdf_to_str_buf(ctx, csi->obj), pdf_to_str_len(ctx, csi->obj));
  697. }
  698. break;
  699. /* type 3 fonts */
  700. case B('d','0'): if (proc->op_d0) proc->op_d0(ctx, proc, s[0], s[1]); break;
  701. case B('d','1'): if (proc->op_d1) proc->op_d1(ctx, proc, s[0], s[1], s[2], s[3], s[4], s[5]); break;
  702. /* color */
  703. case B('C','S'): pdf_process_CS(ctx, proc, csi, 1); break;
  704. case B('c','s'): pdf_process_CS(ctx, proc, csi, 0); break;
  705. case B('S','C'): pdf_process_SC(ctx, proc, csi, 1); break;
  706. case B('s','c'): pdf_process_SC(ctx, proc, csi, 0); break;
  707. case C('S','C','N'): pdf_process_SC(ctx, proc, csi, 1); break;
  708. case C('s','c','n'): pdf_process_SC(ctx, proc, csi, 0); break;
  709. case A('G'): if (proc->op_G) proc->op_G(ctx, proc, s[0]); break;
  710. case A('g'): if (proc->op_g) proc->op_g(ctx, proc, s[0]); break;
  711. case B('R','G'): if (proc->op_RG) proc->op_RG(ctx, proc, s[0], s[1], s[2]); break;
  712. case B('r','g'): if (proc->op_rg) proc->op_rg(ctx, proc, s[0], s[1], s[2]); break;
  713. case A('K'): if (proc->op_K) proc->op_K(ctx, proc, s[0], s[1], s[2], s[3]); break;
  714. case A('k'): if (proc->op_k) proc->op_k(ctx, proc, s[0], s[1], s[2], s[3]); break;
  715. /* shadings, images, xobjects */
  716. case B('B','I'):
  717. {
  718. fz_image *img = parse_inline_image(ctx, csi, stm, csname, sizeof csname);
  719. fz_try(ctx)
  720. {
  721. if (proc->op_BI)
  722. proc->op_BI(ctx, proc, img, csname[0] ? csname : NULL);
  723. }
  724. fz_always(ctx)
  725. fz_drop_image(ctx, img);
  726. fz_catch(ctx)
  727. fz_rethrow(ctx);
  728. }
  729. break;
  730. case B('s','h'):
  731. if (proc->op_sh)
  732. {
  733. pdf_obj *shaderes, *shadeobj;
  734. fz_shade *shade;
  735. shaderes = pdf_dict_get(ctx, csi->rdb, PDF_NAME(Shading));
  736. shadeobj = pdf_dict_gets(ctx, shaderes, csi->name);
  737. if (!shadeobj)
  738. fz_throw(ctx, FZ_ERROR_SYNTAX, "cannot find Shading resource '%s'", csi->name);
  739. shade = pdf_load_shading(ctx, csi->doc, shadeobj);
  740. fz_try(ctx)
  741. proc->op_sh(ctx, proc, csi->name, shade);
  742. fz_always(ctx)
  743. fz_drop_shade(ctx, shade);
  744. fz_catch(ctx)
  745. fz_rethrow(ctx);
  746. }
  747. break;
  748. case B('D','o'): pdf_process_Do(ctx, proc, csi); break;
  749. /* marked content */
  750. case B('M','P'): if (proc->op_MP) proc->op_MP(ctx, proc, csi->name); break;
  751. case B('D','P'): if (proc->op_DP) proc->op_DP(ctx, proc, csi->name, csi->obj, resolve_properties(ctx, csi, csi->obj)); break;
  752. case C('B','M','C'): pdf_process_BMC(ctx, proc, csi, csi->name); break;
  753. case C('B','D','C'): pdf_process_BDC(ctx, proc, csi); break;
  754. case C('E','M','C'): pdf_process_EMC(ctx, proc, csi); break;
  755. /* compatibility */
  756. case B('B','X'): ++csi->xbalance; if (proc->op_BX) proc->op_BX(ctx, proc); break;
  757. case B('E','X'): --csi->xbalance; if (proc->op_EX) proc->op_EX(ctx, proc); break;
  758. }
  759. }
  760. static void
  761. pdf_process_stream(fz_context *ctx, pdf_processor *proc, pdf_csi *csi, fz_stream *stm)
  762. {
  763. pdf_document *doc = csi->doc;
  764. pdf_lexbuf *buf = csi->buf;
  765. fz_cookie *cookie = csi->cookie;
  766. pdf_token tok = PDF_TOK_ERROR;
  767. int in_text_array = 0;
  768. int syntax_errors = 0;
  769. /* make sure we have a clean slate if we come here from flush_text */
  770. pdf_clear_stack(ctx, csi);
  771. fz_var(in_text_array);
  772. fz_var(tok);
  773. if (cookie)
  774. {
  775. cookie->progress_max = (size_t)-1;
  776. cookie->progress = 0;
  777. }
  778. do
  779. {
  780. fz_try(ctx)
  781. {
  782. do
  783. {
  784. /* Check the cookie */
  785. if (cookie)
  786. {
  787. if (cookie->abort)
  788. {
  789. tok = PDF_TOK_EOF;
  790. break;
  791. }
  792. cookie->progress++;
  793. }
  794. tok = pdf_lex(ctx, stm, buf);
  795. if (in_text_array)
  796. {
  797. switch(tok)
  798. {
  799. case PDF_TOK_CLOSE_ARRAY:
  800. in_text_array = 0;
  801. break;
  802. case PDF_TOK_REAL:
  803. pdf_array_push_real(ctx, csi->obj, buf->f);
  804. break;
  805. case PDF_TOK_INT:
  806. pdf_array_push_int(ctx, csi->obj, buf->i);
  807. break;
  808. case PDF_TOK_STRING:
  809. pdf_array_push_string(ctx, csi->obj, buf->scratch, buf->len);
  810. break;
  811. case PDF_TOK_EOF:
  812. break;
  813. case PDF_TOK_KEYWORD:
  814. if (buf->scratch[0] == 'T' && (buf->scratch[1] == 'w' || buf->scratch[1] == 'c') && buf->scratch[2] == 0)
  815. {
  816. int n = pdf_array_len(ctx, csi->obj);
  817. if (n > 0)
  818. {
  819. pdf_obj *o = pdf_array_get(ctx, csi->obj, n-1);
  820. if (pdf_is_number(ctx, o))
  821. {
  822. csi->stack[0] = pdf_to_real(ctx, o);
  823. pdf_array_delete(ctx, csi->obj, n-1);
  824. pdf_process_keyword(ctx, proc, csi, stm, buf->scratch);
  825. }
  826. }
  827. }
  828. /* Deliberate Fallthrough! */
  829. default:
  830. fz_throw(ctx, FZ_ERROR_SYNTAX, "syntax error in array");
  831. }
  832. }
  833. else switch (tok)
  834. {
  835. case PDF_TOK_ENDSTREAM:
  836. case PDF_TOK_EOF:
  837. tok = PDF_TOK_EOF;
  838. break;
  839. case PDF_TOK_OPEN_ARRAY:
  840. if (csi->obj)
  841. {
  842. pdf_drop_obj(ctx, csi->obj);
  843. csi->obj = NULL;
  844. }
  845. if (csi->in_text)
  846. {
  847. in_text_array = 1;
  848. csi->obj = pdf_new_array(ctx, doc, 4);
  849. }
  850. else
  851. {
  852. csi->obj = pdf_parse_array(ctx, doc, stm, buf);
  853. }
  854. break;
  855. case PDF_TOK_OPEN_DICT:
  856. if (csi->obj)
  857. {
  858. pdf_drop_obj(ctx, csi->obj);
  859. csi->obj = NULL;
  860. }
  861. csi->obj = pdf_parse_dict(ctx, doc, stm, buf);
  862. break;
  863. case PDF_TOK_NAME:
  864. if (csi->name[0])
  865. {
  866. pdf_drop_obj(ctx, csi->obj);
  867. csi->obj = NULL;
  868. csi->obj = pdf_new_name(ctx, buf->scratch);
  869. }
  870. else
  871. fz_strlcpy(csi->name, buf->scratch, sizeof(csi->name));
  872. break;
  873. case PDF_TOK_INT:
  874. if (csi->top < (int)nelem(csi->stack)) {
  875. csi->stack[csi->top] = buf->i;
  876. csi->top ++;
  877. }
  878. else
  879. fz_throw(ctx, FZ_ERROR_SYNTAX, "stack overflow");
  880. break;
  881. case PDF_TOK_REAL:
  882. if (csi->top < (int)nelem(csi->stack)) {
  883. csi->stack[csi->top] = buf->f;
  884. csi->top ++;
  885. }
  886. else
  887. fz_throw(ctx, FZ_ERROR_SYNTAX, "stack overflow");
  888. break;
  889. case PDF_TOK_STRING:
  890. if (buf->len <= sizeof(csi->string))
  891. {
  892. memcpy(csi->string, buf->scratch, buf->len);
  893. csi->string_len = buf->len;
  894. }
  895. else
  896. {
  897. if (csi->obj)
  898. {
  899. pdf_drop_obj(ctx, csi->obj);
  900. csi->obj = NULL;
  901. }
  902. csi->obj = pdf_new_string(ctx, buf->scratch, buf->len);
  903. }
  904. break;
  905. case PDF_TOK_KEYWORD:
  906. pdf_process_keyword(ctx, proc, csi, stm, buf->scratch);
  907. pdf_clear_stack(ctx, csi);
  908. break;
  909. default:
  910. fz_throw(ctx, FZ_ERROR_SYNTAX, "syntax error in content stream");
  911. }
  912. }
  913. while (tok != PDF_TOK_EOF);
  914. }
  915. fz_always(ctx)
  916. {
  917. pdf_clear_stack(ctx, csi);
  918. }
  919. fz_catch(ctx)
  920. {
  921. int caught = fz_caught(ctx);
  922. if (cookie)
  923. {
  924. if (caught == FZ_ERROR_TRYLATER)
  925. {
  926. fz_ignore_error(ctx);
  927. cookie->incomplete++;
  928. tok = PDF_TOK_EOF;
  929. }
  930. else if (caught == FZ_ERROR_ABORT)
  931. {
  932. fz_rethrow(ctx);
  933. }
  934. else if (caught == FZ_ERROR_SYNTAX)
  935. {
  936. fz_report_error(ctx);
  937. cookie->errors++;
  938. if (++syntax_errors >= MAX_SYNTAX_ERRORS)
  939. {
  940. fz_warn(ctx, "too many syntax errors; ignoring rest of page");
  941. tok = PDF_TOK_EOF;
  942. }
  943. }
  944. else
  945. {
  946. fz_rethrow(ctx);
  947. }
  948. }
  949. else
  950. {
  951. if (caught == FZ_ERROR_TRYLATER)
  952. {
  953. fz_ignore_error(ctx);
  954. tok = PDF_TOK_EOF;
  955. }
  956. else if (caught == FZ_ERROR_ABORT)
  957. {
  958. fz_rethrow(ctx);
  959. }
  960. else if (caught == FZ_ERROR_SYNTAX)
  961. {
  962. fz_report_error(ctx);
  963. if (++syntax_errors >= MAX_SYNTAX_ERRORS)
  964. {
  965. fz_warn(ctx, "too many syntax errors; ignoring rest of page");
  966. tok = PDF_TOK_EOF;
  967. }
  968. }
  969. else
  970. {
  971. fz_rethrow(ctx);
  972. }
  973. }
  974. /* If we do catch an error, then reset ourselves to a base lexing state */
  975. in_text_array = 0;
  976. }
  977. }
  978. while (tok != PDF_TOK_EOF);
  979. if (syntax_errors > 0)
  980. fz_warn(ctx, "encountered syntax errors; page may not be correct");
  981. }
  982. void pdf_processor_push_resources(fz_context *ctx, pdf_processor *proc, pdf_obj *res)
  983. {
  984. proc->push_resources(ctx, proc, res);
  985. }
  986. pdf_obj *pdf_processor_pop_resources(fz_context *ctx, pdf_processor *proc)
  987. {
  988. return proc->pop_resources(ctx, proc);
  989. }
  990. void
  991. pdf_process_raw_contents(fz_context *ctx, pdf_processor *proc, pdf_document *doc, pdf_obj *rdb, pdf_obj *stmobj, fz_cookie *cookie)
  992. {
  993. pdf_csi csi;
  994. pdf_lexbuf buf;
  995. fz_stream *stm = NULL;
  996. if (!stmobj)
  997. return;
  998. fz_var(stm);
  999. pdf_lexbuf_init(ctx, &buf, PDF_LEXBUF_SMALL);
  1000. pdf_init_csi(ctx, &csi, doc, rdb, &buf, cookie);
  1001. fz_try(ctx)
  1002. {
  1003. fz_defer_reap_start(ctx);
  1004. stm = pdf_open_contents_stream(ctx, doc, stmobj);
  1005. pdf_process_stream(ctx, proc, &csi, stm);
  1006. pdf_process_end(ctx, proc, &csi);
  1007. }
  1008. fz_always(ctx)
  1009. {
  1010. fz_defer_reap_end(ctx);
  1011. fz_drop_stream(ctx, stm);
  1012. pdf_clear_stack(ctx, &csi);
  1013. pdf_lexbuf_fin(ctx, &buf);
  1014. }
  1015. fz_catch(ctx)
  1016. {
  1017. proc->close_processor = NULL; /* aborted run, don't warn about unclosed processor */
  1018. fz_rethrow(ctx);
  1019. }
  1020. }
  1021. void
  1022. pdf_process_contents(fz_context *ctx, pdf_processor *proc, pdf_document *doc, pdf_obj *rdb, pdf_obj *stmobj, fz_cookie *cookie, pdf_obj **out_res)
  1023. {
  1024. pdf_processor_push_resources(ctx, proc, rdb);
  1025. fz_try(ctx)
  1026. pdf_process_raw_contents(ctx, proc, doc, rdb, stmobj, cookie);
  1027. fz_always(ctx)
  1028. {
  1029. pdf_obj *res = pdf_processor_pop_resources(ctx, proc);
  1030. if (out_res)
  1031. *out_res = res;
  1032. else
  1033. pdf_drop_obj(ctx, res);
  1034. }
  1035. fz_catch(ctx)
  1036. fz_rethrow(ctx);
  1037. }
  1038. /* Bug 702543: It looks like certain types of annotation are never
  1039. * printed. */
  1040. static int
  1041. pdf_should_print_annot(fz_context *ctx, pdf_annot *annot)
  1042. {
  1043. enum pdf_annot_type type = pdf_annot_type(ctx, annot);
  1044. /* We may need to add more types here. */
  1045. if (type == PDF_ANNOT_FILE_ATTACHMENT)
  1046. return 0;
  1047. return 1;
  1048. }
  1049. void
  1050. pdf_process_annot(fz_context *ctx, pdf_processor *proc, pdf_annot *annot, fz_cookie *cookie)
  1051. {
  1052. int flags = pdf_dict_get_int(ctx, annot->obj, PDF_NAME(F));
  1053. fz_matrix matrix;
  1054. pdf_obj *ap;
  1055. if (flags & (PDF_ANNOT_IS_INVISIBLE | PDF_ANNOT_IS_HIDDEN) || annot->hidden_editing)
  1056. return;
  1057. /* popup annotations should never be drawn */
  1058. if (pdf_annot_type(ctx, annot) == PDF_ANNOT_POPUP)
  1059. return;
  1060. if (proc->usage)
  1061. {
  1062. if (!strcmp(proc->usage, "Print"))
  1063. {
  1064. if (!(flags & PDF_ANNOT_IS_PRINT))
  1065. return;
  1066. if (!pdf_should_print_annot(ctx, annot))
  1067. return;
  1068. }
  1069. if (!strcmp(proc->usage, "View") && (flags & PDF_ANNOT_IS_NO_VIEW))
  1070. return;
  1071. }
  1072. /* TODO: NoZoom and NoRotate */
  1073. /* XXX what resources, if any, to use for this check? */
  1074. if (pdf_is_ocg_hidden(ctx, annot->page->doc, NULL, proc->usage, pdf_dict_get(ctx, annot->obj, PDF_NAME(OC))))
  1075. return;
  1076. ap = pdf_annot_ap(ctx, annot);
  1077. if (!ap)
  1078. return;
  1079. matrix = pdf_annot_transform(ctx, annot);
  1080. if (proc->op_q)
  1081. proc->op_q(ctx, proc);
  1082. if (proc->op_cm)
  1083. proc->op_cm(ctx, proc,
  1084. matrix.a, matrix.b,
  1085. matrix.c, matrix.d,
  1086. matrix.e, matrix.f);
  1087. if (proc->op_Do_form)
  1088. proc->op_Do_form(ctx, proc, NULL, ap);
  1089. if (proc->op_Q)
  1090. proc->op_Q(ctx, proc);
  1091. }
  1092. void
  1093. pdf_process_glyph(fz_context *ctx, pdf_processor *proc, pdf_document *doc, pdf_obj *rdb, fz_buffer *contents)
  1094. {
  1095. pdf_csi csi;
  1096. pdf_lexbuf buf;
  1097. fz_stream *stm = NULL;
  1098. fz_var(stm);
  1099. if (!contents)
  1100. return;
  1101. pdf_lexbuf_init(ctx, &buf, PDF_LEXBUF_SMALL);
  1102. pdf_init_csi(ctx, &csi, doc, rdb, &buf, NULL);
  1103. fz_try(ctx)
  1104. {
  1105. pdf_processor_push_resources(ctx, proc, rdb);
  1106. stm = fz_open_buffer(ctx, contents);
  1107. pdf_process_stream(ctx, proc, &csi, stm);
  1108. pdf_process_end(ctx, proc, &csi);
  1109. }
  1110. fz_always(ctx)
  1111. {
  1112. pdf_drop_obj(ctx, pdf_processor_pop_resources(ctx, proc));
  1113. fz_drop_stream(ctx, stm);
  1114. pdf_clear_stack(ctx, &csi);
  1115. pdf_lexbuf_fin(ctx, &buf);
  1116. }
  1117. fz_catch(ctx)
  1118. {
  1119. /* Note: Any SYNTAX errors should have been swallowed
  1120. * by pdf_process_stream, but in case any escape from other
  1121. * functions, recast the error type here to be safe. */
  1122. fz_morph_error(ctx, FZ_ERROR_SYNTAX, FZ_ERROR_FORMAT);
  1123. fz_rethrow(ctx);
  1124. }
  1125. }
  1126. void
  1127. pdf_tos_save(fz_context *ctx, pdf_text_object_state *tos, fz_matrix save[2])
  1128. {
  1129. save[0] = tos->tm;
  1130. save[1] = tos->tlm;
  1131. }
  1132. void
  1133. pdf_tos_restore(fz_context *ctx, pdf_text_object_state *tos, fz_matrix save[2])
  1134. {
  1135. tos->tm = save[0];
  1136. tos->tlm = save[1];
  1137. }
  1138. fz_text *
  1139. pdf_tos_get_text(fz_context *ctx, pdf_text_object_state *tos)
  1140. {
  1141. fz_text *text = tos->text;
  1142. tos->text = NULL;
  1143. return text;
  1144. }
  1145. void
  1146. pdf_tos_reset(fz_context *ctx, pdf_text_object_state *tos, int render)
  1147. {
  1148. tos->text = fz_new_text(ctx);
  1149. tos->text_mode = render;
  1150. tos->text_bbox = fz_empty_rect;
  1151. }
  1152. int
  1153. pdf_tos_make_trm(fz_context *ctx, pdf_text_object_state *tos, pdf_text_state *text, pdf_font_desc *fontdesc, int cid, fz_matrix *trm, float *adv)
  1154. {
  1155. fz_matrix tsm;
  1156. tsm.a = text->size * text->scale;
  1157. tsm.b = 0;
  1158. tsm.c = 0;
  1159. tsm.d = text->size;
  1160. tsm.e = 0;
  1161. tsm.f = text->rise;
  1162. if (fontdesc->wmode == 0)
  1163. {
  1164. pdf_hmtx h = pdf_lookup_hmtx(ctx, fontdesc, cid);
  1165. float w0 = *adv = h.w * 0.001f;
  1166. tos->char_tx = (w0 * text->size + text->char_space) * text->scale;
  1167. tos->char_ty = 0;
  1168. }
  1169. else
  1170. {
  1171. pdf_vmtx v = pdf_lookup_vmtx(ctx, fontdesc, cid);
  1172. float w1 = *adv = v.w * 0.001f;
  1173. tsm.e -= v.x * fabsf(text->size) * 0.001f;
  1174. tsm.f -= v.y * text->size * 0.001f;
  1175. tos->char_tx = 0;
  1176. tos->char_ty = w1 * text->size + text->char_space;
  1177. }
  1178. *trm = fz_concat(tsm, tos->tm);
  1179. tos->cid = cid;
  1180. tos->gid = pdf_font_cid_to_gid(ctx, fontdesc, cid);
  1181. tos->fontdesc = fontdesc;
  1182. /* Compensate for the glyph cache limited positioning precision */
  1183. tos->char_bbox = fz_expand_rect(fz_bound_glyph(ctx, fontdesc->font, tos->gid, *trm), 1);
  1184. return tos->gid;
  1185. }
  1186. void
  1187. pdf_tos_move_after_char(fz_context *ctx, pdf_text_object_state *tos)
  1188. {
  1189. tos->text_bbox = fz_union_rect(tos->text_bbox, tos->char_bbox);
  1190. tos->tm = fz_pre_translate(tos->tm, tos->char_tx, tos->char_ty);
  1191. }
  1192. void
  1193. pdf_tos_translate(pdf_text_object_state *tos, float tx, float ty)
  1194. {
  1195. tos->tlm = fz_pre_translate(tos->tlm, tx, ty);
  1196. tos->tm = tos->tlm;
  1197. }
  1198. void
  1199. pdf_tos_set_matrix(pdf_text_object_state *tos, float a, float b, float c, float d, float e, float f)
  1200. {
  1201. tos->tm.a = a;
  1202. tos->tm.b = b;
  1203. tos->tm.c = c;
  1204. tos->tm.d = d;
  1205. tos->tm.e = e;
  1206. tos->tm.f = f;
  1207. tos->tlm = tos->tm;
  1208. }
  1209. void
  1210. pdf_tos_newline(pdf_text_object_state *tos, float leading)
  1211. {
  1212. tos->tlm = fz_pre_translate(tos->tlm, 0, -leading);
  1213. tos->tm = tos->tlm;
  1214. }