pdf-op-buffer.c 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578
  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 "mupdf/pdf.h"
  24. typedef struct resources_stack
  25. {
  26. struct resources_stack *next;
  27. pdf_obj *res;
  28. } resources_stack;
  29. typedef struct
  30. {
  31. pdf_processor super;
  32. fz_output *out;
  33. int ahxencode;
  34. int extgstate;
  35. int newlines;
  36. int balance;
  37. pdf_obj *res;
  38. pdf_obj *last_res;
  39. resources_stack *rstack;
  40. int sep;
  41. } pdf_output_processor;
  42. /* general graphics state */
  43. static void
  44. post_op(fz_context *ctx, pdf_output_processor *proc)
  45. {
  46. if (proc->newlines)
  47. proc->sep = '\n';
  48. else
  49. proc->sep = 1;
  50. }
  51. static inline void separate(fz_context *ctx, pdf_output_processor *proc)
  52. {
  53. if (!proc->sep)
  54. return;
  55. if (proc->sep == '\n')
  56. fz_write_byte(ctx, proc->out, '\n');
  57. else
  58. fz_write_byte(ctx, proc->out, ' ');
  59. }
  60. static void
  61. pdf_out_w(fz_context *ctx, pdf_processor *proc_, float linewidth)
  62. {
  63. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  64. if (proc->extgstate != 0)
  65. return;
  66. separate(ctx, proc);
  67. fz_write_printf(ctx, proc->out, "%g w", linewidth);
  68. post_op(ctx, proc);
  69. }
  70. static void
  71. pdf_out_j(fz_context *ctx, pdf_processor *proc_, int linejoin)
  72. {
  73. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  74. if (proc->extgstate != 0)
  75. return;
  76. separate(ctx, proc);
  77. fz_write_printf(ctx, proc->out, "%d j", linejoin);
  78. post_op(ctx, proc);
  79. }
  80. static void
  81. pdf_out_J(fz_context *ctx, pdf_processor *proc_, int linecap)
  82. {
  83. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  84. if (proc->extgstate != 0)
  85. return;
  86. separate(ctx, proc);
  87. fz_write_printf(ctx, proc->out, "%d J", linecap);
  88. post_op(ctx, proc);
  89. }
  90. static void
  91. pdf_out_M(fz_context *ctx, pdf_processor *proc_, float a)
  92. {
  93. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  94. if (proc->extgstate != 0)
  95. return;
  96. separate(ctx, proc);
  97. fz_write_printf(ctx, proc->out, "%g M", a);
  98. post_op(ctx, proc);
  99. }
  100. static void
  101. pdf_out_d(fz_context *ctx, pdf_processor *proc_, pdf_obj *array, float phase)
  102. {
  103. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  104. int ahx = proc->ahxencode;
  105. if (proc->extgstate != 0)
  106. return;
  107. pdf_print_encrypted_obj(ctx, proc->out, array, 1, ahx, NULL, 0, 0, &proc->sep);
  108. separate(ctx, proc);
  109. fz_write_printf(ctx, proc->out, "%g d", phase);
  110. post_op(ctx, proc);
  111. }
  112. static void
  113. pdf_out_ri(fz_context *ctx, pdf_processor *proc_, const char *intent)
  114. {
  115. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  116. if (proc->extgstate != 0)
  117. return;
  118. separate(ctx, proc);
  119. fz_write_printf(ctx, proc->out, "%n ri", intent);
  120. post_op(ctx, proc);
  121. }
  122. static void
  123. pdf_out_i(fz_context *ctx, pdf_processor *proc_, float flatness)
  124. {
  125. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  126. if (proc->extgstate != 0)
  127. return;
  128. separate(ctx, proc);
  129. fz_write_printf(ctx, proc->out, "%g i", flatness);
  130. post_op(ctx, proc);
  131. }
  132. static void
  133. pdf_out_gs_begin(fz_context *ctx, pdf_processor *proc_, const char *name, pdf_obj *extgstate)
  134. {
  135. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  136. proc->extgstate = 1;
  137. fz_write_printf(ctx, proc->out, "%n gs", name);
  138. post_op(ctx, proc);
  139. }
  140. static void
  141. pdf_out_gs_end(fz_context *ctx, pdf_processor *proc)
  142. {
  143. ((pdf_output_processor*)proc)->extgstate = 0;
  144. }
  145. /* special graphics state */
  146. static void
  147. pdf_out_q(fz_context *ctx, pdf_processor *proc_)
  148. {
  149. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  150. proc->balance++;
  151. separate(ctx, proc);
  152. fz_write_string(ctx, proc->out, "q");
  153. post_op(ctx, proc);
  154. }
  155. static void
  156. pdf_out_Q(fz_context *ctx, pdf_processor *proc_)
  157. {
  158. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  159. proc->balance--;
  160. if (proc->balance < 0)
  161. fz_warn(ctx, "gstate underflow (too many Q operators)");
  162. separate(ctx, proc);
  163. fz_write_string(ctx, proc->out, "Q");
  164. post_op(ctx, proc);
  165. }
  166. static void
  167. pdf_out_cm(fz_context *ctx, pdf_processor *proc_, float a, float b, float c, float d, float e, float f)
  168. {
  169. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  170. separate(ctx, proc);
  171. fz_write_printf(ctx, proc->out, "%g %g %g %g %g %g cm", a, b, c, d, e, f);
  172. post_op(ctx, proc);
  173. }
  174. /* path construction */
  175. static void
  176. pdf_out_m(fz_context *ctx, pdf_processor *proc_, float x, float y)
  177. {
  178. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  179. separate(ctx, proc);
  180. fz_write_printf(ctx, proc->out, "%g %g m", x, y);
  181. post_op(ctx, proc);
  182. }
  183. static void
  184. pdf_out_l(fz_context *ctx, pdf_processor *proc_, float x, float y)
  185. {
  186. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  187. separate(ctx, proc);
  188. fz_write_printf(ctx, proc->out, "%g %g l", x, y);
  189. post_op(ctx, proc);
  190. }
  191. static void
  192. pdf_out_c(fz_context *ctx, pdf_processor *proc_, float x1, float y1, float x2, float y2, float x3, float y3)
  193. {
  194. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  195. separate(ctx, proc);
  196. fz_write_printf(ctx, proc->out, "%g %g %g %g %g %g c", x1, y1, x2, y2, x3, y3);
  197. post_op(ctx, proc);
  198. }
  199. static void
  200. pdf_out_v(fz_context *ctx, pdf_processor *proc_, float x2, float y2, float x3, float y3)
  201. {
  202. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  203. separate(ctx, proc);
  204. fz_write_printf(ctx, proc->out, "%g %g %g %g v", x2, y2, x3, y3);
  205. post_op(ctx, proc);
  206. }
  207. static void
  208. pdf_out_y(fz_context *ctx, pdf_processor *proc_, float x1, float y1, float x3, float y3)
  209. {
  210. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  211. separate(ctx, proc);
  212. fz_write_printf(ctx, proc->out, "%g %g %g %g y", x1, y1, x3, y3);
  213. post_op(ctx, proc);
  214. }
  215. static void
  216. pdf_out_h(fz_context *ctx, pdf_processor *proc_)
  217. {
  218. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  219. separate(ctx, proc);
  220. fz_write_string(ctx, proc->out, "h");
  221. post_op(ctx, proc);
  222. }
  223. static void
  224. pdf_out_re(fz_context *ctx, pdf_processor *proc_, float x, float y, float w, float h)
  225. {
  226. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  227. separate(ctx, proc);
  228. fz_write_printf(ctx, proc->out, "%g %g %g %g re", x, y, w, h);
  229. post_op(ctx, proc);
  230. }
  231. /* path painting */
  232. static void
  233. pdf_out_S(fz_context *ctx, pdf_processor *proc_)
  234. {
  235. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  236. separate(ctx, proc);
  237. fz_write_string(ctx, proc->out, "S");
  238. post_op(ctx, proc);
  239. }
  240. static void
  241. pdf_out_s(fz_context *ctx, pdf_processor *proc_)
  242. {
  243. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  244. separate(ctx, proc);
  245. fz_write_string(ctx, proc->out, "s");
  246. post_op(ctx, proc);
  247. }
  248. static void
  249. pdf_out_F(fz_context *ctx, pdf_processor *proc_)
  250. {
  251. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  252. separate(ctx, proc);
  253. fz_write_string(ctx, proc->out, "F");
  254. post_op(ctx, proc);
  255. }
  256. static void
  257. pdf_out_f(fz_context *ctx, pdf_processor *proc_)
  258. {
  259. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  260. separate(ctx, proc);
  261. fz_write_string(ctx, proc->out, "f");
  262. post_op(ctx, proc);
  263. }
  264. static void
  265. pdf_out_fstar(fz_context *ctx, pdf_processor *proc_)
  266. {
  267. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  268. separate(ctx, proc);
  269. fz_write_string(ctx, proc->out, "f*");
  270. post_op(ctx, proc);
  271. }
  272. static void
  273. pdf_out_B(fz_context *ctx, pdf_processor *proc_)
  274. {
  275. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  276. separate(ctx, proc);
  277. fz_write_string(ctx, proc->out, "B");
  278. post_op(ctx, proc);
  279. }
  280. static void
  281. pdf_out_Bstar(fz_context *ctx, pdf_processor *proc_)
  282. {
  283. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  284. separate(ctx, proc);
  285. fz_write_string(ctx, proc->out, "B*");
  286. post_op(ctx, proc);
  287. }
  288. static void
  289. pdf_out_b(fz_context *ctx, pdf_processor *proc_)
  290. {
  291. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  292. separate(ctx, proc);
  293. fz_write_string(ctx, proc->out, "b");
  294. post_op(ctx, proc);
  295. }
  296. static void
  297. pdf_out_bstar(fz_context *ctx, pdf_processor *proc_)
  298. {
  299. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  300. separate(ctx, proc);
  301. fz_write_string(ctx, proc->out, "b*");
  302. post_op(ctx, proc);
  303. }
  304. static void
  305. pdf_out_n(fz_context *ctx, pdf_processor *proc_)
  306. {
  307. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  308. separate(ctx, proc);
  309. fz_write_string(ctx, proc->out, "n");
  310. post_op(ctx, proc);
  311. }
  312. /* clipping paths */
  313. static void
  314. pdf_out_W(fz_context *ctx, pdf_processor *proc_)
  315. {
  316. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  317. separate(ctx, proc);
  318. fz_write_string(ctx, proc->out, "W");
  319. post_op(ctx, proc);
  320. }
  321. static void
  322. pdf_out_Wstar(fz_context *ctx, pdf_processor *proc_)
  323. {
  324. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  325. separate(ctx, proc);
  326. fz_write_string(ctx, proc->out, "W*");
  327. post_op(ctx, proc);
  328. }
  329. /* text objects */
  330. static void
  331. pdf_out_BT(fz_context *ctx, pdf_processor *proc_)
  332. {
  333. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  334. separate(ctx, proc);
  335. fz_write_string(ctx, proc->out, "BT");
  336. post_op(ctx, proc);
  337. }
  338. static void
  339. pdf_out_ET(fz_context *ctx, pdf_processor *proc_)
  340. {
  341. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  342. separate(ctx, proc);
  343. fz_write_string(ctx, proc->out, "ET");
  344. post_op(ctx, proc);
  345. }
  346. /* text state */
  347. static void
  348. pdf_out_Tc(fz_context *ctx, pdf_processor *proc_, float charspace)
  349. {
  350. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  351. separate(ctx, proc);
  352. fz_write_printf(ctx, proc->out, "%g Tc", charspace);
  353. post_op(ctx, proc);
  354. }
  355. static void
  356. pdf_out_Tw(fz_context *ctx, pdf_processor *proc_, float wordspace)
  357. {
  358. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  359. separate(ctx, proc);
  360. fz_write_printf(ctx, proc->out, "%g Tw", wordspace);
  361. post_op(ctx, proc);
  362. }
  363. static void
  364. pdf_out_Tz(fz_context *ctx, pdf_processor *proc_, float scale)
  365. {
  366. /* scale is exactly as read from the file. */
  367. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  368. separate(ctx, proc);
  369. fz_write_printf(ctx, proc->out, "%g Tz", scale);
  370. post_op(ctx, proc);
  371. }
  372. static void
  373. pdf_out_TL(fz_context *ctx, pdf_processor *proc_, float leading)
  374. {
  375. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  376. separate(ctx, proc);
  377. fz_write_printf(ctx, proc->out, "%g TL", leading);
  378. post_op(ctx, proc);
  379. }
  380. static void
  381. pdf_out_Tf(fz_context *ctx, pdf_processor *proc_, const char *name, pdf_font_desc *font, float size)
  382. {
  383. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  384. if (proc->extgstate != 0)
  385. return;
  386. fz_write_printf(ctx, proc->out, "%n %g Tf", name, size);
  387. post_op(ctx, proc);
  388. }
  389. static void
  390. pdf_out_Tr(fz_context *ctx, pdf_processor *proc_, int render)
  391. {
  392. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  393. separate(ctx, proc);
  394. fz_write_printf(ctx, proc->out, "%d Tr", render);
  395. post_op(ctx, proc);
  396. }
  397. static void
  398. pdf_out_Ts(fz_context *ctx, pdf_processor *proc_, float rise)
  399. {
  400. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  401. separate(ctx, proc);
  402. fz_write_printf(ctx, proc->out, "%g Ts", rise);
  403. post_op(ctx, proc);
  404. }
  405. /* text positioning */
  406. static void
  407. pdf_out_Td(fz_context *ctx, pdf_processor *proc_, float tx, float ty)
  408. {
  409. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  410. separate(ctx, proc);
  411. fz_write_printf(ctx, proc->out, "%g %g Td", tx, ty);
  412. post_op(ctx, proc);
  413. }
  414. static void
  415. pdf_out_TD(fz_context *ctx, pdf_processor *proc_, float tx, float ty)
  416. {
  417. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  418. separate(ctx, proc);
  419. fz_write_printf(ctx, proc->out, "%g %g TD", tx, ty);
  420. post_op(ctx, proc);
  421. }
  422. static void
  423. pdf_out_Tm(fz_context *ctx, pdf_processor *proc_, float a, float b, float c, float d, float e, float f)
  424. {
  425. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  426. separate(ctx, proc);
  427. fz_write_printf(ctx, proc->out, "%g %g %g %g %g %g Tm", a, b, c, d, e, f);
  428. post_op(ctx, proc);
  429. }
  430. static void
  431. pdf_out_Tstar(fz_context *ctx, pdf_processor *proc_)
  432. {
  433. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  434. separate(ctx, proc);
  435. fz_write_string(ctx, proc->out, "T*");
  436. post_op(ctx, proc);
  437. }
  438. /* text showing */
  439. static void
  440. fz_write_pdf_string(fz_context *ctx, fz_output *out, const unsigned char *str, size_t len)
  441. {
  442. size_t i;
  443. for (i = 0; i < len; ++i)
  444. if (str[i] < 32 || str[i] >= 127)
  445. break;
  446. if (i < len)
  447. {
  448. fz_write_byte(ctx, out, '<');
  449. for (i = 0; i < len; ++i)
  450. {
  451. unsigned char c = str[i];
  452. fz_write_byte(ctx, out, "0123456789abcdef"[(c>>4)&15]);
  453. fz_write_byte(ctx, out, "0123456789abcdef"[(c)&15]);
  454. }
  455. fz_write_byte(ctx, out, '>');
  456. }
  457. else
  458. {
  459. fz_write_byte(ctx, out, '(');
  460. for (i = 0; i < len; ++i)
  461. {
  462. unsigned char c = str[i];
  463. if (c == '(' || c == ')' || c == '\\')
  464. fz_write_byte(ctx, out, '\\');
  465. fz_write_byte(ctx, out, c);
  466. }
  467. fz_write_byte(ctx, out, ')');
  468. }
  469. }
  470. static void
  471. pdf_out_TJ(fz_context *ctx, pdf_processor *proc_, pdf_obj *array)
  472. {
  473. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  474. int ahx = proc->ahxencode;
  475. pdf_print_encrypted_obj(ctx, proc->out, array, 1, ahx, NULL, 0, 0, &proc->sep);
  476. separate(ctx, proc);
  477. fz_write_string(ctx, proc->out, "TJ");
  478. post_op(ctx, proc);
  479. }
  480. static void
  481. pdf_out_Tj(fz_context *ctx, pdf_processor *proc_, char *str, size_t len)
  482. {
  483. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  484. separate(ctx, proc);
  485. fz_write_pdf_string(ctx, proc->out, (const unsigned char *)str, len);
  486. fz_write_string(ctx, proc->out, "Tj");
  487. post_op(ctx, proc);
  488. }
  489. static void
  490. pdf_out_squote(fz_context *ctx, pdf_processor *proc_, char *str, size_t len)
  491. {
  492. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  493. separate(ctx, proc);
  494. fz_write_pdf_string(ctx, proc->out, (const unsigned char *)str, len);
  495. fz_write_string(ctx, proc->out, "'");
  496. post_op(ctx, proc);
  497. }
  498. static void
  499. pdf_out_dquote(fz_context *ctx, pdf_processor *proc_, float aw, float ac, char *str, size_t len)
  500. {
  501. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  502. separate(ctx, proc);
  503. fz_write_printf(ctx, proc->out, "%g %g ", aw, ac);
  504. fz_write_pdf_string(ctx, proc->out, (const unsigned char *)str, len);
  505. fz_write_string(ctx, proc->out, "\"");
  506. post_op(ctx, proc);
  507. }
  508. /* type 3 fonts */
  509. static void
  510. pdf_out_d0(fz_context *ctx, pdf_processor *proc_, float wx, float wy)
  511. {
  512. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  513. separate(ctx, proc);
  514. fz_write_printf(ctx, proc->out, "%g %g d0", wx, wy);
  515. post_op(ctx, proc);
  516. }
  517. static void
  518. pdf_out_d1(fz_context *ctx, pdf_processor *proc_, float wx, float wy, float llx, float lly, float urx, float ury)
  519. {
  520. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  521. separate(ctx, proc);
  522. fz_write_printf(ctx, proc->out, "%g %g %g %g %g %g d1", wx, wy, llx, lly, urx, ury);
  523. post_op(ctx, proc);
  524. }
  525. /* color */
  526. static void
  527. pdf_out_CS(fz_context *ctx, pdf_processor *proc_, const char *name, fz_colorspace *cs)
  528. {
  529. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  530. separate(ctx, proc);
  531. fz_write_printf(ctx, proc->out, "%n CS", name);
  532. post_op(ctx, proc);
  533. }
  534. static void
  535. pdf_out_cs(fz_context *ctx, pdf_processor *proc_, const char *name, fz_colorspace *cs)
  536. {
  537. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  538. separate(ctx, proc);
  539. fz_write_printf(ctx, proc->out, "%n cs", name);
  540. post_op(ctx, proc);
  541. }
  542. static void
  543. pdf_out_SC_pattern(fz_context *ctx, pdf_processor *proc_, const char *name, pdf_pattern *pat, int n, float *color)
  544. {
  545. int i;
  546. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  547. separate(ctx, proc);
  548. for (i = 0; i < n; ++i)
  549. fz_write_printf(ctx, proc->out, "%g ", color[i]);
  550. fz_write_printf(ctx, proc->out, "%n SCN", name);
  551. post_op(ctx, proc);
  552. }
  553. static void
  554. pdf_out_sc_pattern(fz_context *ctx, pdf_processor *proc_, const char *name, pdf_pattern *pat, int n, float *color)
  555. {
  556. int i;
  557. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  558. separate(ctx, proc);
  559. for (i = 0; i < n; ++i)
  560. fz_write_printf(ctx, proc->out, "%g ", color[i]);
  561. fz_write_printf(ctx, proc->out, "%n scn", name);
  562. post_op(ctx, proc);
  563. }
  564. static void
  565. pdf_out_SC_shade(fz_context *ctx, pdf_processor *proc_, const char *name, fz_shade *shade)
  566. {
  567. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  568. separate(ctx, proc);
  569. fz_write_printf(ctx, proc->out, "%n SCN", name);
  570. post_op(ctx, proc);
  571. }
  572. static void
  573. pdf_out_sc_shade(fz_context *ctx, pdf_processor *proc_, const char *name, fz_shade *shade)
  574. {
  575. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  576. separate(ctx, proc);
  577. fz_write_printf(ctx, proc->out, "%n scn", name);
  578. post_op(ctx, proc);
  579. }
  580. static void
  581. pdf_out_SC_color(fz_context *ctx, pdf_processor *proc_, int n, float *color)
  582. {
  583. int i;
  584. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  585. separate(ctx, proc);
  586. for (i = 0; i < n; ++i)
  587. fz_write_printf(ctx, proc->out, "%g ", color[i]);
  588. fz_write_string(ctx, proc->out, "SCN");
  589. post_op(ctx, proc);
  590. }
  591. static void
  592. pdf_out_sc_color(fz_context *ctx, pdf_processor *proc_, int n, float *color)
  593. {
  594. int i;
  595. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  596. separate(ctx, proc);
  597. for (i = 0; i < n; ++i)
  598. fz_write_printf(ctx, proc->out, "%g ", color[i]);
  599. fz_write_string(ctx, proc->out, "scn");
  600. post_op(ctx, proc);
  601. }
  602. static void
  603. pdf_out_G(fz_context *ctx, pdf_processor *proc_, float g)
  604. {
  605. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  606. separate(ctx, proc);
  607. fz_write_printf(ctx, proc->out, "%g G", g);
  608. post_op(ctx, proc);
  609. }
  610. static void
  611. pdf_out_g(fz_context *ctx, pdf_processor *proc_, float g)
  612. {
  613. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  614. separate(ctx, proc);
  615. fz_write_printf(ctx, proc->out, "%g g", g);
  616. post_op(ctx, proc);
  617. }
  618. static void
  619. pdf_out_RG(fz_context *ctx, pdf_processor *proc_, float r, float g, float b)
  620. {
  621. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  622. separate(ctx, proc);
  623. fz_write_printf(ctx, proc->out, "%g %g %g RG", r, g, b);
  624. post_op(ctx, proc);
  625. }
  626. static void
  627. pdf_out_rg(fz_context *ctx, pdf_processor *proc_, float r, float g, float b)
  628. {
  629. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  630. separate(ctx, proc);
  631. fz_write_printf(ctx, proc->out, "%g %g %g rg", r, g, b);
  632. post_op(ctx, proc);
  633. }
  634. static void
  635. pdf_out_K(fz_context *ctx, pdf_processor *proc_, float c, float m, float y, float k)
  636. {
  637. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  638. separate(ctx, proc);
  639. fz_write_printf(ctx, proc->out, "%g %g %g %g K", c, m, y, k);
  640. post_op(ctx, proc);
  641. }
  642. static void
  643. pdf_out_k(fz_context *ctx, pdf_processor *proc_, float c, float m, float y, float k)
  644. {
  645. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  646. separate(ctx, proc);
  647. fz_write_printf(ctx, proc->out, "%g %g %g %g k", c, m, y, k);
  648. post_op(ctx, proc);
  649. }
  650. /* shadings, images, xobjects */
  651. static void
  652. pdf_out_BI(fz_context *ctx, pdf_processor *proc_, fz_image *img, const char *colorspace)
  653. {
  654. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  655. fz_output *out = proc->out;
  656. int ahx = proc->ahxencode;
  657. fz_compressed_buffer *cbuf;
  658. fz_buffer *buf = NULL;
  659. int i, w, h, bpc;
  660. unsigned char *data;
  661. size_t len;
  662. fz_pixmap *pix = NULL;
  663. fz_colorspace *cs;
  664. int type;
  665. if (img == NULL)
  666. return;
  667. cbuf = fz_compressed_image_buffer(ctx, img);
  668. if (cbuf == NULL)
  669. {
  670. pix = fz_get_pixmap_from_image(ctx, img, NULL, NULL, &w, &h);
  671. bpc = 8;
  672. cs = pix->colorspace;
  673. type = FZ_IMAGE_RAW;
  674. }
  675. else
  676. {
  677. buf = cbuf->buffer;
  678. if (buf == NULL)
  679. return;
  680. w = img->w;
  681. h = img->h;
  682. bpc = img->bpc;
  683. cs = img->colorspace;
  684. type = cbuf->params.type;
  685. }
  686. fz_try(ctx)
  687. {
  688. separate(ctx, proc);
  689. fz_write_string(ctx, out, "BI ");
  690. fz_write_printf(ctx, out, "/W %d", w);
  691. fz_write_printf(ctx, out, "/H %d", h);
  692. fz_write_printf(ctx, out, "/BPC %d", bpc);
  693. if (img->imagemask)
  694. fz_write_string(ctx, out, "/IM true");
  695. else if (cs == fz_device_gray(ctx))
  696. fz_write_string(ctx, out, "/CS/G");
  697. else if (cs == fz_device_rgb(ctx))
  698. fz_write_string(ctx, out, "/CS/RGB");
  699. else if (cs == fz_device_cmyk(ctx))
  700. fz_write_string(ctx, out, "/CS/CMYK");
  701. else if (cs)
  702. fz_write_printf(ctx, out, "/CS%n", colorspace);
  703. else
  704. fz_throw(ctx, FZ_ERROR_ARGUMENT, "BI operator can only show ImageMask, Gray, RGB, or CMYK images");
  705. if (img->interpolate)
  706. fz_write_string(ctx, out, "/I true");
  707. fz_write_string(ctx, out, "/D[");
  708. for (i = 0; i < img->n * 2; ++i)
  709. {
  710. if (i > 0)
  711. fz_write_byte(ctx, out, ' ');
  712. fz_write_printf(ctx, out, "%g", img->decode[i]);
  713. }
  714. fz_write_string(ctx, out, "]");
  715. proc->sep = 0;
  716. switch (type)
  717. {
  718. default:
  719. fz_throw(ctx, FZ_ERROR_ARGUMENT, "unknown compressed buffer type");
  720. break;
  721. case FZ_IMAGE_JPEG:
  722. fz_write_string(ctx, out, ahx ? "/F[/AHx/DCT]" : "/F/DCT");
  723. proc->sep = !ahx;
  724. if (cbuf->params.u.jpeg.color_transform >= 0)
  725. {
  726. fz_write_printf(ctx, out, "/DP<</ColorTransform %d>>", cbuf->params.u.jpeg.color_transform);
  727. proc->sep = 0;
  728. }
  729. if (cbuf->params.u.jpeg.invert_cmyk && img->n == 4)
  730. {
  731. fz_write_string(ctx, out, "/D[1 0 1 0 1 0 1 0]");
  732. proc->sep = 0;
  733. }
  734. break;
  735. case FZ_IMAGE_FAX:
  736. fz_write_string(ctx, out, ahx ? "/F[/AHx/CCF]/DP[null<<" : "/F/CCF/DP<<");
  737. fz_write_printf(ctx, out, "/K %d", cbuf->params.u.fax.k);
  738. if (cbuf->params.u.fax.columns != 1728)
  739. fz_write_printf(ctx, out, "/Columns %d", cbuf->params.u.fax.columns);
  740. if (cbuf->params.u.fax.rows > 0)
  741. fz_write_printf(ctx, out, "/Rows %d", cbuf->params.u.fax.rows);
  742. if (cbuf->params.u.fax.end_of_line)
  743. fz_write_string(ctx, out, "/EndOfLine true");
  744. if (cbuf->params.u.fax.encoded_byte_align)
  745. fz_write_string(ctx, out, "/EncodedByteAlign true");
  746. if (!cbuf->params.u.fax.end_of_block)
  747. fz_write_string(ctx, out, "/EndOfBlock false");
  748. if (cbuf->params.u.fax.black_is_1)
  749. fz_write_string(ctx, out, "/BlackIs1 true");
  750. if (cbuf->params.u.fax.damaged_rows_before_error > 0)
  751. fz_write_printf(ctx, out, "/DamagedRowsBeforeError %d",
  752. cbuf->params.u.fax.damaged_rows_before_error);
  753. fz_write_string(ctx, out, ahx ? ">>]" : ">>");
  754. proc->sep = 0;
  755. break;
  756. case FZ_IMAGE_RAW:
  757. if (ahx)
  758. {
  759. fz_write_string(ctx, out, "/F/AHx");
  760. proc->sep = 1;
  761. }
  762. break;
  763. case FZ_IMAGE_RLD:
  764. fz_write_string(ctx, out, ahx ? "/F[/AHx/RL]" : "/F/RL");
  765. proc->sep = !ahx;
  766. break;
  767. case FZ_IMAGE_FLATE:
  768. fz_write_string(ctx, out, ahx ? "/F[/AHx/Fl]" : "/F/Fl");
  769. proc->sep = !ahx;
  770. if (cbuf->params.u.flate.predictor > 1)
  771. {
  772. fz_write_string(ctx, out, ahx ? "/DP[null<<" : "/DP<<");
  773. fz_write_printf(ctx, out, "/Predictor %d", cbuf->params.u.flate.predictor);
  774. if (cbuf->params.u.flate.columns != 1)
  775. fz_write_printf(ctx, out, "/Columns %d", cbuf->params.u.flate.columns);
  776. if (cbuf->params.u.flate.colors != 1)
  777. fz_write_printf(ctx, out, "/Colors %d", cbuf->params.u.flate.colors);
  778. if (cbuf->params.u.flate.bpc != 8)
  779. fz_write_printf(ctx, out, "/BitsPerComponent %d", cbuf->params.u.flate.bpc);
  780. fz_write_string(ctx, out, ahx ? ">>]" : ">>");
  781. proc->sep = 0;
  782. }
  783. break;
  784. case FZ_IMAGE_LZW:
  785. fz_write_string(ctx, out, ahx ? "/F[/AHx/LZW]" : "/F/LZW");
  786. proc->sep = !ahx;
  787. if (cbuf->params.u.lzw.predictor > 1)
  788. {
  789. fz_write_string(ctx, out, ahx ? "/DP[null<<" : "/DP<<");
  790. fz_write_printf(ctx, out, "/Predictor %d", cbuf->params.u.lzw.predictor);
  791. if (cbuf->params.u.lzw.columns != 1)
  792. fz_write_printf(ctx, out, "/Columns %d", cbuf->params.u.lzw.columns);
  793. if (cbuf->params.u.lzw.colors != 1)
  794. fz_write_printf(ctx, out, "/Colors %d", cbuf->params.u.lzw.colors);
  795. if (cbuf->params.u.lzw.bpc != 8)
  796. fz_write_printf(ctx, out, "/BitsPerComponent %d", cbuf->params.u.lzw.bpc);
  797. if (cbuf->params.u.lzw.early_change != 1)
  798. fz_write_printf(ctx, out, "/EarlyChange %d", cbuf->params.u.lzw.early_change);
  799. fz_write_string(ctx, out, ahx ? ">>]" : ">>");
  800. proc->sep = 0;
  801. }
  802. break;
  803. case FZ_IMAGE_BROTLI:
  804. fz_write_string(ctx, out, ahx ? "/F[/AHx/Br]\n" : "/F/Br\n");
  805. if (cbuf->params.u.brotli.predictor > 1)
  806. {
  807. fz_write_string(ctx, out, ahx ? "/DP[null<<\n" : "/DP<<\n");
  808. fz_write_printf(ctx, out, "/Predictor %d\n", cbuf->params.u.brotli.predictor);
  809. if (cbuf->params.u.brotli.columns != 1)
  810. fz_write_printf(ctx, out, "/Columns %d\n", cbuf->params.u.brotli.columns);
  811. if (cbuf->params.u.brotli.colors != 1)
  812. fz_write_printf(ctx, out, "/Colors %d\n", cbuf->params.u.brotli.colors);
  813. if (cbuf->params.u.brotli.bpc != 8)
  814. fz_write_printf(ctx, out, "/BitsPerComponent %d\n", cbuf->params.u.brotli.bpc);
  815. fz_write_string(ctx, out, ahx ? ">>]\n" : ">>\n");
  816. }
  817. break;
  818. }
  819. separate(ctx, proc);
  820. fz_write_string(ctx, out, "ID ");
  821. if (buf)
  822. len = fz_buffer_storage(ctx, buf, &data);
  823. else
  824. {
  825. data = pix->samples;
  826. len = ((size_t)w) * h * pix->n;
  827. }
  828. if (ahx)
  829. {
  830. size_t z;
  831. for (z = 0; z < len; ++z)
  832. {
  833. int c = data[z];
  834. fz_write_byte(ctx, out, "0123456789abcdef"[(c >> 4) & 0xf]);
  835. fz_write_byte(ctx, out, "0123456789abcdef"[c & 0xf]);
  836. if ((z & 31) == 31)
  837. fz_write_byte(ctx, out, '\n');
  838. }
  839. fz_write_byte(ctx, out, '>');
  840. }
  841. else
  842. {
  843. fz_write_data(ctx, out, data, len);
  844. }
  845. fz_write_string(ctx, out, " EI");
  846. proc->sep = 1;
  847. }
  848. fz_always(ctx)
  849. fz_drop_pixmap(ctx, pix);
  850. fz_catch(ctx)
  851. fz_rethrow(ctx);
  852. }
  853. static void
  854. pdf_out_sh(fz_context *ctx, pdf_processor *proc_, const char *name, fz_shade *shade)
  855. {
  856. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  857. separate(ctx, proc);
  858. fz_write_printf(ctx, proc->out, "%n sh", name);
  859. post_op(ctx, proc);
  860. }
  861. static void
  862. pdf_out_Do_image(fz_context *ctx, pdf_processor *proc_, const char *name, fz_image *image)
  863. {
  864. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  865. separate(ctx, proc);
  866. fz_write_printf(ctx, proc->out, "%n Do", name);
  867. post_op(ctx, proc);
  868. }
  869. static void
  870. pdf_out_Do_form(fz_context *ctx, pdf_processor *proc_, const char *name, pdf_obj *xobj)
  871. {
  872. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  873. separate(ctx, proc);
  874. fz_write_printf(ctx, proc->out, "%n Do", name);
  875. post_op(ctx, proc);
  876. }
  877. /* marked content */
  878. static void
  879. pdf_out_MP(fz_context *ctx, pdf_processor *proc_, const char *tag)
  880. {
  881. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  882. separate(ctx, proc);
  883. fz_write_printf(ctx, proc->out, "%n MP", tag);
  884. post_op(ctx, proc);
  885. }
  886. static void
  887. pdf_out_DP(fz_context *ctx, pdf_processor *proc_, const char *tag, pdf_obj *raw, pdf_obj *cooked)
  888. {
  889. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  890. int ahx = proc->ahxencode;
  891. separate(ctx, proc);
  892. fz_write_printf(ctx, proc->out, "%n", tag);
  893. proc->sep = 1;
  894. pdf_print_encrypted_obj(ctx, proc->out, raw, 1, ahx, NULL, 0, 0, &proc->sep);
  895. separate(ctx, proc);
  896. fz_write_string(ctx, proc->out, "DP");
  897. post_op(ctx, proc);
  898. }
  899. static void
  900. pdf_out_BMC(fz_context *ctx, pdf_processor *proc_, const char *tag)
  901. {
  902. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  903. separate(ctx, proc);
  904. fz_write_printf(ctx, proc->out, "%n BMC", tag);
  905. post_op(ctx, proc);
  906. }
  907. static void
  908. pdf_out_BDC(fz_context *ctx, pdf_processor *proc_, const char *tag, pdf_obj *raw, pdf_obj *cooked)
  909. {
  910. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  911. int ahx = proc->ahxencode;
  912. separate(ctx, proc);
  913. fz_write_printf(ctx, proc->out, "%n", tag);
  914. proc->sep = 1;
  915. pdf_print_encrypted_obj(ctx, proc->out, raw, 1, ahx, NULL, 0, 0, &proc->sep);
  916. separate(ctx, proc);
  917. fz_write_string(ctx, proc->out, "BDC");
  918. post_op(ctx, proc);
  919. }
  920. static void
  921. pdf_out_EMC(fz_context *ctx, pdf_processor *proc_)
  922. {
  923. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  924. separate(ctx, proc);
  925. fz_write_string(ctx, proc->out, "EMC");
  926. post_op(ctx, proc);
  927. }
  928. /* compatibility */
  929. static void
  930. pdf_out_BX(fz_context *ctx, pdf_processor *proc_)
  931. {
  932. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  933. separate(ctx, proc);
  934. fz_write_string(ctx, proc->out, "BX");
  935. post_op(ctx, proc);
  936. }
  937. static void
  938. pdf_out_EX(fz_context *ctx, pdf_processor *proc_)
  939. {
  940. pdf_output_processor *proc = (pdf_output_processor *)proc_;
  941. separate(ctx, proc);
  942. fz_write_string(ctx, proc->out, "EX");
  943. post_op(ctx, proc);
  944. }
  945. static void
  946. pdf_close_output_processor(fz_context *ctx, pdf_processor *proc_)
  947. {
  948. pdf_output_processor *proc = (pdf_output_processor*)proc_;
  949. fz_output *out = proc->out;
  950. /* Add missing 'Q' operators to get back to zero. */
  951. /* We can't prepend missing 'q' operators to guarantee we don't underflow. */
  952. while (proc->balance > 0)
  953. {
  954. proc->balance--;
  955. separate(ctx, proc);
  956. fz_write_byte(ctx, out, 'Q');
  957. post_op(ctx, proc);
  958. }
  959. fz_close_output(ctx, out);
  960. }
  961. static void
  962. pdf_drop_output_processor(fz_context *ctx, pdf_processor *proc)
  963. {
  964. pdf_output_processor *p = (pdf_output_processor *)proc;
  965. fz_drop_output(ctx, p->out);
  966. }
  967. static void
  968. pdf_reset_output_processor(fz_context *ctx, pdf_processor *proc)
  969. {
  970. pdf_output_processor *p = (pdf_output_processor *)proc;
  971. fz_reset_output(ctx, p->out);
  972. }
  973. static void
  974. pdf_out_push_resources(fz_context *ctx, pdf_processor *proc, pdf_obj *res)
  975. {
  976. pdf_output_processor *p = (pdf_output_processor *)proc;
  977. resources_stack *stk = fz_malloc_struct(ctx, resources_stack);
  978. stk->next = p->rstack;
  979. p->rstack = stk;
  980. stk->res = pdf_keep_obj(ctx, res);
  981. }
  982. static pdf_obj *
  983. pdf_out_pop_resources(fz_context *ctx, pdf_processor *proc)
  984. {
  985. pdf_output_processor *p = (pdf_output_processor *)proc;
  986. resources_stack *stk = p->rstack;
  987. pdf_obj *res = stk->res;
  988. p->rstack = stk->next;
  989. fz_free(ctx, stk);
  990. return res;
  991. }
  992. pdf_processor *
  993. pdf_new_output_processor(fz_context *ctx, fz_output *out, int ahxencode, int newlines)
  994. {
  995. pdf_output_processor *proc = pdf_new_processor(ctx, sizeof *proc);
  996. proc->super.close_processor = pdf_close_output_processor;
  997. proc->super.drop_processor = pdf_drop_output_processor;
  998. proc->super.reset_processor = pdf_reset_output_processor;
  999. proc->super.push_resources = pdf_out_push_resources;
  1000. proc->super.pop_resources = pdf_out_pop_resources;
  1001. /* general graphics state */
  1002. proc->super.op_w = pdf_out_w;
  1003. proc->super.op_j = pdf_out_j;
  1004. proc->super.op_J = pdf_out_J;
  1005. proc->super.op_M = pdf_out_M;
  1006. proc->super.op_d = pdf_out_d;
  1007. proc->super.op_ri = pdf_out_ri;
  1008. proc->super.op_i = pdf_out_i;
  1009. proc->super.op_gs_begin = pdf_out_gs_begin;
  1010. proc->super.op_gs_end = pdf_out_gs_end;
  1011. /* transparency graphics state */
  1012. proc->super.op_gs_BM = NULL;
  1013. proc->super.op_gs_CA = NULL;
  1014. proc->super.op_gs_ca = NULL;
  1015. proc->super.op_gs_SMask = NULL;
  1016. /* special graphics state */
  1017. proc->super.op_q = pdf_out_q;
  1018. proc->super.op_Q = pdf_out_Q;
  1019. proc->super.op_cm = pdf_out_cm;
  1020. /* path construction */
  1021. proc->super.op_m = pdf_out_m;
  1022. proc->super.op_l = pdf_out_l;
  1023. proc->super.op_c = pdf_out_c;
  1024. proc->super.op_v = pdf_out_v;
  1025. proc->super.op_y = pdf_out_y;
  1026. proc->super.op_h = pdf_out_h;
  1027. proc->super.op_re = pdf_out_re;
  1028. /* path painting */
  1029. proc->super.op_S = pdf_out_S;
  1030. proc->super.op_s = pdf_out_s;
  1031. proc->super.op_F = pdf_out_F;
  1032. proc->super.op_f = pdf_out_f;
  1033. proc->super.op_fstar = pdf_out_fstar;
  1034. proc->super.op_B = pdf_out_B;
  1035. proc->super.op_Bstar = pdf_out_Bstar;
  1036. proc->super.op_b = pdf_out_b;
  1037. proc->super.op_bstar = pdf_out_bstar;
  1038. proc->super.op_n = pdf_out_n;
  1039. /* clipping paths */
  1040. proc->super.op_W = pdf_out_W;
  1041. proc->super.op_Wstar = pdf_out_Wstar;
  1042. /* text objects */
  1043. proc->super.op_BT = pdf_out_BT;
  1044. proc->super.op_ET = pdf_out_ET;
  1045. /* text state */
  1046. proc->super.op_Tc = pdf_out_Tc;
  1047. proc->super.op_Tw = pdf_out_Tw;
  1048. proc->super.op_Tz = pdf_out_Tz;
  1049. proc->super.op_TL = pdf_out_TL;
  1050. proc->super.op_Tf = pdf_out_Tf;
  1051. proc->super.op_Tr = pdf_out_Tr;
  1052. proc->super.op_Ts = pdf_out_Ts;
  1053. /* text positioning */
  1054. proc->super.op_Td = pdf_out_Td;
  1055. proc->super.op_TD = pdf_out_TD;
  1056. proc->super.op_Tm = pdf_out_Tm;
  1057. proc->super.op_Tstar = pdf_out_Tstar;
  1058. /* text showing */
  1059. proc->super.op_TJ = pdf_out_TJ;
  1060. proc->super.op_Tj = pdf_out_Tj;
  1061. proc->super.op_squote = pdf_out_squote;
  1062. proc->super.op_dquote = pdf_out_dquote;
  1063. /* type 3 fonts */
  1064. proc->super.op_d0 = pdf_out_d0;
  1065. proc->super.op_d1 = pdf_out_d1;
  1066. /* color */
  1067. proc->super.op_CS = pdf_out_CS;
  1068. proc->super.op_cs = pdf_out_cs;
  1069. proc->super.op_SC_color = pdf_out_SC_color;
  1070. proc->super.op_sc_color = pdf_out_sc_color;
  1071. proc->super.op_SC_pattern = pdf_out_SC_pattern;
  1072. proc->super.op_sc_pattern = pdf_out_sc_pattern;
  1073. proc->super.op_SC_shade = pdf_out_SC_shade;
  1074. proc->super.op_sc_shade = pdf_out_sc_shade;
  1075. proc->super.op_G = pdf_out_G;
  1076. proc->super.op_g = pdf_out_g;
  1077. proc->super.op_RG = pdf_out_RG;
  1078. proc->super.op_rg = pdf_out_rg;
  1079. proc->super.op_K = pdf_out_K;
  1080. proc->super.op_k = pdf_out_k;
  1081. /* shadings, images, xobjects */
  1082. proc->super.op_BI = pdf_out_BI;
  1083. proc->super.op_sh = pdf_out_sh;
  1084. proc->super.op_Do_image = pdf_out_Do_image;
  1085. proc->super.op_Do_form = pdf_out_Do_form;
  1086. /* marked content */
  1087. proc->super.op_MP = pdf_out_MP;
  1088. proc->super.op_DP = pdf_out_DP;
  1089. proc->super.op_BMC = pdf_out_BMC;
  1090. proc->super.op_BDC = pdf_out_BDC;
  1091. proc->super.op_EMC = pdf_out_EMC;
  1092. /* compatibility */
  1093. proc->super.op_BX = pdf_out_BX;
  1094. proc->super.op_EX = pdf_out_EX;
  1095. /* extgstate */
  1096. proc->super.op_gs_OP = NULL;
  1097. proc->super.op_gs_op = NULL;
  1098. proc->super.op_gs_OPM = NULL;
  1099. proc->super.op_gs_UseBlackPtComp = NULL;
  1100. proc->out = out;
  1101. proc->ahxencode = ahxencode;
  1102. proc->newlines = newlines;
  1103. proc->super.requirements = PDF_PROCESSOR_REQUIRES_DECODED_IMAGES;
  1104. proc->balance = 0;
  1105. return (pdf_processor*)proc;
  1106. }
  1107. pdf_processor *
  1108. pdf_new_buffer_processor(fz_context *ctx, fz_buffer *buffer, int ahxencode, int newlines)
  1109. {
  1110. pdf_processor *proc = NULL;
  1111. fz_output *out = fz_new_output_with_buffer(ctx, buffer);
  1112. fz_try(ctx)
  1113. {
  1114. proc = pdf_new_output_processor(ctx, out, ahxencode, newlines);
  1115. }
  1116. fz_catch(ctx)
  1117. {
  1118. fz_drop_output(ctx, out);
  1119. fz_rethrow(ctx);
  1120. }
  1121. return proc;
  1122. }
  1123. /* Simplified processor that only counts matching q/Q pairs. */
  1124. typedef struct
  1125. {
  1126. pdf_processor super;
  1127. int *balance;
  1128. int *min_q;
  1129. int *min_op_q;
  1130. int first;
  1131. int ending;
  1132. } pdf_balance_processor;
  1133. static void
  1134. pdf_balance_q(fz_context *ctx, pdf_processor *proc_)
  1135. {
  1136. pdf_balance_processor *proc = (pdf_balance_processor*)proc_;
  1137. (*proc->balance)++;
  1138. }
  1139. static void
  1140. pdf_balance_Q(fz_context *ctx, pdf_processor *proc_)
  1141. {
  1142. pdf_balance_processor *proc = (pdf_balance_processor*)proc_;
  1143. if (proc->ending)
  1144. return;
  1145. (*proc->balance)--;
  1146. if (*proc->balance < *proc->min_q)
  1147. *proc->min_q = *proc->balance;
  1148. }
  1149. static void
  1150. pdf_balance_void(fz_context *ctx, pdf_processor *proc_)
  1151. {
  1152. pdf_balance_processor *proc = (pdf_balance_processor*)proc_;
  1153. if (*proc->balance < *proc->min_op_q)
  1154. *proc->min_op_q = *proc->balance;
  1155. }
  1156. #define BALANCE { pdf_balance_void(ctx, p); }
  1157. static void pdf_balance_string(fz_context *ctx, pdf_processor *p, const char *x) BALANCE
  1158. static void pdf_balance_int(fz_context *ctx, pdf_processor *p, int x) BALANCE
  1159. static void pdf_balance_float(fz_context *ctx, pdf_processor *p, float x) BALANCE
  1160. static void pdf_balance_float2(fz_context *ctx, pdf_processor *p, float x, float y) BALANCE
  1161. static void pdf_balance_float3(fz_context *ctx, pdf_processor *p, float x, float y, float z) BALANCE
  1162. static void pdf_balance_float4(fz_context *ctx, pdf_processor *p, float x, float y, float z, float w) BALANCE
  1163. static void pdf_balance_float6(fz_context *ctx, pdf_processor *p, float a, float b, float c, float d, float e, float f) BALANCE
  1164. static void pdf_balance_d(fz_context *ctx, pdf_processor *p, pdf_obj *array, float phase) BALANCE
  1165. static void pdf_balance_gs_begin(fz_context *ctx, pdf_processor *p, const char *name, pdf_obj *extgstate) BALANCE
  1166. static void pdf_balance_Tf(fz_context *ctx, pdf_processor *p, const char *name, pdf_font_desc *font, float size) BALANCE
  1167. static void pdf_balance_TJ(fz_context *ctx, pdf_processor *p, pdf_obj *array) BALANCE
  1168. static void pdf_balance_Tj(fz_context *ctx, pdf_processor *p, char *str, size_t len) BALANCE
  1169. static void pdf_balance_squote(fz_context *ctx, pdf_processor *p, char *str, size_t len) BALANCE
  1170. static void pdf_balance_dquote(fz_context *ctx, pdf_processor *p, float aw, float ac, char *str, size_t len) BALANCE
  1171. static void pdf_balance_cs(fz_context *ctx, pdf_processor *p, const char *name, fz_colorspace *cs) BALANCE
  1172. static void pdf_balance_sc_pattern(fz_context *ctx, pdf_processor *p, const char *name, pdf_pattern *pat, int n, float *color) BALANCE
  1173. static void pdf_balance_sc_shade(fz_context *ctx, pdf_processor *p, const char *name, fz_shade *shade) BALANCE
  1174. static void pdf_balance_sc_color(fz_context *ctx, pdf_processor *p, int n, float *color) BALANCE
  1175. static void pdf_balance_BDC(fz_context *ctx, pdf_processor *p, const char *tag, pdf_obj *raw, pdf_obj *cooked) BALANCE
  1176. static void pdf_balance_BI(fz_context *ctx, pdf_processor *p, fz_image *img, const char *colorspace) BALANCE
  1177. static void pdf_balance_sh(fz_context *ctx, pdf_processor *p, const char *name, fz_shade *shade) BALANCE
  1178. static void pdf_balance_Do_image(fz_context *ctx, pdf_processor *p, const char *name, fz_image *image) BALANCE
  1179. static void pdf_balance_Do_form(fz_context *ctx, pdf_processor *p, const char *name, pdf_obj *xobj) BALANCE
  1180. static void pdf_balance_EOD(fz_context *ctx, pdf_processor *p)
  1181. {
  1182. pdf_balance_processor *proc = (pdf_balance_processor *)p;
  1183. proc->ending = 1;
  1184. }
  1185. static pdf_processor *
  1186. pdf_new_balance_processor(fz_context *ctx, int *balance, int *min_q, int *min_op_q)
  1187. {
  1188. pdf_balance_processor *proc = pdf_new_processor(ctx, sizeof *proc);
  1189. proc->super.op_q = pdf_balance_q;
  1190. proc->super.op_Q = pdf_balance_Q;
  1191. /* general graphics state */
  1192. proc->super.op_w = pdf_balance_float;
  1193. proc->super.op_j = pdf_balance_int;
  1194. proc->super.op_J = pdf_balance_int;
  1195. proc->super.op_M = pdf_balance_float;
  1196. proc->super.op_d = pdf_balance_d;
  1197. proc->super.op_ri = pdf_balance_string;
  1198. proc->super.op_i = pdf_balance_float;
  1199. proc->super.op_gs_begin = pdf_balance_gs_begin;
  1200. /* special graphics state */
  1201. proc->super.op_cm = pdf_balance_float6;
  1202. /* path construction */
  1203. proc->super.op_m = pdf_balance_float2;
  1204. proc->super.op_l = pdf_balance_float2;
  1205. proc->super.op_c = pdf_balance_float6;
  1206. proc->super.op_v = pdf_balance_float4;
  1207. proc->super.op_y = pdf_balance_float4;
  1208. proc->super.op_h = pdf_balance_void;
  1209. proc->super.op_re = pdf_balance_float4;
  1210. /* path painting */
  1211. proc->super.op_S = pdf_balance_void;
  1212. proc->super.op_s = pdf_balance_void;
  1213. proc->super.op_F = pdf_balance_void;
  1214. proc->super.op_f = pdf_balance_void;
  1215. proc->super.op_fstar = pdf_balance_void;
  1216. proc->super.op_B = pdf_balance_void;
  1217. proc->super.op_Bstar = pdf_balance_void;
  1218. proc->super.op_b = pdf_balance_void;
  1219. proc->super.op_bstar = pdf_balance_void;
  1220. proc->super.op_n = pdf_balance_void;
  1221. /* clipping paths */
  1222. proc->super.op_W = pdf_balance_void;
  1223. proc->super.op_Wstar = pdf_balance_void;
  1224. /* text objects */
  1225. proc->super.op_BT = pdf_balance_void;
  1226. proc->super.op_ET = pdf_balance_void;
  1227. /* text state */
  1228. proc->super.op_Tc = pdf_balance_float;
  1229. proc->super.op_Tw = pdf_balance_float;
  1230. proc->super.op_Tz = pdf_balance_float;
  1231. proc->super.op_TL = pdf_balance_float;
  1232. proc->super.op_Tf = pdf_balance_Tf;
  1233. proc->super.op_Tr = pdf_balance_int;
  1234. proc->super.op_Ts = pdf_balance_float;
  1235. /* text positioning */
  1236. proc->super.op_Td = pdf_balance_float2;
  1237. proc->super.op_TD = pdf_balance_float2;
  1238. proc->super.op_Tm = pdf_balance_float6;
  1239. proc->super.op_Tstar = pdf_balance_void;
  1240. /* text showing */
  1241. proc->super.op_TJ = pdf_balance_TJ;
  1242. proc->super.op_Tj = pdf_balance_Tj;
  1243. proc->super.op_squote = pdf_balance_squote;
  1244. proc->super.op_dquote = pdf_balance_dquote;
  1245. /* type 3 fonts */
  1246. proc->super.op_d0 = pdf_balance_float2;
  1247. proc->super.op_d1 = pdf_balance_float6;
  1248. /* color */
  1249. proc->super.op_CS = pdf_balance_cs;
  1250. proc->super.op_cs = pdf_balance_cs;
  1251. proc->super.op_SC_color = pdf_balance_sc_color;
  1252. proc->super.op_sc_color = pdf_balance_sc_color;
  1253. proc->super.op_SC_pattern = pdf_balance_sc_pattern;
  1254. proc->super.op_sc_pattern = pdf_balance_sc_pattern;
  1255. proc->super.op_SC_shade = pdf_balance_sc_shade;
  1256. proc->super.op_sc_shade = pdf_balance_sc_shade;
  1257. proc->super.op_G = pdf_balance_float;
  1258. proc->super.op_g = pdf_balance_float;
  1259. proc->super.op_RG = pdf_balance_float3;
  1260. proc->super.op_rg = pdf_balance_float3;
  1261. proc->super.op_K = pdf_balance_float4;
  1262. proc->super.op_k = pdf_balance_float4;
  1263. /* shadings, images, xobjects */
  1264. proc->super.op_BI = pdf_balance_BI;
  1265. proc->super.op_sh = pdf_balance_sh;
  1266. proc->super.op_Do_image = pdf_balance_Do_image;
  1267. proc->super.op_Do_form = pdf_balance_Do_form;
  1268. /* marked content */
  1269. proc->super.op_MP = pdf_balance_string;
  1270. proc->super.op_DP = pdf_balance_BDC;
  1271. proc->super.op_BMC = pdf_balance_string;
  1272. proc->super.op_BDC = pdf_balance_BDC;
  1273. proc->super.op_EMC = pdf_balance_void;
  1274. /* compatibility */
  1275. proc->super.op_BX = pdf_balance_void;
  1276. proc->super.op_EX = pdf_balance_void;
  1277. proc->super.op_EOD = pdf_balance_EOD;
  1278. proc->balance = balance;
  1279. proc->min_q = min_q;
  1280. proc->min_op_q = min_op_q;
  1281. return (pdf_processor*)proc;
  1282. }
  1283. void
  1284. pdf_count_q_balance(fz_context *ctx, pdf_document *doc, pdf_obj *res, pdf_obj *stm, int *prepend, int *append)
  1285. {
  1286. pdf_processor *proc;
  1287. int end_q = 0;
  1288. int min_q = 0;
  1289. int min_op_q = 1;
  1290. proc = pdf_new_balance_processor(ctx, &end_q, &min_q, &min_op_q);
  1291. fz_try(ctx)
  1292. {
  1293. pdf_process_raw_contents(ctx, proc, doc, res, stm, NULL);
  1294. pdf_close_processor(ctx, proc);
  1295. }
  1296. fz_always(ctx)
  1297. pdf_drop_processor(ctx, proc);
  1298. fz_catch(ctx)
  1299. fz_rethrow(ctx);
  1300. /* normally zero, but in bad files there could be more Q than q */
  1301. *prepend = -min_q;
  1302. /* how many Q are missing at the end */
  1303. *append = end_q - min_q;
  1304. /* if there are unguarded operators we must add one level of q/Q around everything */
  1305. if (min_op_q == min_q)
  1306. {
  1307. *prepend += 1;
  1308. *append += 1;
  1309. }
  1310. }