Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/source/pdf/pdf-op-color.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 // Copyright (C) 2004-2024 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 | |
| 23 #include "mupdf/fitz.h" | |
| 24 #include "mupdf/pdf.h" | |
| 25 | |
| 26 #include <string.h> | |
| 27 | |
| 28 enum { | |
| 29 UNMARKED_STROKE = 1, | |
| 30 UNMARKED_FILL = 2 | |
| 31 }; | |
| 32 | |
| 33 typedef struct gstate_stack | |
| 34 { | |
| 35 struct gstate_stack *next; | |
| 36 pdf_obj *cs_stroke; | |
| 37 pdf_obj *cs_fill; | |
| 38 int unmarked; | |
| 39 fz_matrix ctm; | |
| 40 } gstate_stack; | |
| 41 | |
| 42 typedef struct resources_stack | |
| 43 { | |
| 44 struct resources_stack *next; | |
| 45 pdf_obj *old_rdb; | |
| 46 pdf_obj *new_rdb; | |
| 47 } resources_stack; | |
| 48 | |
| 49 typedef struct | |
| 50 { | |
| 51 pdf_obj *cs; | |
| 52 float color[FZ_MAX_COLORS]; | |
| 53 } cs_color; | |
| 54 | |
| 55 #define MAX_REWRITTEN_NAME 32 | |
| 56 | |
| 57 typedef struct | |
| 58 { | |
| 59 pdf_obj *im_obj; | |
| 60 fz_image *after; | |
| 61 char name[MAX_REWRITTEN_NAME]; | |
| 62 } rewritten_image; | |
| 63 | |
| 64 typedef struct | |
| 65 { | |
| 66 int max; | |
| 67 int len; | |
| 68 rewritten_image *res; | |
| 69 } rewritten_images; | |
| 70 | |
| 71 typedef struct | |
| 72 { | |
| 73 pdf_obj *before; | |
| 74 fz_shade *after; | |
| 75 char name[MAX_REWRITTEN_NAME]; | |
| 76 } rewritten_shade; | |
| 77 | |
| 78 typedef struct | |
| 79 { | |
| 80 int max; | |
| 81 int len; | |
| 82 rewritten_shade *res; | |
| 83 } rewritten_shades; | |
| 84 | |
| 85 typedef struct | |
| 86 { | |
| 87 pdf_processor super; | |
| 88 pdf_document *doc; | |
| 89 int structparents; | |
| 90 pdf_processor *chain; | |
| 91 pdf_filter_options *global_options; | |
| 92 pdf_color_filter_options *options; | |
| 93 resources_stack *rstack; | |
| 94 gstate_stack *gstate; | |
| 95 cs_color *stroke; | |
| 96 cs_color *fill; | |
| 97 rewritten_images images; | |
| 98 rewritten_shades shades; | |
| 99 } pdf_color_processor; | |
| 100 | |
| 101 static void | |
| 102 push_rewritten_image(fz_context *ctx, pdf_color_processor *p, pdf_obj *im_obj, fz_image *after, char *name) | |
| 103 { | |
| 104 rewritten_images *list = &p->images; | |
| 105 | |
| 106 if (list->max == list->len) | |
| 107 { | |
| 108 int new_max = list->max * 2; | |
| 109 if (new_max == 0) | |
| 110 new_max = 32; | |
| 111 list->res = fz_realloc(ctx, list->res, sizeof(*list->res) * new_max); | |
| 112 list->max = new_max; | |
| 113 } | |
| 114 list->res[list->len].im_obj = pdf_keep_obj(ctx, im_obj); | |
| 115 list->res[list->len].after = fz_keep_image(ctx, after); | |
| 116 memcpy(list->res[list->len].name, name, MAX_REWRITTEN_NAME); | |
| 117 list->len++; | |
| 118 } | |
| 119 | |
| 120 static fz_image * | |
| 121 find_rewritten_image(fz_context *ctx, pdf_color_processor *p, pdf_obj *im_obj, char *name) | |
| 122 { | |
| 123 rewritten_images *list = &p->images; | |
| 124 int i; | |
| 125 | |
| 126 for (i = 0; i < list->len; i++) | |
| 127 if (list->res[i].im_obj == im_obj) | |
| 128 { | |
| 129 memcpy(name, list->res[i].name, MAX_REWRITTEN_NAME); | |
| 130 return list->res[i].after; | |
| 131 } | |
| 132 | |
| 133 return NULL; | |
| 134 } | |
| 135 | |
| 136 static void | |
| 137 drop_rewritten_images(fz_context *ctx, pdf_color_processor *p) | |
| 138 { | |
| 139 rewritten_images *list = &p->images; | |
| 140 int i; | |
| 141 | |
| 142 for (i = 0; i < list->len; i++) | |
| 143 { | |
| 144 pdf_drop_obj(ctx, list->res[i].im_obj); | |
| 145 fz_drop_image(ctx, list->res[i].after); | |
| 146 } | |
| 147 fz_free(ctx, list->res); | |
| 148 list->res = NULL; | |
| 149 list->len = 0; | |
| 150 list->max = 0; | |
| 151 } | |
| 152 | |
| 153 static void | |
| 154 push_rewritten_shade(fz_context *ctx, pdf_color_processor *p, pdf_obj *before, fz_shade *after, char *name) | |
| 155 { | |
| 156 rewritten_shades *list = &p->shades; | |
| 157 | |
| 158 if (list->max == list->len) | |
| 159 { | |
| 160 int new_max = list->max * 2; | |
| 161 if (new_max == 0) | |
| 162 new_max = 32; | |
| 163 list->res = fz_realloc(ctx, list->res, sizeof(*list->res) * new_max); | |
| 164 list->max = new_max; | |
| 165 } | |
| 166 list->res[list->len].before = pdf_keep_obj(ctx, before); | |
| 167 list->res[list->len].after = fz_keep_shade(ctx, after); | |
| 168 memcpy(list->res[list->len].name, name, MAX_REWRITTEN_NAME); | |
| 169 list->len++; | |
| 170 } | |
| 171 | |
| 172 static fz_shade * | |
| 173 find_rewritten_shade(fz_context *ctx, pdf_color_processor *p, pdf_obj *before, char *name) | |
| 174 { | |
| 175 rewritten_shades *list = &p->shades; | |
| 176 int i; | |
| 177 | |
| 178 for (i = 0; i < list->len; i++) | |
| 179 if (list->res[i].before == before) | |
| 180 { | |
| 181 memcpy(name, list->res[i].name, MAX_REWRITTEN_NAME); | |
| 182 return list->res[i].after; | |
| 183 } | |
| 184 | |
| 185 return NULL; | |
| 186 } | |
| 187 | |
| 188 static void | |
| 189 drop_rewritten_shades(fz_context *ctx, pdf_color_processor *p) | |
| 190 { | |
| 191 rewritten_shades *list = &p->shades; | |
| 192 int i; | |
| 193 | |
| 194 for (i = 0; i < list->len; i++) | |
| 195 { | |
| 196 pdf_drop_obj(ctx, list->res[i].before); | |
| 197 fz_drop_shade(ctx, list->res[i].after); | |
| 198 } | |
| 199 fz_free(ctx, list->res); | |
| 200 list->res = NULL; | |
| 201 list->len = 0; | |
| 202 list->max = 0; | |
| 203 } | |
| 204 | |
| 205 static void | |
| 206 make_resource_instance(fz_context *ctx, pdf_color_processor *p, pdf_obj *key, const char *prefix, char *buf, int len, pdf_obj *target) | |
| 207 { | |
| 208 int i; | |
| 209 | |
| 210 /* key gives us our category. Make sure we have such a category. */ | |
| 211 pdf_obj *res = pdf_dict_get(ctx, p->rstack->new_rdb, key); | |
| 212 if (!res) | |
| 213 res = pdf_dict_put_dict(ctx, p->rstack->new_rdb, key, 8); | |
| 214 | |
| 215 /* Now check through the category for each possible prefixed name | |
| 216 * in turn. */ | |
| 217 for (i = 1; i < 65536; ++i) | |
| 218 { | |
| 219 pdf_obj *obj; | |
| 220 fz_snprintf(buf, len, "%s%d", prefix, i); | |
| 221 | |
| 222 obj = pdf_dict_gets(ctx, res, buf); | |
| 223 if (!obj) | |
| 224 { | |
| 225 /* We've run out of names. At least that means we haven't | |
| 226 * previously added one ourselves. So add it now. */ | |
| 227 pdf_dict_puts(ctx, res, buf, target); | |
| 228 return; | |
| 229 } | |
| 230 if (pdf_objcmp_resolve(ctx, obj, target) == 0) | |
| 231 { | |
| 232 /* We've found this one before! */ | |
| 233 return; | |
| 234 } | |
| 235 } | |
| 236 fz_throw(ctx, FZ_ERROR_LIMIT, "Cannot create unique resource name"); | |
| 237 } | |
| 238 | |
| 239 static void | |
| 240 rewrite_cs(fz_context *ctx, pdf_color_processor *p, pdf_obj *cs_obj, int n, float *color, int stroking) | |
| 241 { | |
| 242 char new_name[MAX_REWRITTEN_NAME]; | |
| 243 fz_colorspace *cs = NULL; | |
| 244 pdf_pattern *pat = NULL; | |
| 245 fz_shade *shade = NULL; | |
| 246 int type; | |
| 247 | |
| 248 if (stroking) | |
| 249 p->gstate->unmarked &= ~UNMARKED_STROKE; | |
| 250 else | |
| 251 p->gstate->unmarked &= ~UNMARKED_FILL; | |
| 252 | |
| 253 /* Otherwise, if it's a name, look it up as a colorspace. */ | |
| 254 if (pdf_name_eq(ctx, cs_obj, PDF_NAME(DeviceGray)) || | |
| 255 pdf_name_eq(ctx, cs_obj, PDF_NAME(DeviceCMYK)) || | |
| 256 pdf_name_eq(ctx, cs_obj, PDF_NAME(DeviceRGB)) || | |
| 257 pdf_name_eq(ctx, cs_obj, PDF_NAME(Pattern))) | |
| 258 { | |
| 259 /* These names should not be looked up. */ | |
| 260 } | |
| 261 else if (pdf_is_name(ctx, cs_obj)) | |
| 262 { | |
| 263 /* Any other names should be looked up in the resource dict, | |
| 264 * because our rewrite function doesn't have access to that. */ | |
| 265 cs_obj = pdf_dict_get(ctx, pdf_dict_get(ctx, p->rstack->old_rdb, PDF_NAME(ColorSpace)), cs_obj); | |
| 266 } | |
| 267 | |
| 268 /* Until now, cs_obj has been a borrowed reference. Make it a real one. */ | |
| 269 pdf_keep_obj(ctx, cs_obj); | |
| 270 | |
| 271 /* Whatever happens, from here on in, we must drop cs_obj. */ | |
| 272 fz_var(cs); | |
| 273 fz_var(pat); | |
| 274 fz_var(shade); | |
| 275 | |
| 276 fz_try(ctx) | |
| 277 { | |
| 278 /* Our gstate always has to contain colorspaces BEFORE rewriting. | |
| 279 * Consider the case where we are given a separation space, and | |
| 280 * we rewrite it to be RGB. Then we change the 'amount' of that | |
| 281 * separation; we can't do that with the RGB value. */ | |
| 282 if (stroking) | |
| 283 { | |
| 284 pdf_drop_obj(ctx, p->gstate->cs_stroke); | |
| 285 p->gstate->cs_stroke = pdf_keep_obj(ctx, cs_obj); | |
| 286 } | |
| 287 else | |
| 288 { | |
| 289 pdf_drop_obj(ctx, p->gstate->cs_fill); | |
| 290 p->gstate->cs_fill = pdf_keep_obj(ctx, cs_obj); | |
| 291 } | |
| 292 /* Now, do any rewriting. This might drop the reference to cs_obj and | |
| 293 * return with a different one. */ | |
| 294 if (p->options->color_rewrite) | |
| 295 p->options->color_rewrite(ctx, p->options->opaque, &cs_obj, &n, color); | |
| 296 | |
| 297 /* If we've rewritten it to be a simple name, great! */ | |
| 298 if (pdf_name_eq(ctx, cs_obj, PDF_NAME(DeviceGray))) | |
| 299 { | |
| 300 if (stroking) | |
| 301 { | |
| 302 if (n == 1) | |
| 303 p->chain->op_G(ctx, p->chain, color[0]); | |
| 304 else | |
| 305 p->chain->op_CS(ctx, p->chain, "DeviceGray", fz_device_gray(ctx)); | |
| 306 } | |
| 307 else | |
| 308 { | |
| 309 if (n == 1) | |
| 310 p->chain->op_g(ctx, p->chain, color[0]); | |
| 311 else | |
| 312 p->chain->op_cs(ctx, p->chain, "DeviceGray", fz_device_gray(ctx)); | |
| 313 } | |
| 314 break; | |
| 315 } | |
| 316 | |
| 317 if (pdf_name_eq(ctx, cs_obj, PDF_NAME(DeviceRGB))) | |
| 318 { | |
| 319 if (stroking) | |
| 320 { | |
| 321 if (n == 3) | |
| 322 p->chain->op_RG(ctx, p->chain, color[0], color[1], color[2]); | |
| 323 else | |
| 324 p->chain->op_CS(ctx, p->chain, "DeviceRGB", fz_device_rgb(ctx)); | |
| 325 } | |
| 326 else | |
| 327 { | |
| 328 if (n == 3) | |
| 329 p->chain->op_rg(ctx, p->chain, color[0], color[1], color[2]); | |
| 330 else | |
| 331 p->chain->op_cs(ctx, p->chain, "DeviceRGB", fz_device_rgb(ctx)); | |
| 332 } | |
| 333 break; | |
| 334 } | |
| 335 | |
| 336 if (pdf_name_eq(ctx, cs_obj, PDF_NAME(DeviceCMYK))) | |
| 337 { | |
| 338 if (stroking) | |
| 339 { | |
| 340 if (n == 4) | |
| 341 p->chain->op_K(ctx, p->chain, color[0], color[1], color[2], color[3]); | |
| 342 else | |
| 343 p->chain->op_CS(ctx, p->chain, "DeviceCMYK", fz_device_cmyk(ctx)); | |
| 344 } | |
| 345 else | |
| 346 { | |
| 347 if (n == 4) | |
| 348 p->chain->op_k(ctx, p->chain, color[0], color[1], color[2], color[3]); | |
| 349 else | |
| 350 p->chain->op_cs(ctx, p->chain, "DeviceCMYK", fz_device_cmyk(ctx)); | |
| 351 } | |
| 352 break; | |
| 353 } | |
| 354 | |
| 355 /* Accept both /Pattern and [ /Pattern ] */ | |
| 356 if (pdf_name_eq(ctx, cs_obj, PDF_NAME(Pattern)) || | |
| 357 (pdf_array_len(ctx, cs_obj) == 1 && pdf_name_eq(ctx, pdf_array_get(ctx, cs_obj, 0), PDF_NAME(Pattern)))) | |
| 358 { | |
| 359 assert(n == 0); | |
| 360 if (stroking) | |
| 361 p->chain->op_CS(ctx, p->chain, "Pattern", NULL); | |
| 362 else | |
| 363 p->chain->op_cs(ctx, p->chain, "Pattern", NULL); | |
| 364 break; | |
| 365 } | |
| 366 | |
| 367 /* Has it been rewritten to be an array? */ | |
| 368 if (pdf_is_array(ctx, cs_obj)) | |
| 369 { | |
| 370 /* Make a new entry (or find an existing one), and send that. */ | |
| 371 make_resource_instance(ctx, p, PDF_NAME(ColorSpace), "CS", new_name, sizeof(new_name), cs_obj); | |
| 372 | |
| 373 cs = pdf_load_colorspace(ctx, cs_obj); | |
| 374 if (stroking) | |
| 375 p->chain->op_CS(ctx, p->chain, new_name, cs); | |
| 376 else | |
| 377 p->chain->op_cs(ctx, p->chain, new_name, cs); | |
| 378 | |
| 379 if (n > 0) | |
| 380 { | |
| 381 if (stroking) | |
| 382 p->chain->op_SC_color(ctx, p->chain, n, color); | |
| 383 else | |
| 384 p->chain->op_sc_color(ctx, p->chain, n, color); | |
| 385 } | |
| 386 break; | |
| 387 } | |
| 388 | |
| 389 /* Has it been rewritten to be a pattern? */ | |
| 390 type = pdf_dict_get_int(ctx, cs_obj, PDF_NAME(PatternType)); | |
| 391 if (type < 1 || type > 2) | |
| 392 fz_throw(ctx, FZ_ERROR_FORMAT, "Bad PatternType"); | |
| 393 | |
| 394 /* Make a new entry (or find an existing one), and send that. */ | |
| 395 make_resource_instance(ctx, p, PDF_NAME(Pattern), "Pa", new_name, sizeof(new_name), cs_obj); | |
| 396 | |
| 397 if (type == 1) | |
| 398 { | |
| 399 pat = pdf_load_pattern(ctx, p->doc, cs_obj); | |
| 400 if (stroking) | |
| 401 p->chain->op_SC_pattern(ctx, p->chain, new_name, pat, n, color); | |
| 402 else | |
| 403 p->chain->op_sc_pattern(ctx, p->chain, new_name, pat, n, color); | |
| 404 break; | |
| 405 } | |
| 406 else if (type == 2) | |
| 407 { | |
| 408 shade = pdf_load_shading(ctx, p->doc, cs_obj); | |
| 409 if (stroking) | |
| 410 p->chain->op_SC_shade(ctx, p->chain, new_name, shade); | |
| 411 else | |
| 412 p->chain->op_sc_shade(ctx, p->chain, new_name, shade); | |
| 413 break; | |
| 414 } | |
| 415 | |
| 416 fz_throw(ctx, FZ_ERROR_FORMAT, "Illegal rewritten colorspace"); | |
| 417 } | |
| 418 fz_always(ctx) | |
| 419 { | |
| 420 fz_drop_shade(ctx, shade); | |
| 421 fz_drop_colorspace(ctx, cs); | |
| 422 pdf_drop_pattern(ctx, pat); | |
| 423 pdf_drop_obj(ctx, cs_obj); | |
| 424 } | |
| 425 fz_catch(ctx) | |
| 426 fz_rethrow(ctx); | |
| 427 } | |
| 428 | |
| 429 static void | |
| 430 mark_stroke(fz_context *ctx, pdf_color_processor *p) | |
| 431 { | |
| 432 float zero[FZ_MAX_COLORS] = { 0 }; | |
| 433 | |
| 434 rewrite_cs(ctx, p, PDF_NAME(DeviceGray), 1, zero, 1); | |
| 435 | |
| 436 p->gstate->unmarked &= ~UNMARKED_STROKE; | |
| 437 } | |
| 438 | |
| 439 static void | |
| 440 mark_fill(fz_context *ctx, pdf_color_processor *p) | |
| 441 { | |
| 442 float zero[FZ_MAX_COLORS] = { 0 }; | |
| 443 | |
| 444 rewrite_cs(ctx, p, PDF_NAME(DeviceGray), 1, zero, 0); | |
| 445 | |
| 446 p->gstate->unmarked &= ~UNMARKED_FILL; | |
| 447 } | |
| 448 | |
| 449 /* general graphics state */ | |
| 450 | |
| 451 static void | |
| 452 pdf_color_w(fz_context *ctx, pdf_processor *proc, float linewidth) | |
| 453 { | |
| 454 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 455 | |
| 456 if (p->chain->op_w) | |
| 457 p->chain->op_w(ctx, p->chain, linewidth); | |
| 458 } | |
| 459 | |
| 460 static void | |
| 461 pdf_color_j(fz_context *ctx, pdf_processor *proc, int linejoin) | |
| 462 { | |
| 463 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 464 | |
| 465 if (p->chain->op_j) | |
| 466 p->chain->op_j(ctx, p->chain, linejoin); | |
| 467 } | |
| 468 | |
| 469 static void | |
| 470 pdf_color_J(fz_context *ctx, pdf_processor *proc, int linecap) | |
| 471 { | |
| 472 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 473 | |
| 474 if (p->chain->op_J) | |
| 475 p->chain->op_J(ctx, p->chain, linecap); | |
| 476 } | |
| 477 | |
| 478 static void | |
| 479 pdf_color_M(fz_context *ctx, pdf_processor *proc, float miterlimit) | |
| 480 { | |
| 481 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 482 | |
| 483 if (p->chain->op_M) | |
| 484 p->chain->op_M(ctx, p->chain, miterlimit); | |
| 485 } | |
| 486 | |
| 487 static void | |
| 488 pdf_color_d(fz_context *ctx, pdf_processor *proc, pdf_obj *array, float phase) | |
| 489 { | |
| 490 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 491 | |
| 492 if (p->chain->op_d) | |
| 493 p->chain->op_d(ctx, p->chain, array, phase); | |
| 494 } | |
| 495 | |
| 496 static void | |
| 497 pdf_color_ri(fz_context *ctx, pdf_processor *proc, const char *intent) | |
| 498 { | |
| 499 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 500 | |
| 501 if (p->chain->op_ri) | |
| 502 p->chain->op_ri(ctx, p->chain, intent); | |
| 503 } | |
| 504 | |
| 505 static void | |
| 506 pdf_color_gs_OP(fz_context *ctx, pdf_processor *proc, int b) | |
| 507 { | |
| 508 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 509 | |
| 510 if (p->chain->op_gs_OP) | |
| 511 p->chain->op_gs_OP(ctx, p->chain, b); | |
| 512 } | |
| 513 | |
| 514 static void | |
| 515 pdf_color_gs_op(fz_context *ctx, pdf_processor *proc, int b) | |
| 516 { | |
| 517 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 518 | |
| 519 if (p->chain->op_gs_op) | |
| 520 p->chain->op_gs_op(ctx, p->chain, b); | |
| 521 } | |
| 522 | |
| 523 static void | |
| 524 pdf_color_gs_OPM(fz_context *ctx, pdf_processor *proc, int i) | |
| 525 { | |
| 526 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 527 | |
| 528 if (p->chain->op_gs_OPM) | |
| 529 p->chain->op_gs_OPM(ctx, p->chain, i); | |
| 530 } | |
| 531 | |
| 532 static void | |
| 533 pdf_color_gs_UseBlackPtComp(fz_context *ctx, pdf_processor *proc, pdf_obj *name) | |
| 534 { | |
| 535 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 536 | |
| 537 if (p->chain->op_gs_UseBlackPtComp) | |
| 538 p->chain->op_gs_UseBlackPtComp(ctx, p->chain, name); | |
| 539 } | |
| 540 | |
| 541 static void | |
| 542 pdf_color_i(fz_context *ctx, pdf_processor *proc, float flatness) | |
| 543 { | |
| 544 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 545 | |
| 546 if (p->chain->op_i) | |
| 547 p->chain->op_i(ctx, p->chain, flatness); | |
| 548 } | |
| 549 | |
| 550 static void | |
| 551 pdf_color_gs_begin(fz_context *ctx, pdf_processor *proc, const char *name, pdf_obj *extgstate) | |
| 552 { | |
| 553 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 554 | |
| 555 if (p->chain->op_gs_begin) | |
| 556 p->chain->op_gs_begin(ctx, p->chain, name, extgstate); | |
| 557 } | |
| 558 | |
| 559 static void | |
| 560 pdf_color_gs_BM(fz_context *ctx, pdf_processor *proc, const char *blendmode) | |
| 561 { | |
| 562 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 563 | |
| 564 if (p->chain->op_gs_BM) | |
| 565 p->chain->op_gs_BM(ctx, p->chain, blendmode); | |
| 566 } | |
| 567 | |
| 568 static void | |
| 569 pdf_color_gs_CA(fz_context *ctx, pdf_processor *proc, float alpha) | |
| 570 { | |
| 571 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 572 | |
| 573 if (p->chain->op_gs_CA) | |
| 574 p->chain->op_gs_CA(ctx, p->chain, alpha); | |
| 575 } | |
| 576 | |
| 577 static void | |
| 578 pdf_color_gs_ca(fz_context *ctx, pdf_processor *proc, float alpha) | |
| 579 { | |
| 580 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 581 | |
| 582 if (p->chain->op_gs_ca) | |
| 583 p->chain->op_gs_ca(ctx, p->chain, alpha); | |
| 584 } | |
| 585 | |
| 586 static void | |
| 587 pdf_color_gs_SMask(fz_context *ctx, pdf_processor *proc, pdf_obj *smask, fz_colorspace *smask_cs, float *bc, int luminosity, pdf_obj *tr) | |
| 588 { | |
| 589 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 590 | |
| 591 if (p->chain->op_gs_SMask) | |
| 592 p->chain->op_gs_SMask(ctx, p->chain, smask, smask_cs, bc, luminosity, tr); | |
| 593 } | |
| 594 | |
| 595 static void | |
| 596 pdf_color_gs_end(fz_context *ctx, pdf_processor *proc) | |
| 597 { | |
| 598 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 599 | |
| 600 if (p->chain->op_gs_end) | |
| 601 p->chain->op_gs_end(ctx, p->chain); | |
| 602 } | |
| 603 | |
| 604 /* special graphics state */ | |
| 605 | |
| 606 static void | |
| 607 pdf_color_q(fz_context *ctx, pdf_processor *proc) | |
| 608 { | |
| 609 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 610 gstate_stack *gs = fz_malloc_struct(ctx, gstate_stack); | |
| 611 | |
| 612 gs->next = p->gstate; | |
| 613 gs->cs_fill = pdf_keep_obj(ctx, p->gstate->cs_fill); | |
| 614 gs->cs_stroke = pdf_keep_obj(ctx, p->gstate->cs_stroke); | |
| 615 gs->unmarked = p->gstate->unmarked; | |
| 616 gs->ctm = p->gstate->ctm; | |
| 617 p->gstate = gs; | |
| 618 | |
| 619 if (p->chain->op_q) | |
| 620 p->chain->op_q(ctx, p->chain); | |
| 621 } | |
| 622 | |
| 623 static void | |
| 624 pdf_color_cm(fz_context *ctx, pdf_processor *proc, float a, float b, float c, float d, float e, float f) | |
| 625 { | |
| 626 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 627 fz_matrix m; | |
| 628 | |
| 629 m.a = a; | |
| 630 m.b = b; | |
| 631 m.c = c; | |
| 632 m.d = d; | |
| 633 m.e = e; | |
| 634 m.f = f; | |
| 635 | |
| 636 p->gstate->ctm = fz_concat(m, p->gstate->ctm); | |
| 637 | |
| 638 if (p->chain->op_cm) | |
| 639 p->chain->op_cm(ctx, p->chain, a, b, c, d, e, f); | |
| 640 } | |
| 641 | |
| 642 /* path construction */ | |
| 643 | |
| 644 static void | |
| 645 pdf_color_m(fz_context *ctx, pdf_processor *proc, float x, float y) | |
| 646 { | |
| 647 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 648 | |
| 649 if (p->chain->op_m) | |
| 650 p->chain->op_m(ctx, p->chain, x, y); | |
| 651 } | |
| 652 | |
| 653 static void | |
| 654 pdf_color_l(fz_context *ctx, pdf_processor *proc, float x, float y) | |
| 655 { | |
| 656 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 657 | |
| 658 if (p->chain->op_l) | |
| 659 p->chain->op_l(ctx, p->chain, x, y); | |
| 660 } | |
| 661 | |
| 662 static void | |
| 663 pdf_color_c(fz_context *ctx, pdf_processor *proc, float x1, float y1, float x2, float y2, float x3, float y3) | |
| 664 { | |
| 665 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 666 | |
| 667 if (p->chain->op_c) | |
| 668 p->chain->op_c(ctx, p->chain, x1, y1, x2, y2, x3, y3); | |
| 669 } | |
| 670 | |
| 671 static void | |
| 672 pdf_color_v(fz_context *ctx, pdf_processor *proc, float x2, float y2, float x3, float y3) | |
| 673 { | |
| 674 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 675 | |
| 676 if (p->chain->op_v) | |
| 677 p->chain->op_v(ctx, p->chain, x2, y2, x3, y3); | |
| 678 } | |
| 679 | |
| 680 static void | |
| 681 pdf_color_y(fz_context *ctx, pdf_processor *proc, float x1, float y1, float x3, float y3) | |
| 682 { | |
| 683 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 684 | |
| 685 if (p->chain->op_y) | |
| 686 p->chain->op_y(ctx, p->chain, x1, y1, x3, y3); | |
| 687 } | |
| 688 | |
| 689 static void | |
| 690 pdf_color_h(fz_context *ctx, pdf_processor *proc) | |
| 691 { | |
| 692 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 693 | |
| 694 if (p->chain->op_h) | |
| 695 p->chain->op_h(ctx, p->chain); | |
| 696 } | |
| 697 | |
| 698 static void | |
| 699 pdf_color_re(fz_context *ctx, pdf_processor *proc, float x, float y, float w, float h) | |
| 700 { | |
| 701 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 702 | |
| 703 if (p->chain->op_re) | |
| 704 p->chain->op_re(ctx, p->chain, x, y, w, h); | |
| 705 } | |
| 706 | |
| 707 /* path painting */ | |
| 708 | |
| 709 static void | |
| 710 pdf_color_S(fz_context *ctx, pdf_processor *proc) | |
| 711 { | |
| 712 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 713 | |
| 714 if (p->gstate->unmarked & UNMARKED_STROKE) | |
| 715 mark_stroke(ctx, p); | |
| 716 | |
| 717 if (p->chain->op_S) | |
| 718 p->chain->op_S(ctx, p->chain); | |
| 719 } | |
| 720 | |
| 721 static void | |
| 722 pdf_color_s(fz_context *ctx, pdf_processor *proc) | |
| 723 { | |
| 724 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 725 | |
| 726 if (p->gstate->unmarked & UNMARKED_FILL) | |
| 727 mark_fill(ctx, p); | |
| 728 | |
| 729 if (p->chain->op_s) | |
| 730 p->chain->op_s(ctx, p->chain); | |
| 731 } | |
| 732 | |
| 733 static void | |
| 734 pdf_color_F(fz_context *ctx, pdf_processor *proc) | |
| 735 { | |
| 736 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 737 | |
| 738 if (p->gstate->unmarked & UNMARKED_FILL) | |
| 739 mark_fill(ctx, p); | |
| 740 | |
| 741 if (p->chain->op_F) | |
| 742 p->chain->op_F(ctx, p->chain); | |
| 743 } | |
| 744 | |
| 745 static void | |
| 746 pdf_color_f(fz_context *ctx, pdf_processor *proc) | |
| 747 { | |
| 748 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 749 | |
| 750 if (p->gstate->unmarked & UNMARKED_FILL) | |
| 751 mark_fill(ctx, p); | |
| 752 | |
| 753 if (p->chain->op_f) | |
| 754 p->chain->op_f(ctx, p->chain); | |
| 755 } | |
| 756 | |
| 757 static void | |
| 758 pdf_color_fstar(fz_context *ctx, pdf_processor *proc) | |
| 759 { | |
| 760 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 761 | |
| 762 if (p->gstate->unmarked & UNMARKED_FILL) | |
| 763 mark_fill(ctx, p); | |
| 764 | |
| 765 if (p->chain->op_fstar) | |
| 766 p->chain->op_fstar(ctx, p->chain); | |
| 767 } | |
| 768 | |
| 769 static void | |
| 770 pdf_color_B(fz_context *ctx, pdf_processor *proc) | |
| 771 { | |
| 772 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 773 | |
| 774 if (p->gstate->unmarked & UNMARKED_STROKE) | |
| 775 mark_stroke(ctx, p); | |
| 776 if (p->gstate->unmarked & UNMARKED_FILL) | |
| 777 mark_fill(ctx, p); | |
| 778 | |
| 779 if (p->chain->op_B) | |
| 780 p->chain->op_B(ctx, p->chain); | |
| 781 } | |
| 782 | |
| 783 static void | |
| 784 pdf_color_Bstar(fz_context *ctx, pdf_processor *proc) | |
| 785 { | |
| 786 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 787 | |
| 788 if (p->gstate->unmarked & UNMARKED_STROKE) | |
| 789 mark_stroke(ctx, p); | |
| 790 if (p->gstate->unmarked & UNMARKED_FILL) | |
| 791 mark_fill(ctx, p); | |
| 792 | |
| 793 if (p->chain->op_Bstar) | |
| 794 p->chain->op_Bstar(ctx, p->chain); | |
| 795 } | |
| 796 | |
| 797 static void | |
| 798 pdf_color_b(fz_context *ctx, pdf_processor *proc) | |
| 799 { | |
| 800 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 801 | |
| 802 if (p->gstate->unmarked & UNMARKED_STROKE) | |
| 803 mark_stroke(ctx, p); | |
| 804 if (p->gstate->unmarked & UNMARKED_FILL) | |
| 805 mark_fill(ctx, p); | |
| 806 | |
| 807 if (p->chain->op_b) | |
| 808 p->chain->op_b(ctx, p->chain); | |
| 809 } | |
| 810 | |
| 811 static void | |
| 812 pdf_color_bstar(fz_context *ctx, pdf_processor *proc) | |
| 813 { | |
| 814 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 815 | |
| 816 if (p->gstate->unmarked & UNMARKED_STROKE) | |
| 817 mark_stroke(ctx, p); | |
| 818 if (p->gstate->unmarked & UNMARKED_FILL) | |
| 819 mark_fill(ctx, p); | |
| 820 | |
| 821 if (p->chain->op_bstar) | |
| 822 p->chain->op_bstar(ctx, p->chain); | |
| 823 } | |
| 824 | |
| 825 static void | |
| 826 pdf_color_n(fz_context *ctx, pdf_processor *proc) | |
| 827 { | |
| 828 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 829 | |
| 830 if (p->chain->op_n) | |
| 831 p->chain->op_n(ctx, p->chain); | |
| 832 } | |
| 833 | |
| 834 /* clipping paths */ | |
| 835 | |
| 836 static void | |
| 837 pdf_color_W(fz_context *ctx, pdf_processor *proc) | |
| 838 { | |
| 839 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 840 | |
| 841 if (p->chain->op_W) | |
| 842 p->chain->op_W(ctx, p->chain); | |
| 843 } | |
| 844 | |
| 845 static void | |
| 846 pdf_color_Wstar(fz_context *ctx, pdf_processor *proc) | |
| 847 { | |
| 848 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 849 | |
| 850 if (p->chain->op_Wstar) | |
| 851 p->chain->op_Wstar(ctx, p->chain); | |
| 852 } | |
| 853 | |
| 854 /* text objects */ | |
| 855 | |
| 856 static void | |
| 857 pdf_color_BT(fz_context *ctx, pdf_processor *proc) | |
| 858 { | |
| 859 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 860 | |
| 861 if (p->chain->op_BT) | |
| 862 p->chain->op_BT(ctx, p->chain); | |
| 863 } | |
| 864 | |
| 865 static void | |
| 866 pdf_color_ET(fz_context *ctx, pdf_processor *proc) | |
| 867 { | |
| 868 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 869 | |
| 870 if (p->chain->op_ET) | |
| 871 p->chain->op_ET(ctx, p->chain); | |
| 872 } | |
| 873 | |
| 874 static void | |
| 875 pdf_color_Q(fz_context *ctx, pdf_processor *proc) | |
| 876 { | |
| 877 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 878 gstate_stack *gs = p->gstate; | |
| 879 | |
| 880 p->gstate = gs->next; | |
| 881 pdf_drop_obj(ctx, gs->cs_fill); | |
| 882 pdf_drop_obj(ctx, gs->cs_stroke); | |
| 883 | |
| 884 fz_try(ctx) | |
| 885 if (p->chain->op_Q) | |
| 886 p->chain->op_Q(ctx, p->chain); | |
| 887 fz_always(ctx) | |
| 888 fz_free(ctx, gs); | |
| 889 fz_catch(ctx) | |
| 890 fz_rethrow(ctx); | |
| 891 } | |
| 892 | |
| 893 /* text state */ | |
| 894 | |
| 895 static void | |
| 896 pdf_color_Tc(fz_context *ctx, pdf_processor *proc, float charspace) | |
| 897 { | |
| 898 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 899 | |
| 900 if (p->chain->op_Tc) | |
| 901 p->chain->op_Tc(ctx, p->chain, charspace); | |
| 902 } | |
| 903 | |
| 904 static void | |
| 905 pdf_color_Tw(fz_context *ctx, pdf_processor *proc, float wordspace) | |
| 906 { | |
| 907 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 908 | |
| 909 if (p->chain->op_Tw) | |
| 910 p->chain->op_Tw(ctx, p->chain, wordspace); | |
| 911 } | |
| 912 | |
| 913 static void | |
| 914 pdf_color_Tz(fz_context *ctx, pdf_processor *proc, float scale) | |
| 915 { | |
| 916 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 917 | |
| 918 if (p->chain->op_Tz) | |
| 919 p->chain->op_Tz(ctx, p->chain, scale); | |
| 920 } | |
| 921 | |
| 922 static void | |
| 923 pdf_color_TL(fz_context *ctx, pdf_processor *proc, float leading) | |
| 924 { | |
| 925 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 926 | |
| 927 if (p->chain->op_TL) | |
| 928 p->chain->op_TL(ctx, p->chain, leading); | |
| 929 } | |
| 930 | |
| 931 static void | |
| 932 pdf_color_Tf(fz_context *ctx, pdf_processor *proc, const char *name, pdf_font_desc *font, float size) | |
| 933 { | |
| 934 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 935 | |
| 936 if (p->chain->op_Tf) | |
| 937 p->chain->op_Tf(ctx, p->chain, name, font, size); | |
| 938 } | |
| 939 | |
| 940 static void | |
| 941 pdf_color_Tr(fz_context *ctx, pdf_processor *proc, int render) | |
| 942 { | |
| 943 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 944 | |
| 945 if (p->chain->op_Tr) | |
| 946 p->chain->op_Tr(ctx, p->chain, render); | |
| 947 } | |
| 948 | |
| 949 static void | |
| 950 pdf_color_Ts(fz_context *ctx, pdf_processor *proc, float rise) | |
| 951 { | |
| 952 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 953 | |
| 954 if (p->chain->op_Ts) | |
| 955 p->chain->op_Ts(ctx, p->chain, rise); | |
| 956 } | |
| 957 | |
| 958 /* text positioning */ | |
| 959 | |
| 960 static void | |
| 961 pdf_color_Td(fz_context *ctx, pdf_processor *proc, float tx, float ty) | |
| 962 { | |
| 963 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 964 | |
| 965 if (p->chain->op_Td) | |
| 966 p->chain->op_Td(ctx, p->chain, tx, ty); | |
| 967 } | |
| 968 | |
| 969 static void | |
| 970 pdf_color_TD(fz_context *ctx, pdf_processor *proc, float tx, float ty) | |
| 971 { | |
| 972 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 973 | |
| 974 if (p->chain->op_TD) | |
| 975 p->chain->op_TD(ctx, p->chain, tx, ty); | |
| 976 } | |
| 977 | |
| 978 static void | |
| 979 pdf_color_Tm(fz_context *ctx, pdf_processor *proc, float a, float b, float c, float d, float e, float f) | |
| 980 { | |
| 981 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 982 | |
| 983 if (p->chain->op_Tm) | |
| 984 p->chain->op_Tm(ctx, p->chain, a, b, c, d, e, f); | |
| 985 } | |
| 986 | |
| 987 static void | |
| 988 pdf_color_Tstar(fz_context *ctx, pdf_processor *proc) | |
| 989 { | |
| 990 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 991 | |
| 992 if (p->chain->op_Tstar) | |
| 993 p->chain->op_Tstar(ctx, p->chain); | |
| 994 } | |
| 995 | |
| 996 /* text showing */ | |
| 997 | |
| 998 static void | |
| 999 pdf_color_TJ(fz_context *ctx, pdf_processor *proc, pdf_obj *array) | |
| 1000 { | |
| 1001 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1002 | |
| 1003 /* FIXME: We could optimise this if we knew the Tr, maybe. */ | |
| 1004 if (p->gstate->unmarked & UNMARKED_STROKE) | |
| 1005 mark_stroke(ctx, p); | |
| 1006 if (p->gstate->unmarked & UNMARKED_FILL) | |
| 1007 mark_fill(ctx, p); | |
| 1008 | |
| 1009 if (p->chain->op_TJ) | |
| 1010 p->chain->op_TJ(ctx, p->chain, array); | |
| 1011 } | |
| 1012 | |
| 1013 static void | |
| 1014 pdf_color_Tj(fz_context *ctx, pdf_processor *proc, char *str, size_t len) | |
| 1015 { | |
| 1016 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1017 | |
| 1018 /* FIXME: We could optimise this if we knew the Tr, maybe. */ | |
| 1019 if (p->gstate->unmarked & UNMARKED_STROKE) | |
| 1020 mark_stroke(ctx, p); | |
| 1021 if (p->gstate->unmarked & UNMARKED_FILL) | |
| 1022 mark_fill(ctx, p); | |
| 1023 | |
| 1024 if (p->chain->op_Tj) | |
| 1025 p->chain->op_Tj(ctx, p->chain, str, len); | |
| 1026 } | |
| 1027 | |
| 1028 static void | |
| 1029 pdf_color_squote(fz_context *ctx, pdf_processor *proc, char *str, size_t len) | |
| 1030 { | |
| 1031 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1032 | |
| 1033 /* FIXME: We could optimise this if we knew the Tr, maybe. */ | |
| 1034 if (p->gstate->unmarked & UNMARKED_STROKE) | |
| 1035 mark_stroke(ctx, p); | |
| 1036 if (p->gstate->unmarked & UNMARKED_FILL) | |
| 1037 mark_fill(ctx, p); | |
| 1038 | |
| 1039 if (p->chain->op_squote) | |
| 1040 p->chain->op_squote(ctx, p->chain, str, len); | |
| 1041 } | |
| 1042 | |
| 1043 static void | |
| 1044 pdf_color_dquote(fz_context *ctx, pdf_processor *proc, float aw, float ac, char *str, size_t len) | |
| 1045 { | |
| 1046 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1047 | |
| 1048 /* FIXME: We could optimise this if we knew the Tr, maybe. */ | |
| 1049 if (p->gstate->unmarked & UNMARKED_STROKE) | |
| 1050 mark_stroke(ctx, p); | |
| 1051 if (p->gstate->unmarked & UNMARKED_FILL) | |
| 1052 mark_fill(ctx, p); | |
| 1053 | |
| 1054 if (p->chain->op_dquote) | |
| 1055 p->chain->op_dquote(ctx, p->chain, aw, ac, str, len); | |
| 1056 } | |
| 1057 | |
| 1058 /* type 3 fonts */ | |
| 1059 | |
| 1060 static void | |
| 1061 pdf_color_d0(fz_context *ctx, pdf_processor *proc, float wx, float wy) | |
| 1062 { | |
| 1063 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1064 | |
| 1065 if (p->chain->op_d0) | |
| 1066 p->chain->op_d0(ctx, p->chain, wx, wy); | |
| 1067 } | |
| 1068 | |
| 1069 static void | |
| 1070 pdf_color_d1(fz_context *ctx, pdf_processor *proc, float wx, float wy, float llx, float lly, float urx, float ury) | |
| 1071 { | |
| 1072 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1073 | |
| 1074 if (p->chain->op_d1) | |
| 1075 p->chain->op_d1(ctx, p->chain, wx, wy, llx, lly, urx, ury); | |
| 1076 } | |
| 1077 | |
| 1078 /* color */ | |
| 1079 | |
| 1080 static void | |
| 1081 pdf_color_CS(fz_context *ctx, pdf_processor *proc, const char *name, fz_colorspace *cs) | |
| 1082 { | |
| 1083 pdf_color_processor *p = (pdf_color_processor *)proc; | |
| 1084 pdf_obj *cs_obj = pdf_new_name(ctx, name); | |
| 1085 float color[FZ_MAX_COLORS] = { 1 }; | |
| 1086 | |
| 1087 fz_try(ctx) | |
| 1088 rewrite_cs(ctx, p, cs_obj, 0, color, 1); | |
| 1089 fz_always(ctx) | |
| 1090 pdf_drop_obj(ctx, cs_obj); | |
| 1091 fz_catch(ctx) | |
| 1092 fz_rethrow(ctx); | |
| 1093 } | |
| 1094 | |
| 1095 static void | |
| 1096 pdf_color_cs(fz_context *ctx, pdf_processor *proc, const char *name, fz_colorspace *cs) | |
| 1097 { | |
| 1098 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1099 pdf_obj *cs_obj = pdf_new_name(ctx, name); | |
| 1100 float color[FZ_MAX_COLORS] = { 1 }; | |
| 1101 | |
| 1102 fz_try(ctx) | |
| 1103 rewrite_cs(ctx, p, cs_obj, 0, color, 0); | |
| 1104 fz_always(ctx) | |
| 1105 pdf_drop_obj(ctx, cs_obj); | |
| 1106 fz_catch(ctx) | |
| 1107 fz_rethrow(ctx); | |
| 1108 } | |
| 1109 | |
| 1110 static void | |
| 1111 pdf_color_SC_pattern(fz_context *ctx, pdf_processor *proc, const char *name, pdf_pattern *pat, int n, float *color) | |
| 1112 { | |
| 1113 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1114 float local_color[FZ_MAX_COLORS] = { 0 }; | |
| 1115 pdf_obj *cs_obj = pdf_dict_gets(ctx, pdf_dict_get(ctx, p->rstack->old_rdb, PDF_NAME(Pattern)), name); | |
| 1116 | |
| 1117 memcpy(local_color, color, sizeof(float) * n); | |
| 1118 rewrite_cs(ctx, p, cs_obj, n, local_color, 1); | |
| 1119 } | |
| 1120 | |
| 1121 static void | |
| 1122 pdf_color_sc_pattern(fz_context *ctx, pdf_processor *proc, const char *name, pdf_pattern *pat, int n, float *color) | |
| 1123 { | |
| 1124 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1125 float local_color[FZ_MAX_COLORS] = { 0 }; | |
| 1126 pdf_obj *cs_obj = pdf_dict_gets(ctx, pdf_dict_get(ctx, p->rstack->old_rdb, PDF_NAME(Pattern)), name); | |
| 1127 | |
| 1128 memcpy(local_color, color, sizeof(float) * n); | |
| 1129 rewrite_cs(ctx, p, cs_obj, n, local_color, 0); | |
| 1130 } | |
| 1131 | |
| 1132 static void | |
| 1133 pdf_color_SC_shade(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade) | |
| 1134 { | |
| 1135 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1136 pdf_obj *orig; | |
| 1137 pdf_obj *dict = NULL; | |
| 1138 pdf_obj *dict2 = NULL; | |
| 1139 char new_name[MAX_REWRITTEN_NAME]; | |
| 1140 pdf_obj *rewritten; | |
| 1141 fz_shade *new_shade = NULL; | |
| 1142 | |
| 1143 if (p->options->shade_rewrite == NULL) | |
| 1144 { | |
| 1145 /* Must copy shading over to new resources dict. */ | |
| 1146 pdf_obj *old_obj = pdf_dict_gets(ctx, pdf_dict_get(ctx, p->rstack->old_rdb, PDF_NAME(Shading)), name); | |
| 1147 pdf_obj *new_shading_dict = pdf_dict_get(ctx, p->rstack->new_rdb, PDF_NAME(Shading)); | |
| 1148 if (new_shading_dict == NULL) | |
| 1149 pdf_dict_put_drop(ctx, p->rstack->new_rdb, PDF_NAME(Shading), new_shading_dict = pdf_new_dict(ctx, p->doc, 4)); | |
| 1150 pdf_dict_puts(ctx, new_shading_dict, name, old_obj); | |
| 1151 | |
| 1152 if (p->chain->op_SC_shade) | |
| 1153 p->chain->op_SC_shade(ctx, p->chain, name, shade); | |
| 1154 return; | |
| 1155 } | |
| 1156 | |
| 1157 orig = pdf_dict_gets(ctx, pdf_dict_get(ctx, p->rstack->old_rdb, PDF_NAME(Pattern)), name); | |
| 1158 orig = pdf_dict_get(ctx, orig, PDF_NAME(Shading)); | |
| 1159 | |
| 1160 new_shade = find_rewritten_shade(ctx, p, orig, new_name); | |
| 1161 if (new_shade) | |
| 1162 { | |
| 1163 /* Must copy shading over to new resources dict. */ | |
| 1164 pdf_obj *old_obj = pdf_dict_gets(ctx, pdf_dict_get(ctx, p->rstack->old_rdb, PDF_NAME(Shading)), name); | |
| 1165 pdf_obj *new_shading_dict = pdf_dict_get(ctx, p->rstack->new_rdb, PDF_NAME(Shading)); | |
| 1166 if (new_shading_dict == NULL) | |
| 1167 pdf_dict_put_drop(ctx, p->rstack->new_rdb, PDF_NAME(Shading), new_shading_dict = pdf_new_dict(ctx, p->doc, 4)); | |
| 1168 pdf_dict_puts(ctx, new_shading_dict, name, old_obj); | |
| 1169 | |
| 1170 if (p->chain->op_SC_shade) | |
| 1171 p->chain->op_SC_shade(ctx, p->chain, new_name, new_shade); | |
| 1172 return; | |
| 1173 } | |
| 1174 | |
| 1175 rewritten = pdf_recolor_shade(ctx, orig, p->options->shade_rewrite, p->options->opaque); | |
| 1176 | |
| 1177 fz_var(new_shade); | |
| 1178 fz_var(dict); | |
| 1179 fz_var(dict2); | |
| 1180 | |
| 1181 fz_try(ctx) | |
| 1182 { | |
| 1183 dict = pdf_new_dict(ctx, p->doc, 1); | |
| 1184 pdf_dict_put_int(ctx, dict, PDF_NAME(PatternType), 2); | |
| 1185 pdf_dict_put(ctx, dict, PDF_NAME(Shading), rewritten); | |
| 1186 dict2 = pdf_add_object(ctx, p->doc, dict); | |
| 1187 make_resource_instance(ctx, p, PDF_NAME(Pattern), "Pa", new_name, sizeof(new_name), dict2); | |
| 1188 | |
| 1189 new_shade = pdf_load_shading(ctx, p->doc, rewritten); | |
| 1190 | |
| 1191 /* Remember that we've done this one before. */ | |
| 1192 push_rewritten_shade(ctx, p, orig, new_shade, new_name); | |
| 1193 | |
| 1194 if (p->chain->op_sh) | |
| 1195 p->chain->op_SC_shade(ctx, p->chain, new_name, new_shade); | |
| 1196 } | |
| 1197 fz_always(ctx) | |
| 1198 { | |
| 1199 fz_drop_shade(ctx, new_shade); | |
| 1200 pdf_drop_obj(ctx, rewritten); | |
| 1201 pdf_drop_obj(ctx, dict); | |
| 1202 pdf_drop_obj(ctx, dict2); | |
| 1203 } | |
| 1204 fz_catch(ctx) | |
| 1205 fz_rethrow(ctx); | |
| 1206 } | |
| 1207 | |
| 1208 static void | |
| 1209 pdf_color_sc_shade(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade) | |
| 1210 { | |
| 1211 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1212 pdf_obj *orig; | |
| 1213 pdf_obj *dict = NULL; | |
| 1214 pdf_obj *dict2 = NULL; | |
| 1215 char new_name[MAX_REWRITTEN_NAME]; | |
| 1216 pdf_obj *rewritten; | |
| 1217 fz_shade *new_shade = NULL; | |
| 1218 | |
| 1219 if (p->options->shade_rewrite == NULL) | |
| 1220 { | |
| 1221 /* Must copy shading over to new resources dict. */ | |
| 1222 pdf_obj *old_obj = pdf_dict_gets(ctx, pdf_dict_get(ctx, p->rstack->old_rdb, PDF_NAME(Shading)), name); | |
| 1223 pdf_obj *new_shading_dict = pdf_dict_get(ctx, p->rstack->new_rdb, PDF_NAME(Shading)); | |
| 1224 if (new_shading_dict == NULL) | |
| 1225 pdf_dict_put_drop(ctx, p->rstack->new_rdb, PDF_NAME(Shading), new_shading_dict = pdf_new_dict(ctx, p->doc, 4)); | |
| 1226 pdf_dict_puts(ctx, new_shading_dict, name, old_obj); | |
| 1227 | |
| 1228 if (p->chain->op_sc_shade) | |
| 1229 p->chain->op_sc_shade(ctx, p->chain, name, shade); | |
| 1230 return; | |
| 1231 } | |
| 1232 | |
| 1233 orig = pdf_dict_gets(ctx, pdf_dict_get(ctx, p->rstack->old_rdb, PDF_NAME(Pattern)), name); | |
| 1234 orig = pdf_dict_get(ctx, orig, PDF_NAME(Shading)); | |
| 1235 | |
| 1236 new_shade = find_rewritten_shade(ctx, p, orig, new_name); | |
| 1237 if (new_shade) | |
| 1238 { | |
| 1239 if (p->chain->op_sc_shade) | |
| 1240 p->chain->op_sc_shade(ctx, p->chain, new_name, new_shade); | |
| 1241 return; | |
| 1242 } | |
| 1243 | |
| 1244 rewritten = pdf_recolor_shade(ctx, orig, p->options->shade_rewrite, p->options->opaque); | |
| 1245 | |
| 1246 fz_var(new_shade); | |
| 1247 fz_var(dict); | |
| 1248 fz_var(dict2); | |
| 1249 | |
| 1250 fz_try(ctx) | |
| 1251 { | |
| 1252 dict = pdf_new_dict(ctx, p->doc, 1); | |
| 1253 pdf_dict_put_int(ctx, dict, PDF_NAME(PatternType), 2); | |
| 1254 pdf_dict_put(ctx, dict, PDF_NAME(Shading), rewritten); | |
| 1255 dict2 = pdf_add_object(ctx, p->doc, dict); | |
| 1256 make_resource_instance(ctx, p, PDF_NAME(Pattern), "Pa", new_name, sizeof(new_name), dict2); | |
| 1257 | |
| 1258 new_shade = pdf_load_shading(ctx, p->doc, rewritten); | |
| 1259 | |
| 1260 /* Remember that we've done this one before. */ | |
| 1261 push_rewritten_shade(ctx, p, orig, new_shade, new_name); | |
| 1262 | |
| 1263 if (p->chain->op_sh) | |
| 1264 p->chain->op_sc_shade(ctx, p->chain, new_name, new_shade); | |
| 1265 } | |
| 1266 fz_always(ctx) | |
| 1267 { | |
| 1268 fz_drop_shade(ctx, new_shade); | |
| 1269 pdf_drop_obj(ctx, rewritten); | |
| 1270 pdf_drop_obj(ctx, dict); | |
| 1271 pdf_drop_obj(ctx, dict2); | |
| 1272 } | |
| 1273 fz_catch(ctx) | |
| 1274 fz_rethrow(ctx); | |
| 1275 } | |
| 1276 | |
| 1277 static void | |
| 1278 pdf_color_SC_color(fz_context *ctx, pdf_processor *proc, int n, float *color) | |
| 1279 { | |
| 1280 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1281 float local_color[FZ_MAX_COLORS] = { 0 }; | |
| 1282 pdf_obj *cs_obj = p->gstate->cs_stroke; | |
| 1283 | |
| 1284 memcpy(local_color, color, sizeof(float) * n); | |
| 1285 rewrite_cs(ctx, p, cs_obj, n, local_color, 1); | |
| 1286 } | |
| 1287 | |
| 1288 static void | |
| 1289 pdf_color_sc_color(fz_context *ctx, pdf_processor *proc, int n, float *color) | |
| 1290 { | |
| 1291 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1292 float local_color[FZ_MAX_COLORS] = { 0 }; | |
| 1293 pdf_obj *cs_obj = p->gstate->cs_fill; | |
| 1294 | |
| 1295 memcpy(local_color, color, sizeof(float) * n); | |
| 1296 rewrite_cs(ctx, p, cs_obj, n, local_color, 0); | |
| 1297 } | |
| 1298 | |
| 1299 static void | |
| 1300 pdf_color_G(fz_context *ctx, pdf_processor *proc, float g) | |
| 1301 { | |
| 1302 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1303 float local_color[FZ_MAX_COLORS] = { g }; | |
| 1304 | |
| 1305 rewrite_cs(ctx, p, PDF_NAME(DeviceGray), 1, local_color, 1); | |
| 1306 } | |
| 1307 | |
| 1308 static void | |
| 1309 pdf_color_g(fz_context *ctx, pdf_processor *proc, float g) | |
| 1310 { | |
| 1311 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1312 float local_color[FZ_MAX_COLORS] = { g }; | |
| 1313 | |
| 1314 rewrite_cs(ctx, p, PDF_NAME(DeviceGray), 1, local_color, 0); | |
| 1315 } | |
| 1316 | |
| 1317 static void | |
| 1318 pdf_color_RG(fz_context *ctx, pdf_processor *proc, float r, float g, float b) | |
| 1319 { | |
| 1320 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1321 float local_color[FZ_MAX_COLORS] = { r, g, b }; | |
| 1322 | |
| 1323 rewrite_cs(ctx, p, PDF_NAME(DeviceRGB), 3, local_color, 1); | |
| 1324 } | |
| 1325 | |
| 1326 static void | |
| 1327 pdf_color_rg(fz_context *ctx, pdf_processor *proc, float r, float g, float b) | |
| 1328 { | |
| 1329 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1330 float local_color[FZ_MAX_COLORS] = { r, g, b }; | |
| 1331 | |
| 1332 rewrite_cs(ctx, p, PDF_NAME(DeviceRGB), 3, local_color, 0); | |
| 1333 } | |
| 1334 | |
| 1335 static void | |
| 1336 pdf_color_K(fz_context *ctx, pdf_processor *proc, float c, float m, float y, float k) | |
| 1337 { | |
| 1338 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1339 float local_color[FZ_MAX_COLORS] = { c, m, y, k }; | |
| 1340 | |
| 1341 rewrite_cs(ctx, p, PDF_NAME(DeviceCMYK), 4, local_color, 1); | |
| 1342 } | |
| 1343 | |
| 1344 static void | |
| 1345 pdf_color_k(fz_context *ctx, pdf_processor *proc, float c, float m, float y, float k) | |
| 1346 { | |
| 1347 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1348 | |
| 1349 float local_color[FZ_MAX_COLORS] = { c, m, y, k }; | |
| 1350 | |
| 1351 rewrite_cs(ctx, p, PDF_NAME(DeviceCMYK), 4, local_color, 0); | |
| 1352 } | |
| 1353 | |
| 1354 /* shadings, images, xobjects */ | |
| 1355 | |
| 1356 static void | |
| 1357 pdf_color_BI(fz_context *ctx, pdf_processor *proc, fz_image *image, const char *colorspace) | |
| 1358 { | |
| 1359 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1360 | |
| 1361 if (image->imagemask) | |
| 1362 { | |
| 1363 /* Imagemasks require the color to have been set. */ | |
| 1364 if (p->gstate->unmarked & UNMARKED_FILL) | |
| 1365 mark_fill(ctx, p); | |
| 1366 } | |
| 1367 | |
| 1368 fz_keep_image(ctx, image); | |
| 1369 if (p->options->image_rewrite) | |
| 1370 p->options->image_rewrite(ctx, p->options->opaque, &image, p->gstate->ctm, NULL); | |
| 1371 | |
| 1372 if (p->chain->op_BI) | |
| 1373 p->chain->op_BI(ctx, p->chain, image, colorspace); | |
| 1374 fz_drop_image(ctx, image); | |
| 1375 } | |
| 1376 | |
| 1377 static void | |
| 1378 pdf_color_sh(fz_context *ctx, pdf_processor *proc, const char *name, fz_shade *shade) | |
| 1379 { | |
| 1380 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1381 pdf_obj *orig; | |
| 1382 char new_name[MAX_REWRITTEN_NAME]; | |
| 1383 pdf_obj *rewritten; | |
| 1384 fz_shade *new_shade = NULL; | |
| 1385 | |
| 1386 if (p->options->shade_rewrite == NULL) | |
| 1387 { | |
| 1388 /* Must copy shading over to new resources dict. */ | |
| 1389 pdf_obj *old_obj = pdf_dict_gets(ctx, pdf_dict_get(ctx, p->rstack->old_rdb, PDF_NAME(Shading)), name); | |
| 1390 pdf_obj *new_shading_dict = pdf_dict_get(ctx, p->rstack->new_rdb, PDF_NAME(Shading)); | |
| 1391 if (new_shading_dict == NULL) | |
| 1392 pdf_dict_put_drop(ctx, p->rstack->new_rdb, PDF_NAME(Shading), new_shading_dict = pdf_new_dict(ctx, p->doc, 4)); | |
| 1393 pdf_dict_puts(ctx, new_shading_dict, name, old_obj); | |
| 1394 | |
| 1395 if (p->chain->op_sh) | |
| 1396 p->chain->op_sh(ctx, p->chain, name, shade); | |
| 1397 return; | |
| 1398 } | |
| 1399 | |
| 1400 orig = pdf_dict_gets(ctx, pdf_dict_get(ctx, p->rstack->old_rdb, PDF_NAME(Shading)), name); | |
| 1401 | |
| 1402 new_shade = find_rewritten_shade(ctx, p, orig, new_name); | |
| 1403 if (new_shade) | |
| 1404 { | |
| 1405 if (p->chain->op_sh) | |
| 1406 p->chain->op_sh(ctx, p->chain, new_name, new_shade); | |
| 1407 return; | |
| 1408 } | |
| 1409 | |
| 1410 rewritten = pdf_recolor_shade(ctx, orig, p->options->shade_rewrite, p->options->opaque); | |
| 1411 | |
| 1412 fz_var(new_shade); | |
| 1413 | |
| 1414 fz_try(ctx) | |
| 1415 { | |
| 1416 make_resource_instance(ctx, p, PDF_NAME(Shading), "Sh", new_name, sizeof(new_name), rewritten); | |
| 1417 | |
| 1418 new_shade = pdf_load_shading(ctx, p->doc, rewritten); | |
| 1419 | |
| 1420 /* Remember that we've done this one before. */ | |
| 1421 push_rewritten_shade(ctx, p, orig, new_shade, new_name); | |
| 1422 | |
| 1423 if (p->chain->op_sh) | |
| 1424 p->chain->op_sh(ctx, p->chain, new_name, new_shade); | |
| 1425 } | |
| 1426 fz_always(ctx) | |
| 1427 { | |
| 1428 fz_drop_shade(ctx, new_shade); | |
| 1429 pdf_drop_obj(ctx, rewritten); | |
| 1430 } | |
| 1431 fz_catch(ctx) | |
| 1432 fz_rethrow(ctx); | |
| 1433 } | |
| 1434 | |
| 1435 static void | |
| 1436 pdf_color_Do_image(fz_context *ctx, pdf_processor *proc, const char *name, fz_image *image) | |
| 1437 { | |
| 1438 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1439 fz_image *orig = image; | |
| 1440 char new_name[MAX_REWRITTEN_NAME]; | |
| 1441 pdf_obj *im_obj = pdf_dict_gets(ctx, pdf_dict_get(ctx, p->rstack->old_rdb, PDF_NAME(XObject)), name); | |
| 1442 | |
| 1443 /* Have we done this one before? */ | |
| 1444 if (!p->options->repeated_image_rewrite) | |
| 1445 { | |
| 1446 image = find_rewritten_image(ctx, p, im_obj, new_name); | |
| 1447 if (image) | |
| 1448 { | |
| 1449 if (p->chain->op_Do_image) | |
| 1450 p->chain->op_Do_image(ctx, p->chain, new_name, image); | |
| 1451 return; | |
| 1452 } | |
| 1453 } | |
| 1454 | |
| 1455 image = orig; | |
| 1456 fz_keep_image(ctx, image); | |
| 1457 pdf_keep_obj(ctx, im_obj); | |
| 1458 | |
| 1459 fz_var(im_obj); | |
| 1460 fz_try(ctx) | |
| 1461 { | |
| 1462 | |
| 1463 if (image->imagemask) | |
| 1464 { | |
| 1465 /* Imagemasks require the color to have been set. */ | |
| 1466 if (p->gstate->unmarked & UNMARKED_FILL) | |
| 1467 mark_fill(ctx, p); | |
| 1468 } | |
| 1469 else | |
| 1470 { | |
| 1471 if (p->options->image_rewrite) | |
| 1472 p->options->image_rewrite(ctx, p->options->opaque, &image, p->gstate->ctm, im_obj); | |
| 1473 } | |
| 1474 | |
| 1475 /* If it's been rewritten add the new one, otherwise copy the old one across. */ | |
| 1476 if (image != orig) | |
| 1477 { | |
| 1478 pdf_drop_obj(ctx, im_obj); | |
| 1479 im_obj = NULL; | |
| 1480 im_obj = pdf_add_image(ctx, p->doc, image); | |
| 1481 } | |
| 1482 | |
| 1483 make_resource_instance(ctx, p, PDF_NAME(XObject), "Im", new_name, sizeof(new_name), im_obj); | |
| 1484 | |
| 1485 if (!p->options->repeated_image_rewrite) | |
| 1486 { | |
| 1487 /* Remember that we've done this one before. */ | |
| 1488 push_rewritten_image(ctx, p, im_obj, image, new_name); | |
| 1489 } | |
| 1490 | |
| 1491 if (p->chain->op_Do_image) | |
| 1492 p->chain->op_Do_image(ctx, p->chain, new_name, image); | |
| 1493 } | |
| 1494 fz_always(ctx) | |
| 1495 { | |
| 1496 pdf_drop_obj(ctx, im_obj); | |
| 1497 fz_drop_image(ctx, image); | |
| 1498 } | |
| 1499 fz_catch(ctx) | |
| 1500 fz_rethrow(ctx); | |
| 1501 } | |
| 1502 | |
| 1503 static void | |
| 1504 pdf_color_Do_form(fz_context *ctx, pdf_processor *proc, const char *name, pdf_obj *xobj) | |
| 1505 { | |
| 1506 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1507 char new_name[MAX_REWRITTEN_NAME]; | |
| 1508 pdf_obj *xres; | |
| 1509 pdf_obj *new_xres = NULL; | |
| 1510 | |
| 1511 fz_var(new_xres); | |
| 1512 | |
| 1513 /* FIXME: Ideally we'd look at p->global_options->instance_forms here | |
| 1514 * to avoid flattening all the XObjects. This is non-trivial, and | |
| 1515 * currently incomplete, hence disabled. We have to find some way to | |
| 1516 * tell the underlying filters (in particular the output filter) that | |
| 1517 * we are in a new XObject (so the output filter can start a new buffer). | |
| 1518 * Maybe it could look at p->global_options->instance_forms too on a | |
| 1519 * push/pop of the resources? For now, let's just leave it disabled. */ | |
| 1520 if (0 && p->global_options->instance_forms) | |
| 1521 { | |
| 1522 make_resource_instance(ctx, p, PDF_NAME(XObject), "Xo", new_name, sizeof(new_name), xobj); | |
| 1523 | |
| 1524 xres = pdf_xobject_resources(ctx, xobj); | |
| 1525 fz_try(ctx) | |
| 1526 pdf_process_contents(ctx, (pdf_processor *)p, p->doc, xres, xobj, NULL, &new_xres); | |
| 1527 fz_catch(ctx) | |
| 1528 { | |
| 1529 pdf_drop_obj(ctx, new_xres); | |
| 1530 fz_rethrow(ctx); | |
| 1531 } | |
| 1532 | |
| 1533 pdf_dict_put_drop(ctx, xobj, PDF_NAME(Resources), new_xres); | |
| 1534 | |
| 1535 if (p->chain->op_Do_form) | |
| 1536 p->chain->op_Do_form(ctx, p->chain, new_name, xobj); | |
| 1537 } | |
| 1538 else | |
| 1539 { | |
| 1540 /* In this case, we just copy the XObject across (renaming it). Our caller will arrange to | |
| 1541 * filter it. */ | |
| 1542 make_resource_instance(ctx, p, PDF_NAME(XObject), "Xo", new_name, sizeof(new_name), xobj); | |
| 1543 if (p->chain->op_Do_form) | |
| 1544 p->chain->op_Do_form(ctx, p->chain, new_name, xobj); | |
| 1545 } | |
| 1546 } | |
| 1547 | |
| 1548 /* marked content */ | |
| 1549 | |
| 1550 static void | |
| 1551 pdf_color_MP(fz_context *ctx, pdf_processor *proc, const char *tag) | |
| 1552 { | |
| 1553 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1554 | |
| 1555 if (p->chain->op_MP) | |
| 1556 p->chain->op_MP(ctx, p->chain, tag); | |
| 1557 } | |
| 1558 | |
| 1559 static void | |
| 1560 pdf_color_DP(fz_context *ctx, pdf_processor *proc, const char *tag, pdf_obj *raw, pdf_obj *cooked) | |
| 1561 { | |
| 1562 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1563 | |
| 1564 if (p->chain->op_DP) | |
| 1565 p->chain->op_DP(ctx, p->chain, tag, raw, cooked); | |
| 1566 } | |
| 1567 | |
| 1568 static void | |
| 1569 pdf_color_BMC(fz_context *ctx, pdf_processor *proc, const char *tag) | |
| 1570 { | |
| 1571 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1572 | |
| 1573 if (p->chain->op_BMC) | |
| 1574 p->chain->op_BMC(ctx, p->chain, tag); | |
| 1575 } | |
| 1576 | |
| 1577 static void | |
| 1578 pdf_color_BDC(fz_context *ctx, pdf_processor *proc, const char *tag, pdf_obj *raw, pdf_obj *cooked) | |
| 1579 { | |
| 1580 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1581 | |
| 1582 if (p->chain->op_BDC) | |
| 1583 p->chain->op_BDC(ctx, p->chain, tag, raw, cooked); | |
| 1584 } | |
| 1585 | |
| 1586 static void | |
| 1587 pdf_color_EMC(fz_context *ctx, pdf_processor *proc) | |
| 1588 { | |
| 1589 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1590 | |
| 1591 if (p->chain->op_EMC) | |
| 1592 p->chain->op_EMC(ctx, p->chain); | |
| 1593 } | |
| 1594 | |
| 1595 /* compatibility */ | |
| 1596 | |
| 1597 static void | |
| 1598 pdf_color_BX(fz_context *ctx, pdf_processor *proc) | |
| 1599 { | |
| 1600 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1601 | |
| 1602 if (p->chain->op_BX) | |
| 1603 p->chain->op_BX(ctx, p->chain); | |
| 1604 } | |
| 1605 | |
| 1606 static void | |
| 1607 pdf_color_EX(fz_context *ctx, pdf_processor *proc) | |
| 1608 { | |
| 1609 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1610 | |
| 1611 if (p->chain->op_EX) | |
| 1612 p->chain->op_EX(ctx, p->chain); | |
| 1613 } | |
| 1614 | |
| 1615 static void | |
| 1616 pdf_color_END(fz_context *ctx, pdf_processor *proc) | |
| 1617 { | |
| 1618 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1619 | |
| 1620 if (p->chain->op_END) | |
| 1621 p->chain->op_END(ctx, p->chain); | |
| 1622 } | |
| 1623 | |
| 1624 static void | |
| 1625 pdf_close_color_processor(fz_context *ctx, pdf_processor *proc) | |
| 1626 { | |
| 1627 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1628 | |
| 1629 pdf_close_processor(ctx, p->chain); | |
| 1630 } | |
| 1631 | |
| 1632 static void | |
| 1633 pdf_drop_color_processor(fz_context *ctx, pdf_processor *proc) | |
| 1634 { | |
| 1635 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1636 gstate_stack *gs = p->gstate; | |
| 1637 | |
| 1638 while (gs) | |
| 1639 { | |
| 1640 gstate_stack *gs_next = gs->next; | |
| 1641 | |
| 1642 pdf_drop_obj(ctx, gs->cs_fill); | |
| 1643 pdf_drop_obj(ctx, gs->cs_stroke); | |
| 1644 fz_free(ctx, gs); | |
| 1645 gs = gs_next; | |
| 1646 } | |
| 1647 drop_rewritten_images(ctx, p); | |
| 1648 drop_rewritten_shades(ctx, p); | |
| 1649 | |
| 1650 pdf_drop_document(ctx, p->doc); | |
| 1651 } | |
| 1652 | |
| 1653 static void | |
| 1654 pdf_color_push_resources(fz_context *ctx, pdf_processor *proc, pdf_obj *res) | |
| 1655 { | |
| 1656 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1657 resources_stack *stk = fz_malloc_struct(ctx, resources_stack); | |
| 1658 pdf_obj *obj; | |
| 1659 | |
| 1660 p->gstate->unmarked = UNMARKED_STROKE | UNMARKED_FILL; | |
| 1661 | |
| 1662 stk->next = p->rstack; | |
| 1663 p->rstack = stk; | |
| 1664 fz_try(ctx) | |
| 1665 { | |
| 1666 stk->old_rdb = pdf_keep_obj(ctx, res); | |
| 1667 /* At the moment we know that we'll always be flattening XObjects. | |
| 1668 * So only the top level 'push' makes a new resource dict. Any | |
| 1669 * subsequent one will share the previous levels one. */ | |
| 1670 if (stk->next) | |
| 1671 stk->new_rdb = pdf_keep_obj(ctx, stk->next->new_rdb); | |
| 1672 else | |
| 1673 stk->new_rdb = pdf_new_dict(ctx, p->doc, 1); | |
| 1674 | |
| 1675 obj = pdf_dict_get(ctx, res, PDF_NAME(Properties)); | |
| 1676 if (obj) | |
| 1677 pdf_dict_put(ctx, stk->new_rdb, PDF_NAME(Properties), obj); | |
| 1678 obj = pdf_dict_get(ctx, res, PDF_NAME(ExtGState)); | |
| 1679 if (obj) | |
| 1680 pdf_dict_put(ctx, stk->new_rdb, PDF_NAME(ExtGState), obj); | |
| 1681 obj = pdf_dict_get(ctx, res, PDF_NAME(Font)); | |
| 1682 if (obj) | |
| 1683 pdf_dict_put(ctx, stk->new_rdb, PDF_NAME(Font), obj); | |
| 1684 | |
| 1685 pdf_processor_push_resources(ctx, p->chain, stk->new_rdb); | |
| 1686 } | |
| 1687 fz_catch(ctx) | |
| 1688 { | |
| 1689 pdf_drop_obj(ctx, stk->old_rdb); | |
| 1690 pdf_drop_obj(ctx, stk->new_rdb); | |
| 1691 fz_free(ctx, stk); | |
| 1692 p->rstack = stk->next; | |
| 1693 fz_rethrow(ctx); | |
| 1694 } | |
| 1695 } | |
| 1696 | |
| 1697 static pdf_obj * | |
| 1698 pdf_color_pop_resources(fz_context *ctx, pdf_processor *proc) | |
| 1699 { | |
| 1700 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1701 resources_stack *stk = p->rstack; | |
| 1702 | |
| 1703 p->rstack = stk->next; | |
| 1704 pdf_drop_obj(ctx, stk->old_rdb); | |
| 1705 pdf_drop_obj(ctx, stk->new_rdb); | |
| 1706 fz_free(ctx, stk); | |
| 1707 | |
| 1708 return pdf_processor_pop_resources(ctx, p->chain); | |
| 1709 } | |
| 1710 | |
| 1711 static void | |
| 1712 pdf_reset_color_processor(fz_context *ctx, pdf_processor *proc) | |
| 1713 { | |
| 1714 pdf_color_processor *p = (pdf_color_processor*)proc; | |
| 1715 | |
| 1716 pdf_reset_processor(ctx, p->chain); | |
| 1717 } | |
| 1718 | |
| 1719 pdf_processor * | |
| 1720 pdf_new_color_filter( | |
| 1721 fz_context *ctx, | |
| 1722 pdf_document *doc, | |
| 1723 pdf_processor *chain, | |
| 1724 int struct_parents, | |
| 1725 fz_matrix transform, | |
| 1726 pdf_filter_options *global_options, | |
| 1727 void *options_) | |
| 1728 { | |
| 1729 pdf_color_processor *proc = pdf_new_processor(ctx, sizeof * proc); | |
| 1730 pdf_color_filter_options *options = (pdf_color_filter_options *)options_; | |
| 1731 | |
| 1732 proc->super.close_processor = pdf_close_color_processor; | |
| 1733 proc->super.drop_processor = pdf_drop_color_processor; | |
| 1734 proc->super.reset_processor = pdf_reset_color_processor; | |
| 1735 | |
| 1736 proc->super.push_resources = pdf_color_push_resources; | |
| 1737 proc->super.pop_resources = pdf_color_pop_resources; | |
| 1738 | |
| 1739 /* general graphics state */ | |
| 1740 proc->super.op_w = pdf_color_w; | |
| 1741 proc->super.op_j = pdf_color_j; | |
| 1742 proc->super.op_J = pdf_color_J; | |
| 1743 proc->super.op_M = pdf_color_M; | |
| 1744 proc->super.op_d = pdf_color_d; | |
| 1745 proc->super.op_ri = pdf_color_ri; | |
| 1746 proc->super.op_i = pdf_color_i; | |
| 1747 proc->super.op_gs_begin = pdf_color_gs_begin; | |
| 1748 proc->super.op_gs_end = pdf_color_gs_end; | |
| 1749 | |
| 1750 /* transparency graphics state */ | |
| 1751 proc->super.op_gs_BM = pdf_color_gs_BM; | |
| 1752 proc->super.op_gs_CA = pdf_color_gs_CA; | |
| 1753 proc->super.op_gs_ca = pdf_color_gs_ca; | |
| 1754 proc->super.op_gs_SMask = pdf_color_gs_SMask; | |
| 1755 | |
| 1756 /* special graphics state */ | |
| 1757 proc->super.op_q = pdf_color_q; | |
| 1758 proc->super.op_Q = pdf_color_Q; | |
| 1759 proc->super.op_cm = pdf_color_cm; | |
| 1760 | |
| 1761 /* path construction */ | |
| 1762 proc->super.op_m = pdf_color_m; | |
| 1763 proc->super.op_l = pdf_color_l; | |
| 1764 proc->super.op_c = pdf_color_c; | |
| 1765 proc->super.op_v = pdf_color_v; | |
| 1766 proc->super.op_y = pdf_color_y; | |
| 1767 proc->super.op_h = pdf_color_h; | |
| 1768 proc->super.op_re = pdf_color_re; | |
| 1769 | |
| 1770 /* path painting */ | |
| 1771 proc->super.op_S = pdf_color_S; | |
| 1772 proc->super.op_s = pdf_color_s; | |
| 1773 proc->super.op_F = pdf_color_F; | |
| 1774 proc->super.op_f = pdf_color_f; | |
| 1775 proc->super.op_fstar = pdf_color_fstar; | |
| 1776 proc->super.op_B = pdf_color_B; | |
| 1777 proc->super.op_Bstar = pdf_color_Bstar; | |
| 1778 proc->super.op_b = pdf_color_b; | |
| 1779 proc->super.op_bstar = pdf_color_bstar; | |
| 1780 proc->super.op_n = pdf_color_n; | |
| 1781 | |
| 1782 /* clipping paths */ | |
| 1783 proc->super.op_W = pdf_color_W; | |
| 1784 proc->super.op_Wstar = pdf_color_Wstar; | |
| 1785 | |
| 1786 /* text objects */ | |
| 1787 proc->super.op_BT = pdf_color_BT; | |
| 1788 proc->super.op_ET = pdf_color_ET; | |
| 1789 | |
| 1790 /* text state */ | |
| 1791 proc->super.op_Tc = pdf_color_Tc; | |
| 1792 proc->super.op_Tw = pdf_color_Tw; | |
| 1793 proc->super.op_Tz = pdf_color_Tz; | |
| 1794 proc->super.op_TL = pdf_color_TL; | |
| 1795 proc->super.op_Tf = pdf_color_Tf; | |
| 1796 proc->super.op_Tr = pdf_color_Tr; | |
| 1797 proc->super.op_Ts = pdf_color_Ts; | |
| 1798 | |
| 1799 /* text positioning */ | |
| 1800 proc->super.op_Td = pdf_color_Td; | |
| 1801 proc->super.op_TD = pdf_color_TD; | |
| 1802 proc->super.op_Tm = pdf_color_Tm; | |
| 1803 proc->super.op_Tstar = pdf_color_Tstar; | |
| 1804 | |
| 1805 /* text showing */ | |
| 1806 proc->super.op_TJ = pdf_color_TJ; | |
| 1807 proc->super.op_Tj = pdf_color_Tj; | |
| 1808 proc->super.op_squote = pdf_color_squote; | |
| 1809 proc->super.op_dquote = pdf_color_dquote; | |
| 1810 | |
| 1811 /* type 3 fonts */ | |
| 1812 proc->super.op_d0 = pdf_color_d0; | |
| 1813 proc->super.op_d1 = pdf_color_d1; | |
| 1814 | |
| 1815 /* color */ | |
| 1816 proc->super.op_CS = pdf_color_CS; | |
| 1817 proc->super.op_cs = pdf_color_cs; | |
| 1818 proc->super.op_SC_color = pdf_color_SC_color; | |
| 1819 proc->super.op_sc_color = pdf_color_sc_color; | |
| 1820 proc->super.op_SC_pattern = pdf_color_SC_pattern; | |
| 1821 proc->super.op_sc_pattern = pdf_color_sc_pattern; | |
| 1822 proc->super.op_SC_shade = pdf_color_SC_shade; | |
| 1823 proc->super.op_sc_shade = pdf_color_sc_shade; | |
| 1824 | |
| 1825 proc->super.op_G = pdf_color_G; | |
| 1826 proc->super.op_g = pdf_color_g; | |
| 1827 proc->super.op_RG = pdf_color_RG; | |
| 1828 proc->super.op_rg = pdf_color_rg; | |
| 1829 proc->super.op_K = pdf_color_K; | |
| 1830 proc->super.op_k = pdf_color_k; | |
| 1831 | |
| 1832 /* shadings, images, xobjects */ | |
| 1833 proc->super.op_BI = pdf_color_BI; | |
| 1834 proc->super.op_sh = pdf_color_sh; | |
| 1835 proc->super.op_Do_image = pdf_color_Do_image; | |
| 1836 proc->super.op_Do_form = pdf_color_Do_form; | |
| 1837 | |
| 1838 /* marked content */ | |
| 1839 proc->super.op_MP = pdf_color_MP; | |
| 1840 proc->super.op_DP = pdf_color_DP; | |
| 1841 proc->super.op_BMC = pdf_color_BMC; | |
| 1842 proc->super.op_BDC = pdf_color_BDC; | |
| 1843 proc->super.op_EMC = pdf_color_EMC; | |
| 1844 | |
| 1845 /* compatibility */ | |
| 1846 proc->super.op_BX = pdf_color_BX; | |
| 1847 proc->super.op_EX = pdf_color_EX; | |
| 1848 | |
| 1849 /* extgstate */ | |
| 1850 proc->super.op_gs_OP = pdf_color_gs_OP; | |
| 1851 proc->super.op_gs_op = pdf_color_gs_op; | |
| 1852 proc->super.op_gs_OPM = pdf_color_gs_OPM; | |
| 1853 proc->super.op_gs_UseBlackPtComp = pdf_color_gs_UseBlackPtComp; | |
| 1854 | |
| 1855 proc->super.op_END = pdf_color_END; | |
| 1856 | |
| 1857 fz_try(ctx) | |
| 1858 proc->gstate = fz_malloc_struct(ctx, gstate_stack); | |
| 1859 fz_catch(ctx) | |
| 1860 { | |
| 1861 fz_free(ctx, proc); | |
| 1862 fz_rethrow(ctx); | |
| 1863 } | |
| 1864 proc->gstate->ctm = fz_identity; | |
| 1865 | |
| 1866 proc->doc = pdf_keep_document(ctx, doc); | |
| 1867 proc->chain = chain; | |
| 1868 proc->global_options = global_options; | |
| 1869 proc->options = options; | |
| 1870 | |
| 1871 proc->super.requirements = PDF_PROCESSOR_REQUIRES_DECODED_IMAGES | proc->chain->requirements; | |
| 1872 | |
| 1873 return (pdf_processor*)proc; | |
| 1874 } |
