Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/source/fitz/draw-paint.c @ 3:2c135c81b16c
MERGE: upstream PyMuPDF 1.26.4 with MuPDF 1.26.7
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:44:09 +0200 |
| parents | b50eed0cc0ef |
| children |
comparison
equal
deleted
inserted
replaced
| 0:6015a75abc2d | 3:2c135c81b16c |
|---|---|
| 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 | |
| 23 #include "mupdf/fitz.h" | |
| 24 | |
| 25 #include "draw-imp.h" | |
| 26 #include "glyph-imp.h" | |
| 27 #include "pixmap-imp.h" | |
| 28 | |
| 29 #include <string.h> | |
| 30 #include <assert.h> | |
| 31 | |
| 32 /* | |
| 33 | |
| 34 The functions in this file implement various flavours of Porter-Duff blending. | |
| 35 | |
| 36 We take the following as definitions: | |
| 37 | |
| 38 Cx = Color (from plane x) | |
| 39 ax = Alpha (from plane x) | |
| 40 cx = Cx.ax = Premultiplied color (from plane x) | |
| 41 | |
| 42 The general PorterDuff blending equation is: | |
| 43 | |
| 44 Blend Z = X op Y cz = Fx.cx + Fy.cy where Fx and Fy depend on op | |
| 45 | |
| 46 The two operations we use in this file are: '(X in Y) over Z' and | |
| 47 'S over Z'. The definitions of the 'over' and 'in' operations are as | |
| 48 follows: | |
| 49 | |
| 50 For S over Z, Fs = 1, Fz = 1-as | |
| 51 For X in Y, Fx = ay, Fy = 0 | |
| 52 | |
| 53 We have 2 choices; we can either work with premultiplied data, or non | |
| 54 premultiplied data. Our | |
| 55 | |
| 56 First the premultiplied case: | |
| 57 | |
| 58 Let S = (X in Y) | |
| 59 Let R = (X in Y) over Z = S over Z | |
| 60 | |
| 61 cs = cx.Fx + cy.Fy (where Fx = ay, Fy = 0) | |
| 62 = cx.ay | |
| 63 as = ax.Fx + ay.Fy | |
| 64 = ax.ay | |
| 65 | |
| 66 cr = cs.Fs + cz.Fz (where Fs = 1, Fz = 1-as) | |
| 67 = cs + cz.(1-as) | |
| 68 = cx.ay + cz.(1-ax.ay) | |
| 69 ar = as.Fs + az.Fz | |
| 70 = as + az.(1-as) | |
| 71 = ax.ay + az.(1-ax.ay) | |
| 72 | |
| 73 This has various nice properties, like not needing any divisions, and | |
| 74 being symmetric in color and alpha, so this is what we use. Because we | |
| 75 went through the pain of deriving the non premultiplied forms, we list | |
| 76 them here too, though they are not used. | |
| 77 | |
| 78 Non Pre-multiplied case: | |
| 79 | |
| 80 Cs.as = Fx.Cx.ax + Fy.Cy.ay (where Fx = ay, Fy = 0) | |
| 81 = Cx.ay.ax | |
| 82 Cs = (Cx.ay.ax)/(ay.ax) | |
| 83 = Cx | |
| 84 Cr.ar = Fs.Cs.as + Fz.Cz.az (where Fs = 1, Fz = 1-as) | |
| 85 = Cs.as + (1-as).Cz.az | |
| 86 = Cx.ax.ay + Cz.az.(1-ax.ay) | |
| 87 Cr = (Cx.ax.ay + Cz.az.(1-ax.ay))/(ax.ay + az.(1-ax.ay)) | |
| 88 | |
| 89 Much more complex, it seems. However, if we could restrict ourselves to | |
| 90 the case where we were always plotting onto an opaque background (i.e. | |
| 91 az = 1), then: | |
| 92 | |
| 93 Cr = Cx.(ax.ay) + Cz.(1-ax.ay) | |
| 94 = (Cx-Cz)*(1-ax.ay) + Cz (a single MLA operation) | |
| 95 ar = 1 | |
| 96 | |
| 97 Sadly, this is not true in the general case, so we abandon this effort | |
| 98 and stick to using the premultiplied form. | |
| 99 | |
| 100 */ | |
| 101 | |
| 102 typedef unsigned char byte; | |
| 103 | |
| 104 /* These are used by the non-aa scan converter */ | |
| 105 | |
| 106 static fz_forceinline void | |
| 107 template_solid_color_1_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da) | |
| 108 { | |
| 109 int sa = FZ_EXPAND(color[1]); | |
| 110 TRACK_FN(); | |
| 111 if (sa == 0) | |
| 112 return; | |
| 113 if (sa == 256) | |
| 114 { | |
| 115 do | |
| 116 { | |
| 117 dp[0] = color[0]; | |
| 118 dp[1] = 255; | |
| 119 dp += 2; | |
| 120 } | |
| 121 while (--w); | |
| 122 } | |
| 123 else | |
| 124 { | |
| 125 do | |
| 126 { | |
| 127 dp[0] = FZ_BLEND(color[0], dp[0], sa); | |
| 128 dp[1] = FZ_BLEND(255, dp[1], sa); | |
| 129 dp += 2; | |
| 130 } | |
| 131 while (--w); | |
| 132 } | |
| 133 } | |
| 134 | |
| 135 static inline int isbigendian(void) | |
| 136 { | |
| 137 union { int i; char c[sizeof(int)]; } u = {1}; | |
| 138 return u.c[0] != 1; | |
| 139 } | |
| 140 | |
| 141 static fz_forceinline void | |
| 142 template_solid_color_3_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da) | |
| 143 { | |
| 144 unsigned int rgba = *(int *)color; | |
| 145 int sa = FZ_EXPAND(color[3]); | |
| 146 TRACK_FN(); | |
| 147 if (sa == 0) | |
| 148 return; | |
| 149 if (isbigendian()) | |
| 150 rgba |= 0x000000FF; | |
| 151 else | |
| 152 rgba |= 0xFF000000; | |
| 153 if (sa == 256) | |
| 154 { | |
| 155 do | |
| 156 { | |
| 157 *(unsigned int *)dp = rgba; | |
| 158 dp += 4; | |
| 159 } | |
| 160 while (--w); | |
| 161 } | |
| 162 else | |
| 163 { | |
| 164 unsigned int mask = 0xFF00FF00; | |
| 165 unsigned int rb = rgba & (mask>>8); | |
| 166 unsigned int ga = (rgba & mask)>>8; | |
| 167 do | |
| 168 { | |
| 169 unsigned int RGBA = *(unsigned int *)dp; | |
| 170 unsigned int RB = (RGBA<<8) & mask; | |
| 171 unsigned int GA = RGBA & mask; | |
| 172 RB += (rb-(RB>>8))*sa; | |
| 173 GA += (ga-(GA>>8))*sa; | |
| 174 RB &= mask; | |
| 175 GA &= mask; | |
| 176 *(unsigned int *)dp = (RB>>8) | GA; | |
| 177 dp += 4; | |
| 178 } | |
| 179 while (--w); | |
| 180 } | |
| 181 } | |
| 182 | |
| 183 static fz_forceinline void | |
| 184 template_solid_color_4_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da) | |
| 185 { | |
| 186 int sa = FZ_EXPAND(color[4]); | |
| 187 TRACK_FN(); | |
| 188 if (sa == 0) | |
| 189 return; | |
| 190 if (sa == 256) | |
| 191 { | |
| 192 #ifdef ARCH_UNALIGNED_OK | |
| 193 if (w > 4) | |
| 194 { | |
| 195 if (isbigendian()) | |
| 196 { | |
| 197 const uint32_t a = *(uint32_t*)color; | |
| 198 const uint32_t b = 0xFF000000|(a>>8); | |
| 199 const uint32_t c = 0x00FF0000|(a>>16)|(a<<24); | |
| 200 const uint32_t d = 0x0000FF00|(a>>24)|(a<<16); | |
| 201 const uint32_t e = 0x000000FF|(a<<8); | |
| 202 w -= 3; | |
| 203 do | |
| 204 { | |
| 205 ((uint32_t *)(void *)dp)[0] = a; | |
| 206 ((uint32_t *)(void *)dp)[1] = b; | |
| 207 ((uint32_t *)(void *)dp)[2] = c; | |
| 208 ((uint32_t *)(void *)dp)[3] = d; | |
| 209 ((uint32_t *)(void *)dp)[4] = e; | |
| 210 dp += 20; | |
| 211 w -= 4; | |
| 212 } | |
| 213 while (w > 0); | |
| 214 } | |
| 215 else | |
| 216 { | |
| 217 const uint32_t a = *(uint32_t*)color; | |
| 218 const uint32_t b = 0x000000FF|(a<<8); | |
| 219 const uint32_t c = 0x0000FF00|(a<<16)|(a>>24); | |
| 220 const uint32_t d = 0x00FF0000|(a<<24)|(a>>16); | |
| 221 const uint32_t e = 0xFF000000|(a>>8); | |
| 222 w -= 3; | |
| 223 do | |
| 224 { | |
| 225 ((uint32_t *)(void *)dp)[0] = a; | |
| 226 ((uint32_t *)(void *)dp)[1] = b; | |
| 227 ((uint32_t *)(void *)dp)[2] = c; | |
| 228 ((uint32_t *)(void *)dp)[3] = d; | |
| 229 ((uint32_t *)(void *)dp)[4] = e; | |
| 230 dp += 20; | |
| 231 w -= 4; | |
| 232 } | |
| 233 while (w > 0); | |
| 234 } | |
| 235 w += 3; | |
| 236 if (w == 0) | |
| 237 return; | |
| 238 } | |
| 239 #endif | |
| 240 do | |
| 241 { | |
| 242 dp[0] = color[0]; | |
| 243 dp[1] = color[1]; | |
| 244 dp[2] = color[2]; | |
| 245 dp[3] = color[3]; | |
| 246 dp[4] = 255; | |
| 247 dp += 5; | |
| 248 } | |
| 249 while (--w); | |
| 250 } | |
| 251 else | |
| 252 { | |
| 253 do | |
| 254 { | |
| 255 dp[0] = FZ_BLEND(color[0], dp[0], sa); | |
| 256 dp[1] = FZ_BLEND(color[1], dp[1], sa); | |
| 257 dp[2] = FZ_BLEND(color[2], dp[2], sa); | |
| 258 dp[3] = FZ_BLEND(color[3], dp[3], sa); | |
| 259 dp[4] = FZ_BLEND(255, dp[5], sa); | |
| 260 dp += 5; | |
| 261 } | |
| 262 while (--w); | |
| 263 } | |
| 264 } | |
| 265 | |
| 266 static fz_forceinline void | |
| 267 template_solid_color_N_256(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da) | |
| 268 { | |
| 269 int k; | |
| 270 int n1 = n - da; | |
| 271 if (n == 3 && da == 0 && w >= 7) | |
| 272 { | |
| 273 union {uint32_t w[3]; byte b[12];} u; | |
| 274 | |
| 275 u.b[0] = u.b[3] = u.b[6] = u.b[9] = color[0]; | |
| 276 u.b[1] = u.b[4] = u.b[7] = u.b[10] = color[1]; | |
| 277 u.b[2] = u.b[5] = u.b[8] = u.b[11] = color[2]; | |
| 278 | |
| 279 switch (((intptr_t)dp) & 3) | |
| 280 { | |
| 281 case 3: | |
| 282 *dp++ = color[0]; | |
| 283 *(uint32_t *)dp = u.w[1]; | |
| 284 dp += 4; | |
| 285 *(uint32_t *)dp = u.w[2]; | |
| 286 dp += 4; | |
| 287 w -= 3; | |
| 288 break; | |
| 289 case 2: | |
| 290 *dp++ = color[0]; | |
| 291 *dp++ = color[1]; | |
| 292 *(uint32_t *)dp = u.w[2]; | |
| 293 dp += 4; | |
| 294 w -= 2; | |
| 295 break; | |
| 296 case 1: | |
| 297 *dp++ = color[0]; | |
| 298 *dp++ = color[1]; | |
| 299 *dp++ = color[2]; | |
| 300 w -= 1; | |
| 301 break; | |
| 302 } | |
| 303 w -= 4; | |
| 304 do | |
| 305 { | |
| 306 *(uint32_t *)dp = u.w[0]; | |
| 307 dp += 4; | |
| 308 *(uint32_t *)dp = u.w[1]; | |
| 309 dp += 4; | |
| 310 *(uint32_t *)dp = u.w[2]; | |
| 311 dp += 4; | |
| 312 w -= 4; | |
| 313 } | |
| 314 while (w > 0); | |
| 315 w += 4; | |
| 316 if (w == 0) | |
| 317 return; | |
| 318 } | |
| 319 do | |
| 320 { | |
| 321 dp[0] = color[0]; | |
| 322 if (n1 > 1) | |
| 323 dp[1] = color[1]; | |
| 324 if (n1 > 2) | |
| 325 dp[2] = color[2]; | |
| 326 for (k = 3; k < n1; k++) | |
| 327 dp[k] = color[k]; | |
| 328 if (da) | |
| 329 dp[n1] = 255; | |
| 330 dp += n; | |
| 331 } | |
| 332 while (--w); | |
| 333 } | |
| 334 | |
| 335 static fz_forceinline void | |
| 336 template_solid_color_N_256_op(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 337 { | |
| 338 int k; | |
| 339 int n1 = n - da; | |
| 340 do | |
| 341 { | |
| 342 if (fz_overprint_component(eop, 0)) | |
| 343 dp[0] = color[0]; | |
| 344 if (n1 > 1) | |
| 345 if (fz_overprint_component(eop, 1)) | |
| 346 dp[1] = color[1]; | |
| 347 if (n1 > 2) | |
| 348 if (fz_overprint_component(eop, 2)) | |
| 349 dp[2] = color[2]; | |
| 350 for (k = 3; k < n1; k++) | |
| 351 if (fz_overprint_component(eop, k)) | |
| 352 dp[k] = color[k]; | |
| 353 if (da) | |
| 354 dp[n1] = 255; | |
| 355 dp += n; | |
| 356 } | |
| 357 while (--w); | |
| 358 } | |
| 359 | |
| 360 static fz_forceinline void | |
| 361 template_solid_color_N_sa(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, int sa) | |
| 362 { | |
| 363 int k; | |
| 364 int n1 = n - da; | |
| 365 do | |
| 366 { | |
| 367 for (k = 0; k < n1; k++) | |
| 368 dp[k] = FZ_BLEND(color[k], dp[k], sa); | |
| 369 if (da) | |
| 370 dp[k] = FZ_BLEND(255, dp[k], sa); | |
| 371 dp += n; | |
| 372 } | |
| 373 while (--w); | |
| 374 } | |
| 375 | |
| 376 static fz_forceinline void | |
| 377 template_solid_color_N_sa_op(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, int sa, const fz_overprint * FZ_RESTRICT eop) | |
| 378 { | |
| 379 int k; | |
| 380 int n1 = n - da; | |
| 381 do | |
| 382 { | |
| 383 for (k = 0; k < n1; k++) | |
| 384 if (fz_overprint_component(eop, k)) | |
| 385 dp[k] = FZ_BLEND(color[k], dp[k], sa); | |
| 386 if (da) | |
| 387 dp[k] = FZ_BLEND(255, dp[k], sa); | |
| 388 dp += n; | |
| 389 } | |
| 390 while (--w); | |
| 391 } | |
| 392 | |
| 393 #if FZ_PLOTTERS_N | |
| 394 static fz_forceinline void | |
| 395 template_solid_color_N_general(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, int sa) | |
| 396 { | |
| 397 int k; | |
| 398 int n1 = n - da; | |
| 399 if (sa == 256) | |
| 400 { | |
| 401 do | |
| 402 { | |
| 403 dp[0] = color[0]; | |
| 404 if (n1 > 1) | |
| 405 dp[1] = color[1]; | |
| 406 if (n1 > 2) | |
| 407 dp[2] = color[2]; | |
| 408 for (k = 3; k < n1; k++) | |
| 409 dp[k] = color[k]; | |
| 410 if (da) | |
| 411 dp[n1] = 255; | |
| 412 dp += n; | |
| 413 } | |
| 414 while (--w); | |
| 415 } | |
| 416 else | |
| 417 { | |
| 418 do | |
| 419 { | |
| 420 for (k = 0; k < n1; k++) | |
| 421 dp[k] = FZ_BLEND(color[k], dp[k], sa); | |
| 422 if (da) | |
| 423 dp[k] = FZ_BLEND(255, dp[k], sa); | |
| 424 dp += n; | |
| 425 } | |
| 426 while (--w); | |
| 427 } | |
| 428 } | |
| 429 | |
| 430 static fz_forceinline void | |
| 431 template_solid_color_N_general_op(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, int sa, const fz_overprint * FZ_RESTRICT eop) | |
| 432 { | |
| 433 int k; | |
| 434 int n1 = n - da; | |
| 435 if (sa == 256) | |
| 436 { | |
| 437 do | |
| 438 { | |
| 439 if (fz_overprint_component(eop, 0)) | |
| 440 dp[0] = color[0]; | |
| 441 if (n1 > 1) | |
| 442 if (fz_overprint_component(eop, 1)) | |
| 443 dp[1] = color[1]; | |
| 444 if (n1 > 2) | |
| 445 if (fz_overprint_component(eop, 2)) | |
| 446 dp[2] = color[2]; | |
| 447 for (k = 3; k < n1; k++) | |
| 448 if (fz_overprint_component(eop, k)) | |
| 449 dp[k] = color[k]; | |
| 450 if (da) | |
| 451 dp[n1] = 255; | |
| 452 dp += n; | |
| 453 } | |
| 454 while (--w); | |
| 455 } | |
| 456 else | |
| 457 { | |
| 458 do | |
| 459 { | |
| 460 for (k = 0; k < n1; k++) | |
| 461 if (fz_overprint_component(eop, k)) | |
| 462 dp[k] = FZ_BLEND(color[k], dp[k], sa); | |
| 463 if (da) | |
| 464 dp[k] = FZ_BLEND(255, dp[k], sa); | |
| 465 dp += n; | |
| 466 } | |
| 467 while (--w); | |
| 468 } | |
| 469 } | |
| 470 #endif | |
| 471 | |
| 472 static fz_forceinline void | |
| 473 template_solid_color_0_da(byte * FZ_RESTRICT dp, int w, int sa) | |
| 474 { | |
| 475 if (sa == 256) | |
| 476 { | |
| 477 memset(dp, 255, w); | |
| 478 } | |
| 479 else | |
| 480 { | |
| 481 do | |
| 482 { | |
| 483 *dp = FZ_BLEND(255, *dp, sa); | |
| 484 dp++; | |
| 485 } | |
| 486 while (--w); | |
| 487 } | |
| 488 } | |
| 489 | |
| 490 #if FZ_PLOTTERS_G | |
| 491 static void paint_solid_color_1_alpha(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 492 { | |
| 493 TRACK_FN(); | |
| 494 template_solid_color_N_sa(dp, 1, w, color, 0, FZ_EXPAND(color[1])); | |
| 495 } | |
| 496 | |
| 497 static void paint_solid_color_1(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 498 { | |
| 499 TRACK_FN(); | |
| 500 template_solid_color_N_256(dp, 1, w, color, 0); | |
| 501 } | |
| 502 | |
| 503 static void paint_solid_color_1_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 504 { | |
| 505 TRACK_FN(); | |
| 506 template_solid_color_1_da(dp, 2, w, color, 1); | |
| 507 } | |
| 508 #endif /* FZ_PLOTTERS_G */ | |
| 509 | |
| 510 static void paint_solid_color_0_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 511 { | |
| 512 TRACK_FN(); | |
| 513 template_solid_color_0_da(dp, w, 256); | |
| 514 } | |
| 515 | |
| 516 #if FZ_PLOTTERS_RGB | |
| 517 static void paint_solid_color_3_alpha(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 518 { | |
| 519 TRACK_FN(); | |
| 520 template_solid_color_N_sa(dp, 3, w, color, 0, FZ_EXPAND(color[3])); | |
| 521 } | |
| 522 | |
| 523 static void paint_solid_color_3(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 524 { | |
| 525 TRACK_FN(); | |
| 526 template_solid_color_N_256(dp, 3, w, color, 0); | |
| 527 } | |
| 528 | |
| 529 static void paint_solid_color_3_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 530 { | |
| 531 TRACK_FN(); | |
| 532 template_solid_color_3_da(dp, 4, w, color, 1); | |
| 533 } | |
| 534 #endif /* FZ_PLOTTERS_RGB */ | |
| 535 | |
| 536 #if FZ_PLOTTERS_CMYK | |
| 537 static void paint_solid_color_4_alpha(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 538 { | |
| 539 TRACK_FN(); | |
| 540 template_solid_color_N_sa(dp, 4, w, color, 0, FZ_EXPAND(color[4])); | |
| 541 } | |
| 542 | |
| 543 static void paint_solid_color_4(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 544 { | |
| 545 TRACK_FN(); | |
| 546 template_solid_color_N_256(dp, 4, w, color, 0); | |
| 547 } | |
| 548 | |
| 549 static void paint_solid_color_4_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 550 { | |
| 551 TRACK_FN(); | |
| 552 template_solid_color_4_da(dp, 5, w, color, 1); | |
| 553 } | |
| 554 #endif /* FZ_PLOTTERS_CMYK */ | |
| 555 | |
| 556 #if FZ_PLOTTERS_N | |
| 557 static void paint_solid_color_N_alpha(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 558 { | |
| 559 TRACK_FN(); | |
| 560 template_solid_color_N_sa(dp, n, w, color, 0, FZ_EXPAND(color[n])); | |
| 561 } | |
| 562 | |
| 563 static void paint_solid_color_N(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 564 { | |
| 565 TRACK_FN(); | |
| 566 template_solid_color_N_256(dp, n, w, color, 0); | |
| 567 } | |
| 568 | |
| 569 static void paint_solid_color_N_da(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 570 { | |
| 571 TRACK_FN(); | |
| 572 template_solid_color_N_general(dp, n, w, color, 1, FZ_EXPAND(color[n-1])); | |
| 573 } | |
| 574 #endif /* FZ_PLOTTERS_N */ | |
| 575 | |
| 576 #if FZ_ENABLE_SPOT_RENDERING | |
| 577 static void paint_solid_color_N_alpha_op(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 578 { | |
| 579 TRACK_FN(); | |
| 580 template_solid_color_N_sa_op(dp, n, w, color, 0, FZ_EXPAND(color[n]), eop); | |
| 581 } | |
| 582 | |
| 583 static void paint_solid_color_N_op(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 584 { | |
| 585 TRACK_FN(); | |
| 586 template_solid_color_N_256_op(dp, n, w, color, 0, eop); | |
| 587 } | |
| 588 | |
| 589 static void paint_solid_color_N_da_op(byte * FZ_RESTRICT dp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 590 { | |
| 591 TRACK_FN(); | |
| 592 template_solid_color_N_general_op(dp, n, w, color, 1, FZ_EXPAND(color[n-1]), eop); | |
| 593 } | |
| 594 #endif /* FZ_ENABLE_SPOT_RENDERING */ | |
| 595 | |
| 596 fz_solid_color_painter_t * | |
| 597 fz_get_solid_color_painter(int n, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 598 { | |
| 599 #if FZ_ENABLE_SPOT_RENDERING | |
| 600 if (fz_overprint_required(eop)) | |
| 601 { | |
| 602 if (da) | |
| 603 return paint_solid_color_N_da_op; | |
| 604 else if (color[n] == 255) | |
| 605 return paint_solid_color_N_op; | |
| 606 else | |
| 607 return paint_solid_color_N_alpha_op; | |
| 608 } | |
| 609 #endif /* FZ_ENABLE_SPOT_RENDERING */ | |
| 610 switch (n-da) | |
| 611 { | |
| 612 case 0: | |
| 613 return paint_solid_color_0_da; | |
| 614 #if FZ_PLOTTERS_G | |
| 615 case 1: | |
| 616 if (da) | |
| 617 return paint_solid_color_1_da; | |
| 618 else if (color[1] == 255) | |
| 619 return paint_solid_color_1; | |
| 620 else | |
| 621 return paint_solid_color_1_alpha; | |
| 622 #endif /* FZ_PLOTTERS_G */ | |
| 623 #if FZ_PLOTTERS_RGB | |
| 624 case 3: | |
| 625 if (da) | |
| 626 return paint_solid_color_3_da; | |
| 627 else if (color[3] == 255) | |
| 628 return paint_solid_color_3; | |
| 629 else | |
| 630 return paint_solid_color_3_alpha; | |
| 631 #endif /* FZ_PLOTTERS_RGB */ | |
| 632 #if FZ_PLOTTERS_CMYK | |
| 633 case 4: | |
| 634 if (da) | |
| 635 return paint_solid_color_4_da; | |
| 636 else if (color[4] == 255) | |
| 637 return paint_solid_color_4; | |
| 638 else | |
| 639 return paint_solid_color_4_alpha; | |
| 640 #endif /* FZ_PLOTTERS_CMYK */ | |
| 641 default: | |
| 642 #if FZ_PLOTTERS_N | |
| 643 if (da) | |
| 644 return paint_solid_color_N_da; | |
| 645 else if (color[n] == 255) | |
| 646 return paint_solid_color_N; | |
| 647 else | |
| 648 return paint_solid_color_N_alpha; | |
| 649 #else | |
| 650 return NULL; | |
| 651 #endif /* FZ_PLOTTERS_N */ | |
| 652 } | |
| 653 } | |
| 654 | |
| 655 /* Blend a non-premultiplied color in mask over destination */ | |
| 656 | |
| 657 static fz_forceinline void | |
| 658 template_span_with_color_1_da_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da) | |
| 659 { | |
| 660 int g = color[0]; | |
| 661 do | |
| 662 { | |
| 663 int ma = *mp++; | |
| 664 ma = FZ_EXPAND(ma); | |
| 665 if (ma == 256) | |
| 666 { | |
| 667 dp[0] = g; | |
| 668 dp[1] = 255; | |
| 669 } | |
| 670 else if (ma != 0) | |
| 671 { | |
| 672 dp[0] = FZ_BLEND(g, dp[0], ma); | |
| 673 dp[1] = FZ_BLEND(255, dp[1], ma); | |
| 674 } | |
| 675 dp += 2; | |
| 676 } | |
| 677 while (--w); | |
| 678 } | |
| 679 | |
| 680 static fz_forceinline void | |
| 681 template_span_with_color_1_da_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da) | |
| 682 { | |
| 683 int sa = FZ_EXPAND(color[1]); | |
| 684 int g = color[0]; | |
| 685 do | |
| 686 { | |
| 687 int ma = *mp++; | |
| 688 ma = FZ_EXPAND(ma); | |
| 689 if (ma != 0) | |
| 690 { | |
| 691 ma = FZ_COMBINE(ma, sa); | |
| 692 dp[0] = FZ_BLEND(g, dp[0], ma); | |
| 693 dp[1] = FZ_BLEND(255, dp[1], ma); | |
| 694 } | |
| 695 dp += 2; | |
| 696 } | |
| 697 while (--w); | |
| 698 } | |
| 699 | |
| 700 static fz_forceinline void | |
| 701 template_span_with_color_3_da_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da) | |
| 702 { | |
| 703 unsigned int rgba = *((const unsigned int *)color); | |
| 704 unsigned int mask, rb, ga; | |
| 705 if (isbigendian()) | |
| 706 rgba |= 0x000000FF; | |
| 707 else | |
| 708 rgba |= 0xFF000000; | |
| 709 mask = 0xFF00FF00; | |
| 710 rb = rgba & (mask>>8); | |
| 711 ga = (rgba & mask)>>8; | |
| 712 do | |
| 713 { | |
| 714 unsigned int ma = *mp++; | |
| 715 dp += 4; | |
| 716 ma = FZ_EXPAND(ma); | |
| 717 if (ma == 256) | |
| 718 { | |
| 719 ((unsigned int *)dp)[-1] = rgba; | |
| 720 } | |
| 721 else if (ma != 0) | |
| 722 { | |
| 723 unsigned int RGBA = ((unsigned int *)dp)[-1]; | |
| 724 unsigned int RB = (RGBA<<8) & mask; | |
| 725 unsigned int GA = RGBA & mask; | |
| 726 RB += (rb-(RB>>8))*ma; | |
| 727 GA += (ga-(GA>>8))*ma; | |
| 728 RB &= mask; | |
| 729 GA &= mask; | |
| 730 ((unsigned int *)dp)[-1] = (RB>>8) | GA; | |
| 731 } | |
| 732 } | |
| 733 while (--w); | |
| 734 } | |
| 735 | |
| 736 static fz_forceinline void | |
| 737 template_span_with_color_3_da_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da) | |
| 738 { | |
| 739 unsigned int rgba = *((const unsigned int *)color); | |
| 740 unsigned int mask, rb, ga; | |
| 741 int sa = FZ_EXPAND(color[3]); | |
| 742 if (isbigendian()) | |
| 743 rgba |= 0x000000FF; | |
| 744 else | |
| 745 rgba |= 0xFF000000; | |
| 746 mask = 0xFF00FF00; | |
| 747 rb = rgba & (mask>>8); | |
| 748 ga = (rgba & mask)>>8; | |
| 749 do | |
| 750 { | |
| 751 unsigned int ma = *mp++; | |
| 752 ma = FZ_COMBINE(FZ_EXPAND(ma), sa); | |
| 753 dp += 4; | |
| 754 if (ma != 0) | |
| 755 { | |
| 756 unsigned int RGBA = ((unsigned int*)dp)[-1]; | |
| 757 unsigned int RB = (RGBA<<8) & mask; | |
| 758 unsigned int GA = RGBA & mask; | |
| 759 RB += (rb-(RB>>8))*ma; | |
| 760 GA += (ga-(GA>>8))*ma; | |
| 761 RB &= mask; | |
| 762 GA &= mask; | |
| 763 ((unsigned int *)dp)[-1] = (RB>>8) | GA; | |
| 764 } | |
| 765 } | |
| 766 while (--w); | |
| 767 } | |
| 768 | |
| 769 static fz_forceinline void | |
| 770 template_span_with_color_4_da_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da) | |
| 771 { | |
| 772 int c = color[0]; | |
| 773 int m = color[1]; | |
| 774 int y = color[2]; | |
| 775 int k = color[3]; | |
| 776 TRACK_FN(); | |
| 777 do | |
| 778 { | |
| 779 int ma = *mp++; | |
| 780 ma = FZ_EXPAND(ma); | |
| 781 if (ma == 256) | |
| 782 { | |
| 783 dp[0] = c; | |
| 784 dp[1] = m; | |
| 785 dp[2] = y; | |
| 786 dp[3] = k; | |
| 787 dp[4] = 255; | |
| 788 } | |
| 789 else if (ma != 0) | |
| 790 { | |
| 791 dp[0] = FZ_BLEND(c, dp[0], ma); | |
| 792 dp[1] = FZ_BLEND(m, dp[1], ma); | |
| 793 dp[2] = FZ_BLEND(y, dp[2], ma); | |
| 794 dp[3] = FZ_BLEND(k, dp[3], ma); | |
| 795 dp[4] = FZ_BLEND(255, dp[4], ma); | |
| 796 } | |
| 797 dp += 5; | |
| 798 } | |
| 799 while (--w); | |
| 800 } | |
| 801 | |
| 802 static fz_forceinline void | |
| 803 template_span_with_color_4_da_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da) | |
| 804 { | |
| 805 int sa = FZ_EXPAND(color[4]); | |
| 806 int c = color[0]; | |
| 807 int m = color[1]; | |
| 808 int y = color[2]; | |
| 809 int k = color[3]; | |
| 810 TRACK_FN(); | |
| 811 do | |
| 812 { | |
| 813 int ma = *mp++; | |
| 814 ma = FZ_EXPAND(ma); | |
| 815 if (ma != 0) | |
| 816 { | |
| 817 ma = FZ_COMBINE(ma, sa); | |
| 818 dp[0] = FZ_BLEND(c, dp[0], ma); | |
| 819 dp[1] = FZ_BLEND(m, dp[1], ma); | |
| 820 dp[2] = FZ_BLEND(y, dp[2], ma); | |
| 821 dp[3] = FZ_BLEND(k, dp[3], ma); | |
| 822 dp[4] = FZ_BLEND(255, dp[4], ma); | |
| 823 } | |
| 824 dp += 5; | |
| 825 } | |
| 826 while (--w); | |
| 827 } | |
| 828 | |
| 829 static fz_forceinline void | |
| 830 template_span_with_color_N_general_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da) | |
| 831 { | |
| 832 int k; | |
| 833 int n1 = n - da; | |
| 834 do | |
| 835 { | |
| 836 int ma = *mp++; | |
| 837 ma = FZ_EXPAND(ma); | |
| 838 if (ma == 256) | |
| 839 { | |
| 840 if (n1 > 0) | |
| 841 dp[0] = color[0]; | |
| 842 if (n1 > 1) | |
| 843 dp[1] = color[1]; | |
| 844 if (n1 > 2) | |
| 845 dp[2] = color[2]; | |
| 846 for (k = 3; k < n1; k++) | |
| 847 dp[k] = color[k]; | |
| 848 if (da) | |
| 849 dp[n1] = 255; | |
| 850 } | |
| 851 else if (ma != 0) | |
| 852 { | |
| 853 if (n1 > 0) | |
| 854 dp[0] = FZ_BLEND(color[0], dp[0], ma); | |
| 855 if (n1 > 1) | |
| 856 dp[1] = FZ_BLEND(color[1], dp[1], ma); | |
| 857 if (n1 > 2) | |
| 858 dp[2] = FZ_BLEND(color[2], dp[2], ma); | |
| 859 for (k = 3; k < n1; k++) | |
| 860 dp[k] = FZ_BLEND(color[k], dp[k], ma); | |
| 861 if (da) | |
| 862 dp[n1] = FZ_BLEND(255, dp[n1], ma); | |
| 863 } | |
| 864 dp += n; | |
| 865 } | |
| 866 while (--w); | |
| 867 } | |
| 868 | |
| 869 static fz_forceinline void | |
| 870 template_span_with_color_N_general_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da) | |
| 871 { | |
| 872 int k; | |
| 873 int n1 = n - da; | |
| 874 int sa = FZ_EXPAND(color[n1]); | |
| 875 do | |
| 876 { | |
| 877 int ma = *mp++; | |
| 878 ma = FZ_COMBINE(FZ_EXPAND(ma), sa); | |
| 879 if (n1 > 0) | |
| 880 dp[0] = FZ_BLEND(color[0], dp[0], ma); | |
| 881 if (n1 > 1) | |
| 882 dp[1] = FZ_BLEND(color[1], dp[1], ma); | |
| 883 if (n1 > 2) | |
| 884 dp[2] = FZ_BLEND(color[2], dp[2], ma); | |
| 885 for (k = 3; k < n1; k++) | |
| 886 dp[k] = FZ_BLEND(color[k], dp[k], ma); | |
| 887 if (da) | |
| 888 dp[n1] = FZ_BLEND(255, dp[n1], ma); | |
| 889 dp += n; | |
| 890 } | |
| 891 while (--w); | |
| 892 } | |
| 893 | |
| 894 static fz_forceinline void | |
| 895 template_span_with_color_N_general_op_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 896 { | |
| 897 int k; | |
| 898 int n1 = n - da; | |
| 899 do | |
| 900 { | |
| 901 int ma = *mp++; | |
| 902 ma = FZ_EXPAND(ma); | |
| 903 if (ma == 256) | |
| 904 { | |
| 905 if (n1 > 0) | |
| 906 if (fz_overprint_component(eop, 0)) | |
| 907 dp[0] = color[0]; | |
| 908 if (n1 > 1) | |
| 909 if (fz_overprint_component(eop, 1)) | |
| 910 dp[1] = color[1]; | |
| 911 if (n1 > 2) | |
| 912 if (fz_overprint_component(eop, 2)) | |
| 913 dp[2] = color[2]; | |
| 914 for (k = 3; k < n1; k++) | |
| 915 if (fz_overprint_component(eop, k)) | |
| 916 dp[k] = color[k]; | |
| 917 if (da) | |
| 918 dp[n1] = 255; | |
| 919 } | |
| 920 else if (ma != 0) | |
| 921 { | |
| 922 for (k = 0; k < n1; k++) | |
| 923 if (fz_overprint_component(eop, k)) | |
| 924 dp[k] = FZ_BLEND(color[k], dp[k], ma); | |
| 925 if (da) | |
| 926 dp[n1] = FZ_BLEND(255, dp[k], ma); | |
| 927 } | |
| 928 dp += n; | |
| 929 } | |
| 930 while (--w); | |
| 931 } | |
| 932 | |
| 933 static fz_forceinline void | |
| 934 template_span_with_color_N_general_op_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 935 { | |
| 936 int k; | |
| 937 int n1 = n - da; | |
| 938 int sa = FZ_EXPAND(color[n1]); | |
| 939 do | |
| 940 { | |
| 941 int ma = *mp++; | |
| 942 ma = FZ_COMBINE(FZ_EXPAND(ma), sa); | |
| 943 for (k = 0; k < n1; k++) | |
| 944 if (fz_overprint_component(eop, k)) | |
| 945 dp[k] = FZ_BLEND(color[k], dp[k], ma); | |
| 946 if (da) | |
| 947 dp[k] = FZ_BLEND(255, dp[k], ma); | |
| 948 dp += n; | |
| 949 } | |
| 950 while (--w); | |
| 951 } | |
| 952 | |
| 953 static void | |
| 954 paint_span_with_color_0_da_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 955 { | |
| 956 TRACK_FN(); | |
| 957 template_span_with_color_N_general_solid(dp, mp, 1, w, color, 1); | |
| 958 } | |
| 959 | |
| 960 static void | |
| 961 paint_span_with_color_0_da_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 962 { | |
| 963 TRACK_FN(); | |
| 964 template_span_with_color_N_general_alpha(dp, mp, 1, w, color, 1); | |
| 965 } | |
| 966 | |
| 967 static void | |
| 968 paint_span_with_color_1_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 969 { | |
| 970 TRACK_FN(); | |
| 971 template_span_with_color_N_general_solid(dp, mp, 1, w, color, 0); | |
| 972 } | |
| 973 | |
| 974 static void | |
| 975 paint_span_with_color_1_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 976 { | |
| 977 TRACK_FN(); | |
| 978 template_span_with_color_N_general_alpha(dp, mp, 1, w, color, 0); | |
| 979 } | |
| 980 | |
| 981 static void | |
| 982 paint_span_with_color_1_da_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 983 { | |
| 984 TRACK_FN(); | |
| 985 template_span_with_color_1_da_solid(dp, mp, 2, w, color, 1); | |
| 986 } | |
| 987 | |
| 988 static void | |
| 989 paint_span_with_color_1_da_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 990 { | |
| 991 TRACK_FN(); | |
| 992 template_span_with_color_1_da_alpha(dp, mp, 2, w, color, 1); | |
| 993 } | |
| 994 | |
| 995 #if FZ_PLOTTERS_RGB | |
| 996 static void | |
| 997 paint_span_with_color_3_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 998 { | |
| 999 TRACK_FN(); | |
| 1000 template_span_with_color_N_general_solid(dp, mp, 3, w, color, 0); | |
| 1001 } | |
| 1002 | |
| 1003 static void | |
| 1004 paint_span_with_color_3_da_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 1005 { | |
| 1006 TRACK_FN(); | |
| 1007 template_span_with_color_3_da_solid(dp, mp, 4, w, color, 1); | |
| 1008 } | |
| 1009 | |
| 1010 static void | |
| 1011 paint_span_with_color_3_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 1012 { | |
| 1013 TRACK_FN(); | |
| 1014 template_span_with_color_N_general_alpha(dp, mp, 3, w, color, 0); | |
| 1015 } | |
| 1016 | |
| 1017 static void | |
| 1018 paint_span_with_color_3_da_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 1019 { | |
| 1020 TRACK_FN(); | |
| 1021 template_span_with_color_3_da_alpha(dp, mp, 4, w, color, 1); | |
| 1022 } | |
| 1023 #endif /* FZ_PLOTTERS_RGB */ | |
| 1024 | |
| 1025 #if FZ_PLOTTERS_CMYK | |
| 1026 static void | |
| 1027 paint_span_with_color_4_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 1028 { | |
| 1029 TRACK_FN(); | |
| 1030 template_span_with_color_N_general_solid(dp, mp, 4, w, color, 0); | |
| 1031 } | |
| 1032 | |
| 1033 static void | |
| 1034 paint_span_with_color_4_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 1035 { | |
| 1036 TRACK_FN(); | |
| 1037 template_span_with_color_N_general_alpha(dp, mp, 4, w, color, 0); | |
| 1038 } | |
| 1039 | |
| 1040 static void | |
| 1041 paint_span_with_color_4_da_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 1042 { | |
| 1043 TRACK_FN(); | |
| 1044 template_span_with_color_4_da_solid(dp, mp, 5, w, color, 1); | |
| 1045 } | |
| 1046 | |
| 1047 static void | |
| 1048 paint_span_with_color_4_da_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 1049 { | |
| 1050 TRACK_FN(); | |
| 1051 template_span_with_color_4_da_alpha(dp, mp, 5, w, color, 1); | |
| 1052 } | |
| 1053 #endif /* FZ_PLOTTERS_CMYK */ | |
| 1054 | |
| 1055 #if FZ_PLOTTERS_N | |
| 1056 static void | |
| 1057 paint_span_with_color_N_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 1058 { | |
| 1059 TRACK_FN(); | |
| 1060 template_span_with_color_N_general_solid(dp, mp, n, w, color, 0); | |
| 1061 } | |
| 1062 | |
| 1063 static void | |
| 1064 paint_span_with_color_N_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 1065 { | |
| 1066 TRACK_FN(); | |
| 1067 template_span_with_color_N_general_alpha(dp, mp, n, w, color, 0); | |
| 1068 } | |
| 1069 | |
| 1070 static void | |
| 1071 paint_span_with_color_N_da_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 1072 { | |
| 1073 TRACK_FN(); | |
| 1074 template_span_with_color_N_general_solid(dp, mp, n, w, color, 1); | |
| 1075 } | |
| 1076 | |
| 1077 static void | |
| 1078 paint_span_with_color_N_da_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 1079 { | |
| 1080 TRACK_FN(); | |
| 1081 template_span_with_color_N_general_alpha(dp, mp, n, w, color, 1); | |
| 1082 } | |
| 1083 #endif /* FZ_PLOTTERS_N */ | |
| 1084 | |
| 1085 #if FZ_ENABLE_SPOT_RENDERING | |
| 1086 static void | |
| 1087 paint_span_with_color_N_op_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 1088 { | |
| 1089 TRACK_FN(); | |
| 1090 template_span_with_color_N_general_op_solid(dp, mp, n, w, color, 0, eop); | |
| 1091 } | |
| 1092 | |
| 1093 static void | |
| 1094 paint_span_with_color_N_op_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 1095 { | |
| 1096 TRACK_FN(); | |
| 1097 template_span_with_color_N_general_op_alpha(dp, mp, n, w, color, 0, eop); | |
| 1098 } | |
| 1099 | |
| 1100 static void | |
| 1101 paint_span_with_color_N_da_op_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 1102 { | |
| 1103 TRACK_FN(); | |
| 1104 template_span_with_color_N_general_op_solid(dp, mp, n, w, color, 1, eop); | |
| 1105 } | |
| 1106 | |
| 1107 static void | |
| 1108 paint_span_with_color_N_da_op_alpha(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT mp, int n, int w, const byte * FZ_RESTRICT color, int da, const fz_overprint * FZ_RESTRICT eop) | |
| 1109 { | |
| 1110 TRACK_FN(); | |
| 1111 template_span_with_color_N_general_op_alpha(dp, mp, n, w, color, 1, eop); | |
| 1112 } | |
| 1113 #endif /* FZ_ENABLE_SPOT_RENDERING */ | |
| 1114 | |
| 1115 fz_span_color_painter_t * | |
| 1116 fz_get_span_color_painter(int n, int da, const byte * FZ_RESTRICT color, const fz_overprint * FZ_RESTRICT eop) | |
| 1117 { | |
| 1118 byte alpha = color[n-da]; | |
| 1119 if (alpha == 0) | |
| 1120 return NULL; | |
| 1121 #if FZ_ENABLE_SPOT_RENDERING | |
| 1122 if (fz_overprint_required(eop)) | |
| 1123 { | |
| 1124 if (alpha == 255) | |
| 1125 return da ? paint_span_with_color_N_da_op_solid : paint_span_with_color_N_op_solid; | |
| 1126 else | |
| 1127 return da ? paint_span_with_color_N_da_op_alpha : paint_span_with_color_N_op_alpha; | |
| 1128 } | |
| 1129 #endif /* FZ_ENABLE_SPOT_RENDERING */ | |
| 1130 switch(n-da) | |
| 1131 { | |
| 1132 case 0: | |
| 1133 if (alpha == 255) | |
| 1134 return da ? paint_span_with_color_0_da_solid : NULL; | |
| 1135 else | |
| 1136 return da ? paint_span_with_color_0_da_alpha : NULL; | |
| 1137 case 1: | |
| 1138 if (alpha == 255) | |
| 1139 return da ? paint_span_with_color_1_da_solid : paint_span_with_color_1_solid; | |
| 1140 else | |
| 1141 return da ? paint_span_with_color_1_da_alpha : paint_span_with_color_1_alpha; | |
| 1142 #if FZ_PLOTTERS_RGB | |
| 1143 case 3: | |
| 1144 if (alpha == 255) | |
| 1145 return da ? paint_span_with_color_3_da_solid : paint_span_with_color_3_solid; | |
| 1146 else | |
| 1147 return da ? paint_span_with_color_3_da_alpha : paint_span_with_color_3_alpha; | |
| 1148 #endif/* FZ_PLOTTERS_RGB */ | |
| 1149 #if FZ_PLOTTERS_CMYK | |
| 1150 case 4: | |
| 1151 if (alpha == 255) | |
| 1152 return da ? paint_span_with_color_4_da_solid : paint_span_with_color_4_solid; | |
| 1153 else | |
| 1154 return da ? paint_span_with_color_4_da_alpha : paint_span_with_color_4_alpha; | |
| 1155 #endif/* FZ_PLOTTERS_CMYK */ | |
| 1156 #if FZ_PLOTTERS_N | |
| 1157 default: | |
| 1158 if (alpha == 255) | |
| 1159 return da ? paint_span_with_color_N_da_solid : paint_span_with_color_N_solid; | |
| 1160 else | |
| 1161 return da ? paint_span_with_color_N_da_alpha : paint_span_with_color_N_alpha; | |
| 1162 #else | |
| 1163 default: return NULL; | |
| 1164 #endif /* FZ_PLOTTERS_N */ | |
| 1165 } | |
| 1166 } | |
| 1167 | |
| 1168 /* Blend source in mask over destination */ | |
| 1169 | |
| 1170 /* FIXME: There is potential for SWAR optimisation here */ | |
| 1171 static fz_forceinline void | |
| 1172 template_span_with_mask_1_general(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, int a, const byte * FZ_RESTRICT mp, int w) | |
| 1173 { | |
| 1174 do | |
| 1175 { | |
| 1176 int ma = *mp++; | |
| 1177 ma = FZ_EXPAND(ma); | |
| 1178 if (ma == 0 || (a && sp[1] == 0)) | |
| 1179 { | |
| 1180 dp += 1 + a; | |
| 1181 sp += 1 + a; | |
| 1182 } | |
| 1183 else if (ma == 256) | |
| 1184 { | |
| 1185 *dp++ = *sp++; | |
| 1186 if (a) | |
| 1187 *dp++ = *sp++; | |
| 1188 } | |
| 1189 else | |
| 1190 { | |
| 1191 *dp = FZ_BLEND(*sp, *dp, ma); | |
| 1192 sp++; dp++; | |
| 1193 if (a) | |
| 1194 { | |
| 1195 *dp = FZ_BLEND(*sp, *dp, ma); | |
| 1196 sp++; dp++; | |
| 1197 } | |
| 1198 } | |
| 1199 } | |
| 1200 while (--w); | |
| 1201 } | |
| 1202 | |
| 1203 static fz_forceinline void | |
| 1204 template_span_with_mask_3_general(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, int a, const byte * FZ_RESTRICT mp, int w) | |
| 1205 { | |
| 1206 do | |
| 1207 { | |
| 1208 int ma = *mp++; | |
| 1209 ma = FZ_EXPAND(ma); | |
| 1210 if (ma == 0 || (a && sp[3] == 0)) | |
| 1211 { | |
| 1212 dp += 3 + a; | |
| 1213 sp += 3 + a; | |
| 1214 } | |
| 1215 else if (ma == 256) | |
| 1216 { | |
| 1217 if (a) | |
| 1218 { | |
| 1219 *(int32_t *)dp = *(int32_t *)sp; | |
| 1220 sp += 4; dp += 4; | |
| 1221 } | |
| 1222 else | |
| 1223 { | |
| 1224 *dp++ = *sp++; | |
| 1225 *dp++ = *sp++; | |
| 1226 *dp++ = *sp++; | |
| 1227 } | |
| 1228 } | |
| 1229 else if (a) | |
| 1230 { | |
| 1231 const uint32_t mask = 0x00ff00ff; | |
| 1232 uint32_t d0 = *(uint32_t *)dp; | |
| 1233 uint32_t d1 = d0>>8; | |
| 1234 uint32_t s0 = *(uint32_t *)sp; | |
| 1235 uint32_t s1 = s0>>8; | |
| 1236 d0 &= mask; | |
| 1237 d1 &= mask; | |
| 1238 s0 &= mask; | |
| 1239 s1 &= mask; | |
| 1240 d0 = (((d0<<8) + (s0-d0)*ma)>>8) & mask; | |
| 1241 d1 = ((d1<<8) + (s1-d1)*ma) & ~mask; | |
| 1242 d0 |= d1; | |
| 1243 | |
| 1244 #ifndef NDEBUG | |
| 1245 if (isbigendian()) | |
| 1246 { | |
| 1247 assert((d0 & 0xff) >= (d0>>24)); | |
| 1248 assert((d0 & 0xff) >= ((d0>>16) & 0xff)); | |
| 1249 assert((d0 & 0xff) >= ((d0>>8) & 0xff)); | |
| 1250 } | |
| 1251 else | |
| 1252 { | |
| 1253 assert((d0>>24) >= (d0 & 0xff)); | |
| 1254 assert((d0>>24) >= ((d0>>8) & 0xff)); | |
| 1255 assert((d0>>24) >= ((d0>>16) & 0xff)); | |
| 1256 } | |
| 1257 #endif | |
| 1258 | |
| 1259 *(uint32_t *)dp = d0; | |
| 1260 sp += 4; | |
| 1261 dp += 4; | |
| 1262 } | |
| 1263 else | |
| 1264 { | |
| 1265 *dp = FZ_BLEND(*sp, *dp, ma); | |
| 1266 sp++; dp++; | |
| 1267 *dp = FZ_BLEND(*sp, *dp, ma); | |
| 1268 sp++; dp++; | |
| 1269 *dp = FZ_BLEND(*sp, *dp, ma); | |
| 1270 sp++; dp++; | |
| 1271 } | |
| 1272 } | |
| 1273 while (--w); | |
| 1274 } | |
| 1275 | |
| 1276 static fz_forceinline void | |
| 1277 template_span_with_mask_4_general(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, int a, const byte * FZ_RESTRICT mp, int w) | |
| 1278 { | |
| 1279 do | |
| 1280 { | |
| 1281 int ma = *mp++; | |
| 1282 ma = FZ_EXPAND(ma); | |
| 1283 if (ma == 0 || (a && sp[4] == 0)) | |
| 1284 { | |
| 1285 dp += 4 + a; | |
| 1286 sp += 4 + a; | |
| 1287 } | |
| 1288 else if (ma == 256) | |
| 1289 { | |
| 1290 if (!a) | |
| 1291 { | |
| 1292 *(uint32_t *)dp = *(uint32_t *)sp; | |
| 1293 dp += 4; | |
| 1294 sp += 4; | |
| 1295 } | |
| 1296 else | |
| 1297 { | |
| 1298 *dp++ = *sp++; | |
| 1299 *dp++ = *sp++; | |
| 1300 *dp++ = *sp++; | |
| 1301 *dp++ = *sp++; | |
| 1302 *dp++ = *sp++; | |
| 1303 } | |
| 1304 } | |
| 1305 else if (a) | |
| 1306 { | |
| 1307 *dp = FZ_BLEND(*sp, *dp, ma); | |
| 1308 sp++; dp++; | |
| 1309 *dp = FZ_BLEND(*sp, *dp, ma); | |
| 1310 sp++; dp++; | |
| 1311 *dp = FZ_BLEND(*sp, *dp, ma); | |
| 1312 sp++; dp++; | |
| 1313 *dp = FZ_BLEND(*sp, *dp, ma); | |
| 1314 sp++; dp++; | |
| 1315 *dp = FZ_BLEND(*sp, *dp, ma); | |
| 1316 sp++; dp++; | |
| 1317 } | |
| 1318 else | |
| 1319 { | |
| 1320 const uint32_t mask = 0x00ff00ff; | |
| 1321 uint32_t d0 = *(uint32_t *)dp; | |
| 1322 uint32_t d1 = d0>>8; | |
| 1323 uint32_t s0 = *(uint32_t *)sp; | |
| 1324 uint32_t s1 = s0>>8; | |
| 1325 sp += 4; | |
| 1326 d0 &= mask; | |
| 1327 d1 &= mask; | |
| 1328 s0 &= mask; | |
| 1329 s1 &= mask; | |
| 1330 d0 = (((d0<<8) + (s0-d0)*ma)>>8) & mask; | |
| 1331 d1 = ((d1<<8) + (s1-d1)*ma) & ~mask; | |
| 1332 d0 |= d1; | |
| 1333 *(uint32_t *)dp = d0; | |
| 1334 dp += 4; | |
| 1335 } | |
| 1336 } | |
| 1337 while (--w); | |
| 1338 } | |
| 1339 | |
| 1340 static fz_forceinline void | |
| 1341 template_span_with_mask_N_general(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, int a, const byte * FZ_RESTRICT mp, int n, int w) | |
| 1342 { | |
| 1343 do | |
| 1344 { | |
| 1345 int ma = *mp++; | |
| 1346 ma = FZ_EXPAND(ma); | |
| 1347 if (ma == 0 || (a && sp[n] == 0)) | |
| 1348 { | |
| 1349 dp += n + a; | |
| 1350 sp += n + a; | |
| 1351 } | |
| 1352 else if (ma == 256) | |
| 1353 { | |
| 1354 int k; | |
| 1355 for (k = 0; k < n; k++) | |
| 1356 *dp++ = *sp++; | |
| 1357 if (a) | |
| 1358 *dp++ = *sp++; | |
| 1359 } | |
| 1360 else | |
| 1361 { | |
| 1362 int k; | |
| 1363 for (k = 0; k < n; k++) | |
| 1364 { | |
| 1365 *dp = FZ_BLEND(*sp, *dp, ma); | |
| 1366 sp++; dp++; | |
| 1367 } | |
| 1368 if (a) | |
| 1369 { | |
| 1370 *dp = FZ_BLEND(*sp, *dp, ma); | |
| 1371 sp++; dp++; | |
| 1372 } | |
| 1373 } | |
| 1374 } | |
| 1375 while (--w); | |
| 1376 } | |
| 1377 | |
| 1378 static void | |
| 1379 paint_span_with_mask_0_a(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop) | |
| 1380 { | |
| 1381 TRACK_FN(); | |
| 1382 template_span_with_mask_N_general(dp, sp, 1, mp, 0, w); | |
| 1383 } | |
| 1384 | |
| 1385 static void | |
| 1386 paint_span_with_mask_1_a(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop) | |
| 1387 { | |
| 1388 TRACK_FN(); | |
| 1389 template_span_with_mask_1_general(dp, sp, 1, mp, w); | |
| 1390 } | |
| 1391 | |
| 1392 static void | |
| 1393 paint_span_with_mask_1(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop) | |
| 1394 { | |
| 1395 TRACK_FN(); | |
| 1396 template_span_with_mask_1_general(dp, sp, 0, mp, w); | |
| 1397 } | |
| 1398 | |
| 1399 #if FZ_PLOTTERS_RGB | |
| 1400 static void | |
| 1401 paint_span_with_mask_3_a(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop) | |
| 1402 { | |
| 1403 TRACK_FN(); | |
| 1404 template_span_with_mask_3_general(dp, sp, 1, mp, w); | |
| 1405 } | |
| 1406 | |
| 1407 static void | |
| 1408 paint_span_with_mask_3(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop) | |
| 1409 { | |
| 1410 TRACK_FN(); | |
| 1411 template_span_with_mask_3_general(dp, sp, 0, mp, w); | |
| 1412 } | |
| 1413 #endif /* FZ_PLOTTERS_RGB */ | |
| 1414 | |
| 1415 #if FZ_PLOTTERS_CMYK | |
| 1416 static void | |
| 1417 paint_span_with_mask_4_a(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop) | |
| 1418 { | |
| 1419 TRACK_FN(); | |
| 1420 template_span_with_mask_4_general(dp, sp, 1, mp, w); | |
| 1421 } | |
| 1422 | |
| 1423 static void | |
| 1424 paint_span_with_mask_4(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop) | |
| 1425 { | |
| 1426 TRACK_FN(); | |
| 1427 template_span_with_mask_4_general(dp, sp, 0, mp, w); | |
| 1428 } | |
| 1429 #endif /* FZ_PLOTTERS_CMYK */ | |
| 1430 | |
| 1431 #if FZ_PLOTTERS_N | |
| 1432 static void | |
| 1433 paint_span_with_mask_N_a(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop) | |
| 1434 { | |
| 1435 TRACK_FN(); | |
| 1436 template_span_with_mask_N_general(dp, sp, 1, mp, n, w); | |
| 1437 } | |
| 1438 | |
| 1439 static void | |
| 1440 paint_span_with_mask_N(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop) | |
| 1441 { | |
| 1442 TRACK_FN(); | |
| 1443 template_span_with_mask_N_general(dp, sp, 0, mp, n, w); | |
| 1444 } | |
| 1445 #endif /* FZ_PLOTTERS_N */ | |
| 1446 | |
| 1447 typedef void (fz_span_mask_painter_t)(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w, int n, int a, const fz_overprint * FZ_RESTRICT eop); | |
| 1448 | |
| 1449 static fz_span_mask_painter_t * | |
| 1450 fz_get_span_mask_painter(int a, int n) | |
| 1451 { | |
| 1452 switch(n) | |
| 1453 { | |
| 1454 case 0: | |
| 1455 /* assert(a); */ | |
| 1456 return paint_span_with_mask_0_a; | |
| 1457 case 1: | |
| 1458 if (a) | |
| 1459 return paint_span_with_mask_1_a; | |
| 1460 else | |
| 1461 return paint_span_with_mask_1; | |
| 1462 #if FZ_PLOTTERS_RGB | |
| 1463 case 3: | |
| 1464 if (a) | |
| 1465 return paint_span_with_mask_3_a; | |
| 1466 else | |
| 1467 return paint_span_with_mask_3; | |
| 1468 #endif /* FZ_PLOTTERS_RGB */ | |
| 1469 #if FZ_PLOTTERS_CMYK | |
| 1470 case 4: | |
| 1471 if (a) | |
| 1472 return paint_span_with_mask_4_a; | |
| 1473 else | |
| 1474 return paint_span_with_mask_4; | |
| 1475 #endif /* FZ_PLOTTERS_CMYK */ | |
| 1476 default: | |
| 1477 { | |
| 1478 #if FZ_PLOTTERS_N | |
| 1479 if (a) | |
| 1480 return paint_span_with_mask_N_a; | |
| 1481 else | |
| 1482 return paint_span_with_mask_N; | |
| 1483 #else | |
| 1484 return NULL; | |
| 1485 #endif /* FZ_PLOTTERS_N */ | |
| 1486 } | |
| 1487 } | |
| 1488 } | |
| 1489 | |
| 1490 /* Blend source in constant alpha over destination */ | |
| 1491 | |
| 1492 static fz_forceinline void | |
| 1493 template_span_1_with_alpha_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int w, int alpha) | |
| 1494 { | |
| 1495 if (sa) | |
| 1496 alpha = FZ_EXPAND(alpha); | |
| 1497 do | |
| 1498 { | |
| 1499 int masa = (sa ? FZ_COMBINE(sp[1], alpha) : alpha); | |
| 1500 int t = FZ_EXPAND(255-masa); | |
| 1501 *dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t); | |
| 1502 dp++; sp++; | |
| 1503 if (da) | |
| 1504 { | |
| 1505 *dp = masa + FZ_COMBINE(*dp, t); | |
| 1506 dp++; | |
| 1507 } | |
| 1508 if (sa) | |
| 1509 sp++; | |
| 1510 } | |
| 1511 while (--w); | |
| 1512 } | |
| 1513 | |
| 1514 static fz_forceinline void | |
| 1515 template_span_3_with_alpha_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int w, int alpha) | |
| 1516 { | |
| 1517 if (sa) | |
| 1518 alpha = FZ_EXPAND(alpha); | |
| 1519 do | |
| 1520 { | |
| 1521 int masa = (sa ? FZ_COMBINE(sp[3], alpha) : alpha); | |
| 1522 int t = FZ_EXPAND(255-masa); | |
| 1523 *dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t); | |
| 1524 sp++; dp++; | |
| 1525 *dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t); | |
| 1526 sp++; dp++; | |
| 1527 *dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t); | |
| 1528 sp++; dp++; | |
| 1529 if (da) | |
| 1530 { | |
| 1531 *dp = masa + FZ_COMBINE(*dp, t); | |
| 1532 dp++; | |
| 1533 } | |
| 1534 if (sa) | |
| 1535 sp++; | |
| 1536 } | |
| 1537 while (--w); | |
| 1538 } | |
| 1539 | |
| 1540 static fz_forceinline void | |
| 1541 template_span_4_with_alpha_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int w, int alpha) | |
| 1542 { | |
| 1543 if (sa) | |
| 1544 alpha = FZ_EXPAND(alpha); | |
| 1545 do | |
| 1546 { | |
| 1547 int masa = (sa ? FZ_COMBINE(sp[4], alpha) : alpha); | |
| 1548 int t = FZ_EXPAND(255-masa); | |
| 1549 *dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t); | |
| 1550 sp++; dp++; | |
| 1551 *dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t); | |
| 1552 sp++; dp++; | |
| 1553 *dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t); | |
| 1554 sp++; dp++; | |
| 1555 *dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t); | |
| 1556 sp++; dp++; | |
| 1557 if (da) | |
| 1558 { | |
| 1559 *dp = masa + FZ_COMBINE(*dp, t); | |
| 1560 dp++; | |
| 1561 } | |
| 1562 if (sa) | |
| 1563 sp++; | |
| 1564 } | |
| 1565 while (--w); | |
| 1566 } | |
| 1567 | |
| 1568 #if FZ_PLOTTERS_N | |
| 1569 static fz_forceinline void | |
| 1570 template_span_N_with_alpha_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n1, int w, int alpha) | |
| 1571 { | |
| 1572 if (sa) | |
| 1573 alpha = FZ_EXPAND(alpha); | |
| 1574 do | |
| 1575 { | |
| 1576 int masa = (sa ? FZ_COMBINE(sp[n1], alpha) : alpha); | |
| 1577 int t = FZ_EXPAND(255-masa); | |
| 1578 int k; | |
| 1579 for (k = 0; k < n1; k++) | |
| 1580 { | |
| 1581 *dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t); | |
| 1582 sp++; dp++; | |
| 1583 } | |
| 1584 if (da) | |
| 1585 { | |
| 1586 *dp = masa + FZ_COMBINE(*dp, t); | |
| 1587 dp++; | |
| 1588 } | |
| 1589 if (sa) | |
| 1590 sp++; | |
| 1591 } | |
| 1592 while (--w); | |
| 1593 } | |
| 1594 | |
| 1595 static fz_forceinline void | |
| 1596 template_span_N_with_alpha_general_op(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n1, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 1597 { | |
| 1598 if (sa) | |
| 1599 alpha = FZ_EXPAND(alpha); | |
| 1600 do | |
| 1601 { | |
| 1602 int masa = (sa ? FZ_COMBINE(sp[n1], alpha) : alpha); | |
| 1603 int t = FZ_EXPAND(255-masa); | |
| 1604 int k; | |
| 1605 for (k = 0; k < n1; k++) | |
| 1606 { | |
| 1607 if (fz_overprint_component(eop, k)) | |
| 1608 *dp = FZ_COMBINE(*sp, alpha) + FZ_COMBINE(*dp, t); | |
| 1609 sp++; | |
| 1610 dp++; | |
| 1611 } | |
| 1612 if (da) | |
| 1613 { | |
| 1614 *dp = masa + FZ_COMBINE(*dp, t); | |
| 1615 dp++; | |
| 1616 } | |
| 1617 if (sa) | |
| 1618 sp++; | |
| 1619 } | |
| 1620 while (--w); | |
| 1621 } | |
| 1622 #endif | |
| 1623 | |
| 1624 /* Blend source over destination */ | |
| 1625 | |
| 1626 static fz_forceinline void | |
| 1627 template_span_1_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int w) | |
| 1628 { | |
| 1629 do | |
| 1630 { | |
| 1631 int t = (sa ? FZ_EXPAND(sp[1]): 256); | |
| 1632 if (t == 0) | |
| 1633 { | |
| 1634 dp += 1 + da; sp += 1 + sa; | |
| 1635 } | |
| 1636 else | |
| 1637 { | |
| 1638 t = 256 - t; | |
| 1639 if (t == 0) | |
| 1640 { | |
| 1641 *dp++ = *sp++; | |
| 1642 if (da) | |
| 1643 *dp++ = (sa ? *sp : 255); | |
| 1644 if (sa) | |
| 1645 sp++; | |
| 1646 } | |
| 1647 else | |
| 1648 { | |
| 1649 *dp = *sp + FZ_COMBINE(*dp, t); | |
| 1650 sp++; | |
| 1651 dp++; | |
| 1652 if (da) | |
| 1653 { | |
| 1654 *dp = *sp + FZ_COMBINE(*dp, t); | |
| 1655 dp++; | |
| 1656 } | |
| 1657 sp++; | |
| 1658 } | |
| 1659 } | |
| 1660 } | |
| 1661 while (--w); | |
| 1662 } | |
| 1663 | |
| 1664 static fz_forceinline void | |
| 1665 template_span_3_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int w) | |
| 1666 { | |
| 1667 do | |
| 1668 { | |
| 1669 int t = (sa ? FZ_EXPAND(sp[3]) : 256); | |
| 1670 if (t == 0) | |
| 1671 { | |
| 1672 dp += 3 + da; sp += 3 + sa; | |
| 1673 } | |
| 1674 else | |
| 1675 { | |
| 1676 t = 256 - t; | |
| 1677 if (t == 0) | |
| 1678 { | |
| 1679 if (da && sa) | |
| 1680 *(int32_t *)dp = *(const int32_t *)sp; | |
| 1681 else | |
| 1682 { | |
| 1683 dp[0] = sp[0]; | |
| 1684 dp[1] = sp[1]; | |
| 1685 dp[2] = sp[2]; | |
| 1686 if (da) | |
| 1687 dp[3] = 255; | |
| 1688 } | |
| 1689 dp += 3+da; sp += 3+sa; | |
| 1690 } | |
| 1691 else | |
| 1692 { | |
| 1693 /* sa != 0 as t != 0 */ | |
| 1694 *dp = *sp++ + FZ_COMBINE(*dp, t); | |
| 1695 dp++; | |
| 1696 *dp = *sp++ + FZ_COMBINE(*dp, t); | |
| 1697 dp++; | |
| 1698 *dp = *sp++ + FZ_COMBINE(*dp, t); | |
| 1699 dp++; | |
| 1700 if (da) | |
| 1701 { | |
| 1702 *dp = *sp + FZ_COMBINE(*dp, t); | |
| 1703 dp++; | |
| 1704 } | |
| 1705 sp++; | |
| 1706 } | |
| 1707 } | |
| 1708 } | |
| 1709 while (--w); | |
| 1710 } | |
| 1711 | |
| 1712 static fz_forceinline void | |
| 1713 template_span_4_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int w) | |
| 1714 { | |
| 1715 do | |
| 1716 { | |
| 1717 int t = (sa ? FZ_EXPAND(sp[4]) : 256); | |
| 1718 if (t == 0) | |
| 1719 { | |
| 1720 dp += 4+da; sp += 4+sa; | |
| 1721 } | |
| 1722 else | |
| 1723 { | |
| 1724 t = 256 - t; | |
| 1725 if (t == 0) | |
| 1726 { | |
| 1727 dp[0] = sp[0]; | |
| 1728 dp[1] = sp[1]; | |
| 1729 dp[2] = sp[2]; | |
| 1730 dp[3] = sp[3]; | |
| 1731 if (da) | |
| 1732 dp[4] = (sa ? sp[4] : 255); | |
| 1733 dp += 4+da; sp += 4 + sa; | |
| 1734 } | |
| 1735 else | |
| 1736 { | |
| 1737 /* sa != 0 as t != 0 */ | |
| 1738 *dp = *sp++ + FZ_COMBINE(*dp, t); | |
| 1739 dp++; | |
| 1740 *dp = *sp++ + FZ_COMBINE(*dp, t); | |
| 1741 dp++; | |
| 1742 *dp = *sp++ + FZ_COMBINE(*dp, t); | |
| 1743 dp++; | |
| 1744 *dp = *sp++ + FZ_COMBINE(*dp, t); | |
| 1745 dp++; | |
| 1746 if (da) | |
| 1747 { | |
| 1748 *dp = *sp + FZ_COMBINE(*dp, t); | |
| 1749 dp++; | |
| 1750 } | |
| 1751 sp++; | |
| 1752 } | |
| 1753 } | |
| 1754 } | |
| 1755 while (--w); | |
| 1756 } | |
| 1757 | |
| 1758 #if FZ_PLOTTERS_N | |
| 1759 static fz_forceinline void | |
| 1760 template_span_N_general(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n1, int w) | |
| 1761 { | |
| 1762 do | |
| 1763 { | |
| 1764 int t = (sa ? FZ_EXPAND(sp[n1]) : 256); | |
| 1765 if (t == 0) | |
| 1766 { | |
| 1767 dp += n1 + da; sp += n1 + sa; | |
| 1768 } | |
| 1769 else | |
| 1770 { | |
| 1771 t = 256 - t; | |
| 1772 if (t == 0) | |
| 1773 { | |
| 1774 int k; | |
| 1775 for (k = 0; k < n1; k++) | |
| 1776 *dp++ = *sp++; | |
| 1777 if (da) | |
| 1778 *dp++ = (sa ? *sp : 255); | |
| 1779 if (sa) | |
| 1780 sp++; | |
| 1781 } | |
| 1782 else | |
| 1783 { | |
| 1784 /* sa != 0, as t != 0 */ | |
| 1785 int k; | |
| 1786 for (k = 0; k < n1; k++) | |
| 1787 { | |
| 1788 *dp = *sp + FZ_COMBINE(*dp, t); | |
| 1789 sp++; | |
| 1790 dp++; | |
| 1791 } | |
| 1792 if (da) | |
| 1793 { | |
| 1794 *dp = *sp + FZ_COMBINE(*dp, t); | |
| 1795 dp++; | |
| 1796 } | |
| 1797 sp++; | |
| 1798 } | |
| 1799 } | |
| 1800 } | |
| 1801 while (--w); | |
| 1802 } | |
| 1803 | |
| 1804 static fz_forceinline void | |
| 1805 template_span_N_general_op(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n1, int w, const fz_overprint * FZ_RESTRICT eop) | |
| 1806 { | |
| 1807 do | |
| 1808 { | |
| 1809 int t = (sa ? FZ_EXPAND(sp[n1]) : 256); | |
| 1810 if (t == 0) | |
| 1811 { | |
| 1812 dp += n1 + da; sp += n1 + sa; | |
| 1813 } | |
| 1814 else | |
| 1815 { | |
| 1816 t = 256 - t; | |
| 1817 if (t == 0) | |
| 1818 { | |
| 1819 int k; | |
| 1820 for (k = 0; k < n1; k++) | |
| 1821 { | |
| 1822 if (fz_overprint_component(eop, k)) | |
| 1823 *dp = *sp; | |
| 1824 dp++; | |
| 1825 sp++; | |
| 1826 } | |
| 1827 if (da) | |
| 1828 *dp++ = (sa ? *sp : 255); | |
| 1829 if (sa) | |
| 1830 sp++; | |
| 1831 } | |
| 1832 else | |
| 1833 { | |
| 1834 int k; | |
| 1835 /* sa can never be 0 here, as t != 0. */ | |
| 1836 for (k = 0; k < n1; k++) | |
| 1837 { | |
| 1838 if (fz_overprint_component(eop, k)) | |
| 1839 *dp = *sp + FZ_COMBINE(*dp, t); | |
| 1840 sp++; | |
| 1841 dp++; | |
| 1842 } | |
| 1843 if (da) | |
| 1844 { | |
| 1845 *dp = *sp + FZ_COMBINE(*dp, t); | |
| 1846 dp++; | |
| 1847 } | |
| 1848 sp++; | |
| 1849 } | |
| 1850 } | |
| 1851 } | |
| 1852 while (--w); | |
| 1853 } | |
| 1854 #endif | |
| 1855 | |
| 1856 static void | |
| 1857 paint_span_0_da_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 1858 { | |
| 1859 TRACK_FN(); | |
| 1860 do | |
| 1861 { | |
| 1862 int s = *sp++; | |
| 1863 int t = FZ_EXPAND(255 - s); | |
| 1864 *dp = s + FZ_COMBINE(*dp, t); | |
| 1865 dp ++; | |
| 1866 } | |
| 1867 while (--w); | |
| 1868 } | |
| 1869 | |
| 1870 static void | |
| 1871 paint_span_0_da_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 1872 { | |
| 1873 TRACK_FN(); | |
| 1874 alpha = FZ_EXPAND(alpha); | |
| 1875 do | |
| 1876 { | |
| 1877 int masa = FZ_COMBINE(sp[0], alpha); | |
| 1878 int t = FZ_EXPAND(255-masa); | |
| 1879 *dp = masa + FZ_COMBINE(*dp, t); | |
| 1880 dp++; | |
| 1881 sp++; | |
| 1882 } | |
| 1883 while (--w); | |
| 1884 } | |
| 1885 | |
| 1886 static void | |
| 1887 paint_span_1_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 1888 { | |
| 1889 TRACK_FN(); | |
| 1890 template_span_1_general(dp, 0, sp, 1, w); | |
| 1891 } | |
| 1892 | |
| 1893 static void | |
| 1894 paint_span_1_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 1895 { | |
| 1896 TRACK_FN(); | |
| 1897 template_span_1_with_alpha_general(dp, 0, sp, 1, w, alpha); | |
| 1898 } | |
| 1899 | |
| 1900 static void | |
| 1901 paint_span_1_da_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 1902 { | |
| 1903 TRACK_FN(); | |
| 1904 template_span_1_general(dp, 1, sp, 1, w); | |
| 1905 } | |
| 1906 | |
| 1907 static void | |
| 1908 paint_span_1_da_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 1909 { | |
| 1910 TRACK_FN(); | |
| 1911 template_span_1_with_alpha_general(dp, 1, sp, 1, w, alpha); | |
| 1912 } | |
| 1913 | |
| 1914 #if FZ_PLOTTERS_G | |
| 1915 static void | |
| 1916 paint_span_1_da(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 1917 { | |
| 1918 TRACK_FN(); | |
| 1919 template_span_1_general(dp, 1, sp, 0, w); | |
| 1920 } | |
| 1921 | |
| 1922 static void | |
| 1923 paint_span_1_da_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 1924 { | |
| 1925 TRACK_FN(); | |
| 1926 template_span_1_with_alpha_general(dp, 1, sp, 0, w, alpha); | |
| 1927 } | |
| 1928 | |
| 1929 static void | |
| 1930 paint_span_1(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 1931 { | |
| 1932 TRACK_FN(); | |
| 1933 template_span_1_general(dp, 0, sp, 0, w); | |
| 1934 } | |
| 1935 | |
| 1936 static void | |
| 1937 paint_span_1_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 1938 { | |
| 1939 TRACK_FN(); | |
| 1940 template_span_1_with_alpha_general(dp, 0, sp, 0, w, alpha); | |
| 1941 } | |
| 1942 #endif /* FZ_PLOTTERS_G */ | |
| 1943 | |
| 1944 #if FZ_PLOTTERS_RGB | |
| 1945 static void | |
| 1946 paint_span_3_da_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 1947 { | |
| 1948 TRACK_FN(); | |
| 1949 template_span_3_general(dp, 1, sp, 1, w); | |
| 1950 } | |
| 1951 | |
| 1952 static void | |
| 1953 paint_span_3_da_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 1954 { | |
| 1955 TRACK_FN(); | |
| 1956 template_span_3_with_alpha_general(dp, 1, sp, 1, w, alpha); | |
| 1957 } | |
| 1958 | |
| 1959 static void | |
| 1960 paint_span_3_da(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 1961 { | |
| 1962 TRACK_FN(); | |
| 1963 template_span_3_general(dp, 1, sp, 0, w); | |
| 1964 } | |
| 1965 | |
| 1966 static void | |
| 1967 paint_span_3_da_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 1968 { | |
| 1969 TRACK_FN(); | |
| 1970 template_span_3_with_alpha_general(dp, 1, sp, 0, w, alpha); | |
| 1971 } | |
| 1972 | |
| 1973 static void | |
| 1974 paint_span_3_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 1975 { | |
| 1976 TRACK_FN(); | |
| 1977 template_span_3_general(dp, 0, sp, 1, w); | |
| 1978 } | |
| 1979 | |
| 1980 static void | |
| 1981 paint_span_3_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 1982 { | |
| 1983 TRACK_FN(); | |
| 1984 template_span_3_with_alpha_general(dp, 0, sp, 1, w, alpha); | |
| 1985 } | |
| 1986 | |
| 1987 static void | |
| 1988 paint_span_3(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 1989 { | |
| 1990 TRACK_FN(); | |
| 1991 template_span_3_general(dp, 0, sp, 0, w); | |
| 1992 } | |
| 1993 | |
| 1994 static void | |
| 1995 paint_span_3_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 1996 { | |
| 1997 TRACK_FN(); | |
| 1998 template_span_3_with_alpha_general(dp, 0, sp, 0, w, alpha); | |
| 1999 } | |
| 2000 #endif /* FZ_PLOTTERS_RGB */ | |
| 2001 | |
| 2002 #if FZ_PLOTTERS_CMYK | |
| 2003 static void | |
| 2004 paint_span_4_da_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 2005 { | |
| 2006 TRACK_FN(); | |
| 2007 template_span_4_general(dp, 1, sp, 1, w); | |
| 2008 } | |
| 2009 | |
| 2010 static void | |
| 2011 paint_span_4_da_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 2012 { | |
| 2013 TRACK_FN(); | |
| 2014 template_span_4_with_alpha_general(dp, 1, sp, 1, w, alpha); | |
| 2015 } | |
| 2016 | |
| 2017 static void | |
| 2018 paint_span_4_da(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 2019 { | |
| 2020 TRACK_FN(); | |
| 2021 template_span_4_general(dp, 1, sp, 0, w); | |
| 2022 } | |
| 2023 | |
| 2024 static void | |
| 2025 paint_span_4_da_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 2026 { | |
| 2027 TRACK_FN(); | |
| 2028 template_span_4_with_alpha_general(dp, 1, sp, 0, w, alpha); | |
| 2029 } | |
| 2030 | |
| 2031 static void | |
| 2032 paint_span_4_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 2033 { | |
| 2034 TRACK_FN(); | |
| 2035 template_span_4_general(dp, 0, sp, 1, w); | |
| 2036 } | |
| 2037 | |
| 2038 static void | |
| 2039 paint_span_4_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 2040 { | |
| 2041 TRACK_FN(); | |
| 2042 template_span_4_with_alpha_general(dp, 0, sp, 1, w, alpha); | |
| 2043 } | |
| 2044 | |
| 2045 static void | |
| 2046 paint_span_4(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 2047 { | |
| 2048 TRACK_FN(); | |
| 2049 template_span_4_general(dp, 0, sp, 0, w); | |
| 2050 } | |
| 2051 | |
| 2052 static void | |
| 2053 paint_span_4_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 2054 { | |
| 2055 TRACK_FN(); | |
| 2056 template_span_4_with_alpha_general(dp, 0, sp, 0, w, alpha); | |
| 2057 } | |
| 2058 #endif /* FZ_PLOTTERS_CMYK */ | |
| 2059 | |
| 2060 #if FZ_PLOTTERS_N | |
| 2061 static void | |
| 2062 paint_span_N_da_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 2063 { | |
| 2064 TRACK_FN(); | |
| 2065 template_span_N_general(dp, 1, sp, 1, n, w); | |
| 2066 } | |
| 2067 | |
| 2068 static void | |
| 2069 paint_span_N_da_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 2070 { | |
| 2071 TRACK_FN(); | |
| 2072 template_span_N_with_alpha_general(dp, 1, sp, 1, n, w, alpha); | |
| 2073 } | |
| 2074 | |
| 2075 static void | |
| 2076 paint_span_N_da(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 2077 { | |
| 2078 TRACK_FN(); | |
| 2079 template_span_N_general(dp, 1, sp, 0, n, w); | |
| 2080 } | |
| 2081 | |
| 2082 static void | |
| 2083 paint_span_N_da_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 2084 { | |
| 2085 TRACK_FN(); | |
| 2086 template_span_N_with_alpha_general(dp, 1, sp, 0, n, w, alpha); | |
| 2087 } | |
| 2088 | |
| 2089 static void | |
| 2090 paint_span_N_sa(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 2091 { | |
| 2092 TRACK_FN(); | |
| 2093 template_span_N_general(dp, 0, sp, 1, n, w); | |
| 2094 } | |
| 2095 | |
| 2096 static void | |
| 2097 paint_span_N_sa_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 2098 { | |
| 2099 TRACK_FN(); | |
| 2100 template_span_N_with_alpha_general(dp, 0, sp, 1, n, w, alpha); | |
| 2101 } | |
| 2102 | |
| 2103 static void | |
| 2104 paint_span_N(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 2105 { | |
| 2106 TRACK_FN(); | |
| 2107 template_span_N_general(dp, 0, sp, 0, n, w); | |
| 2108 } | |
| 2109 | |
| 2110 static void | |
| 2111 paint_span_N_alpha(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 2112 { | |
| 2113 TRACK_FN(); | |
| 2114 template_span_N_with_alpha_general(dp, 0, sp, 0, n, w, alpha); | |
| 2115 } | |
| 2116 #endif /* FZ_PLOTTERS_N */ | |
| 2117 | |
| 2118 #if FZ_ENABLE_SPOT_RENDERING | |
| 2119 static void | |
| 2120 paint_span_N_general_op(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 2121 { | |
| 2122 TRACK_FN(); | |
| 2123 template_span_N_general_op(dp, da, sp, sa, n, w, eop); | |
| 2124 } | |
| 2125 | |
| 2126 static void | |
| 2127 paint_span_N_general_alpha_op(byte * FZ_RESTRICT dp, int da, const byte * FZ_RESTRICT sp, int sa, int n, int w, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 2128 { | |
| 2129 TRACK_FN(); | |
| 2130 template_span_N_with_alpha_general_op(dp, da, sp, sa, n, w, alpha, eop); | |
| 2131 } | |
| 2132 #endif /* FZ_ENABLE_SPOT_RENDERING */ | |
| 2133 | |
| 2134 fz_span_painter_t * | |
| 2135 fz_get_span_painter(int da, int sa, int n, int alpha, const fz_overprint * FZ_RESTRICT eop) | |
| 2136 { | |
| 2137 #if FZ_ENABLE_SPOT_RENDERING | |
| 2138 if (fz_overprint_required(eop)) | |
| 2139 { | |
| 2140 if (alpha == 255) | |
| 2141 return paint_span_N_general_op; | |
| 2142 else if (alpha > 0) | |
| 2143 return paint_span_N_general_alpha_op; | |
| 2144 else | |
| 2145 return NULL; | |
| 2146 } | |
| 2147 #endif /* FZ_ENABLE_SPOT_RENDERING */ | |
| 2148 switch (n) | |
| 2149 { | |
| 2150 case 0: | |
| 2151 if (alpha == 255) | |
| 2152 return paint_span_0_da_sa; | |
| 2153 else if (alpha > 0) | |
| 2154 return paint_span_0_da_sa_alpha; | |
| 2155 break; | |
| 2156 case 1: | |
| 2157 if (sa) | |
| 2158 if (da) | |
| 2159 { | |
| 2160 if (alpha == 255) | |
| 2161 return paint_span_1_da_sa; | |
| 2162 else if (alpha > 0) | |
| 2163 return paint_span_1_da_sa_alpha; | |
| 2164 } | |
| 2165 else | |
| 2166 { | |
| 2167 if (alpha == 255) | |
| 2168 return paint_span_1_sa; | |
| 2169 else if (alpha > 0) | |
| 2170 return paint_span_1_sa_alpha; | |
| 2171 } | |
| 2172 else | |
| 2173 #if FZ_PLOTTERS_G | |
| 2174 if (da) | |
| 2175 { | |
| 2176 if (alpha == 255) | |
| 2177 return paint_span_1_da; | |
| 2178 else if (alpha > 0) | |
| 2179 return paint_span_1_da_alpha; | |
| 2180 } | |
| 2181 else | |
| 2182 { | |
| 2183 if (alpha == 255) | |
| 2184 return paint_span_1; | |
| 2185 else if (alpha > 0) | |
| 2186 return paint_span_1_alpha; | |
| 2187 } | |
| 2188 #else | |
| 2189 goto fallback; | |
| 2190 #endif /* FZ_PLOTTERS_G */ | |
| 2191 break; | |
| 2192 #if FZ_PLOTTERS_RGB | |
| 2193 case 3: | |
| 2194 if (da) | |
| 2195 if (sa) | |
| 2196 { | |
| 2197 if (alpha == 255) | |
| 2198 return paint_span_3_da_sa; | |
| 2199 else if (alpha > 0) | |
| 2200 return paint_span_3_da_sa_alpha; | |
| 2201 } | |
| 2202 else | |
| 2203 { | |
| 2204 if (alpha == 255) | |
| 2205 return paint_span_3_da; | |
| 2206 else if (alpha > 0) | |
| 2207 return paint_span_3_da_alpha; | |
| 2208 } | |
| 2209 else | |
| 2210 if (sa) | |
| 2211 { | |
| 2212 if (alpha == 255) | |
| 2213 return paint_span_3_sa; | |
| 2214 else if (alpha > 0) | |
| 2215 return paint_span_3_sa_alpha; | |
| 2216 } | |
| 2217 else | |
| 2218 { | |
| 2219 if (alpha == 255) | |
| 2220 return paint_span_3; | |
| 2221 else if (alpha > 0) | |
| 2222 return paint_span_3_alpha; | |
| 2223 } | |
| 2224 break; | |
| 2225 #endif /* FZ_PLOTTERS_RGB */ | |
| 2226 #if FZ_PLOTTERS_CMYK | |
| 2227 case 4: | |
| 2228 if (da) | |
| 2229 if (sa) | |
| 2230 { | |
| 2231 if (alpha == 255) | |
| 2232 return paint_span_4_da_sa; | |
| 2233 else if (alpha > 0) | |
| 2234 return paint_span_4_da_sa_alpha; | |
| 2235 } | |
| 2236 else | |
| 2237 { | |
| 2238 if (alpha == 255) | |
| 2239 return paint_span_4_da; | |
| 2240 else if (alpha > 0) | |
| 2241 return paint_span_4_da_alpha; | |
| 2242 } | |
| 2243 else | |
| 2244 if (sa) | |
| 2245 { | |
| 2246 if (alpha == 255) | |
| 2247 return paint_span_4_sa; | |
| 2248 else if (alpha > 0) | |
| 2249 return paint_span_4_sa_alpha; | |
| 2250 } | |
| 2251 else | |
| 2252 { | |
| 2253 if (alpha == 255) | |
| 2254 return paint_span_4; | |
| 2255 else if (alpha > 0) | |
| 2256 return paint_span_4_alpha; | |
| 2257 } | |
| 2258 break; | |
| 2259 #endif /* FZ_PLOTTERS_CMYK */ | |
| 2260 default: | |
| 2261 { | |
| 2262 #if !FZ_PLOTTERS_G | |
| 2263 fallback:{} | |
| 2264 #endif /* FZ_PLOTTERS_G */ | |
| 2265 #if FZ_PLOTTERS_N | |
| 2266 if (da) | |
| 2267 if (sa) | |
| 2268 { | |
| 2269 if (alpha == 255) | |
| 2270 return paint_span_N_da_sa; | |
| 2271 else if (alpha > 0) | |
| 2272 return paint_span_N_da_sa_alpha; | |
| 2273 } | |
| 2274 else | |
| 2275 { | |
| 2276 if (alpha == 255) | |
| 2277 return paint_span_N_da; | |
| 2278 else if (alpha > 0) | |
| 2279 return paint_span_N_da_alpha; | |
| 2280 } | |
| 2281 else | |
| 2282 if (sa) | |
| 2283 { | |
| 2284 if (alpha == 255) | |
| 2285 return paint_span_N_sa; | |
| 2286 else if (alpha > 0) | |
| 2287 return paint_span_N_sa_alpha; | |
| 2288 } | |
| 2289 else | |
| 2290 { | |
| 2291 if (alpha == 255) | |
| 2292 return paint_span_N; | |
| 2293 else if (alpha > 0) | |
| 2294 return paint_span_N_alpha; | |
| 2295 } | |
| 2296 #endif /* FZ_PLOTTERS_N */ | |
| 2297 break; | |
| 2298 } | |
| 2299 } | |
| 2300 return NULL; | |
| 2301 } | |
| 2302 | |
| 2303 /* | |
| 2304 * Pixmap blending functions | |
| 2305 */ | |
| 2306 | |
| 2307 void | |
| 2308 fz_paint_pixmap_with_bbox(fz_pixmap * FZ_RESTRICT dst, const fz_pixmap * FZ_RESTRICT src, int alpha, fz_irect bbox) | |
| 2309 { | |
| 2310 const unsigned char *sp; | |
| 2311 unsigned char *dp; | |
| 2312 int x, y, w, h, n, da, sa; | |
| 2313 fz_span_painter_t *fn; | |
| 2314 | |
| 2315 assert(dst->n - dst->alpha == src->n - src->alpha); | |
| 2316 | |
| 2317 if (alpha == 0) | |
| 2318 return; | |
| 2319 | |
| 2320 bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(dst)); | |
| 2321 bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(src)); | |
| 2322 | |
| 2323 x = bbox.x0; | |
| 2324 y = bbox.y0; | |
| 2325 w = fz_irect_width(bbox); | |
| 2326 h = fz_irect_height(bbox); | |
| 2327 if (w == 0 || h == 0) | |
| 2328 return; | |
| 2329 | |
| 2330 n = src->n; | |
| 2331 sp = src->samples + (y - src->y) * (size_t)src->stride + (x - src->x) * (size_t)src->n; | |
| 2332 sa = src->alpha; | |
| 2333 dp = dst->samples + (y - dst->y) * (size_t)dst->stride + (x - dst->x) * (size_t)dst->n; | |
| 2334 da = dst->alpha; | |
| 2335 | |
| 2336 n -= sa; | |
| 2337 fn = fz_get_span_painter(da, sa, n, alpha, 0); | |
| 2338 if (fn == NULL) | |
| 2339 return; | |
| 2340 | |
| 2341 while (h--) | |
| 2342 { | |
| 2343 (*fn)(dp, da, sp, sa, n, w, alpha, 0); | |
| 2344 sp += src->stride; | |
| 2345 dp += dst->stride; | |
| 2346 } | |
| 2347 } | |
| 2348 | |
| 2349 void | |
| 2350 fz_paint_pixmap(fz_pixmap * FZ_RESTRICT dst, const fz_pixmap * FZ_RESTRICT src, int alpha) | |
| 2351 { | |
| 2352 const unsigned char *sp; | |
| 2353 unsigned char *dp; | |
| 2354 fz_irect bbox; | |
| 2355 int x, y, w, h, n, da, sa; | |
| 2356 fz_span_painter_t *fn; | |
| 2357 | |
| 2358 if (alpha == 0) | |
| 2359 return; | |
| 2360 | |
| 2361 if (dst->n - dst->alpha != src->n - src->alpha) | |
| 2362 { | |
| 2363 // fprintf(stderr, "fz_paint_pixmap - FIXME\n"); | |
| 2364 return; | |
| 2365 } | |
| 2366 assert(dst->n - dst->alpha == src->n - src->alpha); | |
| 2367 | |
| 2368 bbox = fz_intersect_irect(fz_pixmap_bbox_no_ctx(src), fz_pixmap_bbox_no_ctx(dst)); | |
| 2369 x = bbox.x0; | |
| 2370 y = bbox.y0; | |
| 2371 w = fz_irect_width(bbox); | |
| 2372 h = fz_irect_height(bbox); | |
| 2373 if (w == 0 || h == 0) | |
| 2374 return; | |
| 2375 | |
| 2376 n = src->n; | |
| 2377 sp = src->samples + (y - src->y) * (size_t)src->stride + (x - src->x) * (size_t)src->n; | |
| 2378 sa = src->alpha; | |
| 2379 dp = dst->samples + (y - dst->y) * (size_t)dst->stride + (x - dst->x) * (size_t)dst->n; | |
| 2380 da = dst->alpha; | |
| 2381 | |
| 2382 n -= sa; | |
| 2383 fn = fz_get_span_painter(da, sa, n, alpha, 0); | |
| 2384 if (fn == NULL) | |
| 2385 return; | |
| 2386 | |
| 2387 while (h--) | |
| 2388 { | |
| 2389 (*fn)(dp, da, sp, sa, n, w, alpha, 0); | |
| 2390 sp += src->stride; | |
| 2391 dp += dst->stride; | |
| 2392 } | |
| 2393 } | |
| 2394 | |
| 2395 static fz_forceinline void | |
| 2396 paint_span_alpha_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, int n, int w) | |
| 2397 { | |
| 2398 TRACK_FN(); | |
| 2399 sp += n-1; | |
| 2400 do | |
| 2401 { | |
| 2402 int s = *sp; | |
| 2403 int t = FZ_EXPAND(255 - s); | |
| 2404 sp += n; | |
| 2405 *dp = s + FZ_COMBINE(*dp, t); | |
| 2406 dp ++; | |
| 2407 } | |
| 2408 while (--w); | |
| 2409 } | |
| 2410 | |
| 2411 static fz_forceinline void | |
| 2412 paint_span_alpha_not_solid(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, int n, int w, int alpha) | |
| 2413 { | |
| 2414 TRACK_FN(); | |
| 2415 sp += n-1; | |
| 2416 alpha = FZ_EXPAND(alpha); | |
| 2417 do | |
| 2418 { | |
| 2419 int masa = FZ_COMBINE(sp[0], alpha); | |
| 2420 sp += n; | |
| 2421 *dp = FZ_BLEND(*sp, *dp, masa); | |
| 2422 dp++; | |
| 2423 } | |
| 2424 while (--w); | |
| 2425 } | |
| 2426 | |
| 2427 void | |
| 2428 fz_paint_pixmap_alpha(fz_pixmap * FZ_RESTRICT dst, const fz_pixmap * FZ_RESTRICT src, int alpha) | |
| 2429 { | |
| 2430 const unsigned char *sp; | |
| 2431 unsigned char *dp; | |
| 2432 fz_irect bbox; | |
| 2433 int x, y, w, h, n; | |
| 2434 | |
| 2435 if (alpha == 0) | |
| 2436 return; | |
| 2437 | |
| 2438 assert(dst->n == 1 && dst->alpha == 1 && src->n >= 1 && src->alpha == 1); | |
| 2439 | |
| 2440 bbox = fz_intersect_irect(fz_pixmap_bbox_no_ctx(src), fz_pixmap_bbox_no_ctx(dst)); | |
| 2441 x = bbox.x0; | |
| 2442 y = bbox.y0; | |
| 2443 w = fz_irect_width(bbox); | |
| 2444 h = fz_irect_height(bbox); | |
| 2445 if (w == 0 || h == 0) | |
| 2446 return; | |
| 2447 | |
| 2448 n = src->n; | |
| 2449 sp = src->samples + (y - src->y) * (size_t)src->stride + (x - src->x) * (size_t)src->n; | |
| 2450 dp = dst->samples + (y - dst->y) * (size_t)dst->stride + (x - dst->x) * (size_t)dst->n; | |
| 2451 | |
| 2452 if (alpha == 255) | |
| 2453 { | |
| 2454 while (h--) | |
| 2455 { | |
| 2456 paint_span_alpha_solid(dp, sp, n, w); | |
| 2457 sp += src->stride; | |
| 2458 dp += dst->stride; | |
| 2459 } | |
| 2460 } | |
| 2461 else | |
| 2462 { | |
| 2463 while (h--) | |
| 2464 { | |
| 2465 paint_span_alpha_not_solid(dp, sp, n, w, alpha); | |
| 2466 sp += src->stride; | |
| 2467 dp += dst->stride; | |
| 2468 } | |
| 2469 } | |
| 2470 } | |
| 2471 | |
| 2472 void | |
| 2473 fz_paint_pixmap_with_overprint(fz_pixmap * FZ_RESTRICT dst, const fz_pixmap * FZ_RESTRICT src, const fz_overprint * FZ_RESTRICT eop) | |
| 2474 { | |
| 2475 const unsigned char *sp; | |
| 2476 unsigned char *dp; | |
| 2477 fz_irect bbox; | |
| 2478 int x, y, w, h, n, da, sa; | |
| 2479 fz_span_painter_t *fn; | |
| 2480 | |
| 2481 if (dst->n - dst->alpha != src->n - src->alpha) | |
| 2482 { | |
| 2483 // fprintf(stderr, "fz_paint_pixmap_with_overprint - FIXME\n"); | |
| 2484 return; | |
| 2485 } | |
| 2486 assert(dst->n - dst->alpha == src->n - src->alpha); | |
| 2487 | |
| 2488 bbox = fz_intersect_irect(fz_pixmap_bbox_no_ctx(src), fz_pixmap_bbox_no_ctx(dst)); | |
| 2489 x = bbox.x0; | |
| 2490 y = bbox.y0; | |
| 2491 w = fz_irect_width(bbox); | |
| 2492 h = fz_irect_height(bbox); | |
| 2493 if (w == 0 || h == 0) | |
| 2494 return; | |
| 2495 | |
| 2496 n = src->n; | |
| 2497 sp = src->samples + (y - src->y) * (size_t)src->stride + (x - src->x) * (size_t)src->n; | |
| 2498 sa = src->alpha; | |
| 2499 dp = dst->samples + (y - dst->y) * (size_t)dst->stride + (x - dst->x) * (size_t)dst->n; | |
| 2500 da = dst->alpha; | |
| 2501 | |
| 2502 n -= sa; | |
| 2503 fn = fz_get_span_painter(da, sa, n, 255, eop); | |
| 2504 if (fn == NULL) | |
| 2505 return; | |
| 2506 | |
| 2507 while (h--) | |
| 2508 { | |
| 2509 (*fn)(dp, da, sp, sa, n, w, 255, eop); | |
| 2510 sp += src->stride; | |
| 2511 dp += dst->stride; | |
| 2512 } | |
| 2513 } | |
| 2514 | |
| 2515 void | |
| 2516 fz_paint_pixmap_with_mask(fz_pixmap * FZ_RESTRICT dst, const fz_pixmap * FZ_RESTRICT src, const fz_pixmap * FZ_RESTRICT msk) | |
| 2517 { | |
| 2518 const unsigned char *sp, *mp; | |
| 2519 unsigned char *dp; | |
| 2520 fz_irect bbox; | |
| 2521 int x, y, w, h, n, sa, da; | |
| 2522 fz_span_mask_painter_t *fn; | |
| 2523 | |
| 2524 assert(dst->n == src->n); | |
| 2525 assert(msk->n == 1); | |
| 2526 | |
| 2527 bbox = fz_pixmap_bbox_no_ctx(dst); | |
| 2528 bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(src)); | |
| 2529 bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(msk)); | |
| 2530 | |
| 2531 x = bbox.x0; | |
| 2532 y = bbox.y0; | |
| 2533 w = fz_irect_width(bbox); | |
| 2534 h = fz_irect_height(bbox); | |
| 2535 if (w == 0 || h == 0) | |
| 2536 return; | |
| 2537 | |
| 2538 n = src->n; | |
| 2539 sp = src->samples + (y - src->y) * (size_t)src->stride + (x - src->x) * (size_t)src->n; | |
| 2540 sa = src->alpha; | |
| 2541 mp = msk->samples + (y - msk->y) * (size_t)msk->stride + (x - msk->x) * (size_t)msk->n; | |
| 2542 dp = dst->samples + (y - dst->y) * (size_t)dst->stride + (x - dst->x) * (size_t)dst->n; | |
| 2543 da = dst->alpha; | |
| 2544 | |
| 2545 /* sa == da, or something has gone very wrong! */ | |
| 2546 assert(sa == da); | |
| 2547 | |
| 2548 n -= sa; | |
| 2549 fn = fz_get_span_mask_painter(da, n); | |
| 2550 if (fn == NULL) | |
| 2551 return; | |
| 2552 | |
| 2553 while (h--) | |
| 2554 { | |
| 2555 (*fn)(dp, sp, mp, w, n, sa, NULL); | |
| 2556 sp += src->stride; | |
| 2557 dp += dst->stride; | |
| 2558 mp += msk->stride; | |
| 2559 } | |
| 2560 } | |
| 2561 | |
| 2562 static fz_forceinline void | |
| 2563 paint_over_span_with_mask(byte * FZ_RESTRICT dp, const byte * FZ_RESTRICT sp, const byte * FZ_RESTRICT mp, int w) | |
| 2564 { | |
| 2565 do | |
| 2566 { | |
| 2567 int ma = *mp++; | |
| 2568 ma = FZ_EXPAND(ma); | |
| 2569 if (ma == 0 || *sp == 0) | |
| 2570 { | |
| 2571 dp++; | |
| 2572 sp++; | |
| 2573 } | |
| 2574 else | |
| 2575 { | |
| 2576 int a = *sp++; | |
| 2577 if (ma != 256) | |
| 2578 a = fz_mul255(ma, a); | |
| 2579 *dp = 255 - fz_mul255(255 - a, 255 - *dp); | |
| 2580 dp++; | |
| 2581 } | |
| 2582 } | |
| 2583 while (--w); | |
| 2584 } | |
| 2585 | |
| 2586 void | |
| 2587 fz_paint_over_pixmap_with_mask(fz_pixmap * FZ_RESTRICT dst, const fz_pixmap * FZ_RESTRICT src, const fz_pixmap * FZ_RESTRICT msk) | |
| 2588 { | |
| 2589 const unsigned char *sp, *mp; | |
| 2590 unsigned char *dp; | |
| 2591 fz_irect bbox; | |
| 2592 int x, y, w, h; | |
| 2593 | |
| 2594 assert(dst->n == src->n); | |
| 2595 assert(msk->n == 1); | |
| 2596 | |
| 2597 bbox = fz_pixmap_bbox_no_ctx(dst); | |
| 2598 bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(src)); | |
| 2599 bbox = fz_intersect_irect(bbox, fz_pixmap_bbox_no_ctx(msk)); | |
| 2600 | |
| 2601 x = bbox.x0; | |
| 2602 y = bbox.y0; | |
| 2603 w = fz_irect_width(bbox); | |
| 2604 h = fz_irect_height(bbox); | |
| 2605 if (w == 0 || h == 0) | |
| 2606 return; | |
| 2607 | |
| 2608 /* sa == da, or something has gone very wrong! */ | |
| 2609 assert(src->alpha == dst->alpha && dst->alpha == 1 && src->n == 1); | |
| 2610 sp = src->samples + (y - src->y) * (size_t)src->stride + (size_t)(x - src->x); | |
| 2611 mp = msk->samples + (y - msk->y) * (size_t)msk->stride + (size_t)(x - msk->x); | |
| 2612 dp = dst->samples + (y - dst->y) * (size_t)dst->stride + (size_t)(x - dst->x); | |
| 2613 | |
| 2614 | |
| 2615 while (h--) | |
| 2616 { | |
| 2617 paint_over_span_with_mask(dp, sp, mp, w); | |
| 2618 sp += src->stride; | |
| 2619 dp += dst->stride; | |
| 2620 mp += msk->stride; | |
| 2621 } | |
| 2622 } | |
| 2623 | |
| 2624 static inline void | |
| 2625 fz_paint_glyph_mask(int span, unsigned char *dp, int da, const fz_glyph *glyph, int w, int h, int skip_x, int skip_y) | |
| 2626 { | |
| 2627 while (h--) | |
| 2628 { | |
| 2629 int skip_xx, ww, len, extend; | |
| 2630 const unsigned char *runp; | |
| 2631 unsigned char *ddp = dp; | |
| 2632 int offset = ((const int *)(glyph->data))[skip_y++]; | |
| 2633 if (offset >= 0) | |
| 2634 { | |
| 2635 int eol = 0; | |
| 2636 runp = &glyph->data[offset]; | |
| 2637 extend = 0; | |
| 2638 ww = w; | |
| 2639 skip_xx = skip_x; | |
| 2640 while (skip_xx) | |
| 2641 { | |
| 2642 int v = *runp++; | |
| 2643 switch (v & 3) | |
| 2644 { | |
| 2645 case 0: /* Extend */ | |
| 2646 extend = v>>2; | |
| 2647 len = 0; | |
| 2648 break; | |
| 2649 case 1: /* Transparent */ | |
| 2650 len = (v>>2) + 1 + (extend<<6); | |
| 2651 extend = 0; | |
| 2652 if (len > skip_xx) | |
| 2653 { | |
| 2654 len -= skip_xx; | |
| 2655 goto transparent_run; | |
| 2656 } | |
| 2657 break; | |
| 2658 case 2: /* Solid */ | |
| 2659 eol = v & 4; | |
| 2660 len = (v>>3) + 1 + (extend<<5); | |
| 2661 extend = 0; | |
| 2662 if (len > skip_xx) | |
| 2663 { | |
| 2664 len -= skip_xx; | |
| 2665 goto solid_run; | |
| 2666 } | |
| 2667 break; | |
| 2668 default: /* Intermediate */ | |
| 2669 eol = v & 4; | |
| 2670 len = (v>>3) + 1 + (extend<<5); | |
| 2671 extend = 0; | |
| 2672 if (len > skip_xx) | |
| 2673 { | |
| 2674 runp += skip_xx; | |
| 2675 len -= skip_xx; | |
| 2676 goto intermediate_run; | |
| 2677 } | |
| 2678 runp += len; | |
| 2679 break; | |
| 2680 } | |
| 2681 if (eol) | |
| 2682 { | |
| 2683 ww = 0; | |
| 2684 break; | |
| 2685 } | |
| 2686 skip_xx -= len; | |
| 2687 } | |
| 2688 while (ww > 0) | |
| 2689 { | |
| 2690 int v = *runp++; | |
| 2691 switch(v & 3) | |
| 2692 { | |
| 2693 case 0: /* Extend */ | |
| 2694 extend = v>>2; | |
| 2695 break; | |
| 2696 case 1: /* Transparent */ | |
| 2697 len = (v>>2) + 1 + (extend<<6); | |
| 2698 extend = 0; | |
| 2699 transparent_run: | |
| 2700 if (len > ww) | |
| 2701 len = ww; | |
| 2702 ww -= len; | |
| 2703 ddp += len; | |
| 2704 break; | |
| 2705 case 2: /* Solid */ | |
| 2706 eol = v & 4; | |
| 2707 len = (v>>3) + 1 + (extend<<5); | |
| 2708 extend = 0; | |
| 2709 solid_run: | |
| 2710 if (len > ww) | |
| 2711 len = ww; | |
| 2712 ww -= len; | |
| 2713 do | |
| 2714 { | |
| 2715 *ddp++ = 0xFF; | |
| 2716 } | |
| 2717 while (--len); | |
| 2718 break; | |
| 2719 default: /* Intermediate */ | |
| 2720 eol = v & 4; | |
| 2721 len = (v>>3) + 1 + (extend<<5); | |
| 2722 extend = 0; | |
| 2723 intermediate_run: | |
| 2724 if (len > ww) | |
| 2725 len = ww; | |
| 2726 ww -= len; | |
| 2727 do | |
| 2728 { | |
| 2729 int a = *runp++; | |
| 2730 v = *ddp; | |
| 2731 if (v == 0) | |
| 2732 { | |
| 2733 *ddp++ = a; | |
| 2734 } | |
| 2735 else | |
| 2736 { | |
| 2737 a = FZ_EXPAND(a); | |
| 2738 *ddp = FZ_BLEND(0xFF, v, a); | |
| 2739 ddp++; | |
| 2740 } | |
| 2741 } | |
| 2742 while (--len); | |
| 2743 break; | |
| 2744 } | |
| 2745 if (eol) | |
| 2746 break; | |
| 2747 } | |
| 2748 } | |
| 2749 dp += span; | |
| 2750 } | |
| 2751 } | |
| 2752 | |
| 2753 static inline void | |
| 2754 fz_paint_glyph_mask_alpha(int span, unsigned char *dp, int da, const fz_glyph *glyph, int w, int h, int skip_x, int skip_y, unsigned char alpha) | |
| 2755 { | |
| 2756 while (h--) | |
| 2757 { | |
| 2758 int skip_xx, ww, len, extend; | |
| 2759 const unsigned char *runp; | |
| 2760 unsigned char *ddp = dp; | |
| 2761 int offset = ((const int *)(glyph->data))[skip_y++]; | |
| 2762 if (offset >= 0) | |
| 2763 { | |
| 2764 int eol = 0; | |
| 2765 runp = &glyph->data[offset]; | |
| 2766 extend = 0; | |
| 2767 ww = w; | |
| 2768 skip_xx = skip_x; | |
| 2769 while (skip_xx) | |
| 2770 { | |
| 2771 int v = *runp++; | |
| 2772 switch (v & 3) | |
| 2773 { | |
| 2774 case 0: /* Extend */ | |
| 2775 extend = v>>2; | |
| 2776 len = 0; | |
| 2777 break; | |
| 2778 case 1: /* Transparent */ | |
| 2779 len = (v>>2) + 1 + (extend<<6); | |
| 2780 extend = 0; | |
| 2781 if (len > skip_xx) | |
| 2782 { | |
| 2783 len -= skip_xx; | |
| 2784 goto transparent_run; | |
| 2785 } | |
| 2786 break; | |
| 2787 case 2: /* Solid */ | |
| 2788 eol = v & 4; | |
| 2789 len = (v>>3) + 1 + (extend<<5); | |
| 2790 extend = 0; | |
| 2791 if (len > skip_xx) | |
| 2792 { | |
| 2793 len -= skip_xx; | |
| 2794 goto solid_run; | |
| 2795 } | |
| 2796 break; | |
| 2797 default: /* Intermediate */ | |
| 2798 eol = v & 4; | |
| 2799 len = (v>>3) + 1 + (extend<<5); | |
| 2800 extend = 0; | |
| 2801 if (len > skip_xx) | |
| 2802 { | |
| 2803 runp += skip_xx; | |
| 2804 len -= skip_xx; | |
| 2805 goto intermediate_run; | |
| 2806 } | |
| 2807 runp += len; | |
| 2808 break; | |
| 2809 } | |
| 2810 if (eol) | |
| 2811 { | |
| 2812 ww = 0; | |
| 2813 break; | |
| 2814 } | |
| 2815 skip_xx -= len; | |
| 2816 } | |
| 2817 while (ww > 0) | |
| 2818 { | |
| 2819 int v = *runp++; | |
| 2820 switch(v & 3) | |
| 2821 { | |
| 2822 case 0: /* Extend */ | |
| 2823 extend = v>>2; | |
| 2824 break; | |
| 2825 case 1: /* Transparent */ | |
| 2826 len = (v>>2) + 1 + (extend<<6); | |
| 2827 extend = 0; | |
| 2828 transparent_run: | |
| 2829 if (len > ww) | |
| 2830 len = ww; | |
| 2831 ww -= len; | |
| 2832 ddp += len; | |
| 2833 break; | |
| 2834 case 2: /* Solid */ | |
| 2835 eol = v & 4; | |
| 2836 len = (v>>3) + 1 + (extend<<5); | |
| 2837 extend = 0; | |
| 2838 solid_run: | |
| 2839 if (len > ww) | |
| 2840 len = ww; | |
| 2841 ww -= len; | |
| 2842 do | |
| 2843 { | |
| 2844 *ddp++ = alpha; | |
| 2845 } | |
| 2846 while (--len); | |
| 2847 break; | |
| 2848 default: /* Intermediate */ | |
| 2849 eol = v & 4; | |
| 2850 len = (v>>3) + 1 + (extend<<5); | |
| 2851 extend = 0; | |
| 2852 intermediate_run: | |
| 2853 if (len > ww) | |
| 2854 len = ww; | |
| 2855 ww -= len; | |
| 2856 do | |
| 2857 { | |
| 2858 int a = *runp++; | |
| 2859 v = *ddp; | |
| 2860 if (v == 0) | |
| 2861 { | |
| 2862 *ddp++ = fz_mul255(a, alpha); | |
| 2863 } | |
| 2864 else | |
| 2865 { | |
| 2866 a = FZ_EXPAND(a); | |
| 2867 *ddp = FZ_BLEND(alpha, v, a); | |
| 2868 ddp++; | |
| 2869 } | |
| 2870 } | |
| 2871 while (--len); | |
| 2872 break; | |
| 2873 } | |
| 2874 if (eol) | |
| 2875 break; | |
| 2876 } | |
| 2877 } | |
| 2878 dp += span; | |
| 2879 } | |
| 2880 } | |
| 2881 | |
| 2882 #define N 1 | |
| 2883 #include "paint-glyph.h" | |
| 2884 | |
| 2885 #define ALPHA | |
| 2886 #define N 1 | |
| 2887 #include "paint-glyph.h" | |
| 2888 | |
| 2889 #if FZ_PLOTTERS_G | |
| 2890 #define DA | |
| 2891 #define N 1 | |
| 2892 #include "paint-glyph.h" | |
| 2893 | |
| 2894 #define DA | |
| 2895 #define ALPHA | |
| 2896 #define N 1 | |
| 2897 #include "paint-glyph.h" | |
| 2898 #endif /* FZ_PLOTTERS_G */ | |
| 2899 | |
| 2900 #if FZ_PLOTTERS_RGB | |
| 2901 #define DA | |
| 2902 #define N 3 | |
| 2903 #include "paint-glyph.h" | |
| 2904 | |
| 2905 #define DA | |
| 2906 #define ALPHA | |
| 2907 #define N 3 | |
| 2908 #include "paint-glyph.h" | |
| 2909 | |
| 2910 #define N 3 | |
| 2911 #include "paint-glyph.h" | |
| 2912 | |
| 2913 #define ALPHA | |
| 2914 #define N 3 | |
| 2915 #include "paint-glyph.h" | |
| 2916 #endif /* FZ_PLOTTERS_RGB */ | |
| 2917 | |
| 2918 #if FZ_PLOTTERS_CMYK | |
| 2919 #define DA | |
| 2920 #define N 4 | |
| 2921 #include "paint-glyph.h" | |
| 2922 | |
| 2923 #define DA | |
| 2924 #define ALPHA | |
| 2925 #define N 4 | |
| 2926 #include "paint-glyph.h" | |
| 2927 | |
| 2928 #define ALPHA | |
| 2929 #define N 4 | |
| 2930 #include "paint-glyph.h" | |
| 2931 | |
| 2932 #define N 4 | |
| 2933 #include "paint-glyph.h" | |
| 2934 #endif /* FZ_PLOTTERS_CMYK */ | |
| 2935 | |
| 2936 #if FZ_PLOTTERS_N | |
| 2937 #define ALPHA | |
| 2938 #include "paint-glyph.h" | |
| 2939 | |
| 2940 #define DA | |
| 2941 #include "paint-glyph.h" | |
| 2942 | |
| 2943 #define DA | |
| 2944 #define ALPHA | |
| 2945 #include "paint-glyph.h" | |
| 2946 | |
| 2947 #include "paint-glyph.h" | |
| 2948 #endif /* FZ_PLOTTERS_N */ | |
| 2949 | |
| 2950 #if FZ_ENABLE_SPOT_RENDERING | |
| 2951 #define ALPHA | |
| 2952 #define EOP | |
| 2953 #include "paint-glyph.h" | |
| 2954 | |
| 2955 #define DA | |
| 2956 #define EOP | |
| 2957 #include "paint-glyph.h" | |
| 2958 | |
| 2959 #define DA | |
| 2960 #define ALPHA | |
| 2961 #define EOP | |
| 2962 #include "paint-glyph.h" | |
| 2963 | |
| 2964 #define EOP | |
| 2965 #include "paint-glyph.h" | |
| 2966 #endif /* FZ_ENABLE_SPOT_RENDERING */ | |
| 2967 | |
| 2968 static void | |
| 2969 fz_paint_glyph_alpha(const unsigned char * FZ_RESTRICT colorbv, int n, int span, unsigned char * FZ_RESTRICT dp, int da, const fz_glyph *glyph, int w, int h, int skip_x, int skip_y, const fz_overprint * FZ_RESTRICT eop) | |
| 2970 { | |
| 2971 #if FZ_ENABLE_SPOT_RENDERING | |
| 2972 if (fz_overprint_required(eop)) | |
| 2973 { | |
| 2974 if (da) | |
| 2975 fz_paint_glyph_alpha_N_da_op(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y, eop); | |
| 2976 else | |
| 2977 fz_paint_glyph_alpha_N_op(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y, eop); | |
| 2978 return; | |
| 2979 } | |
| 2980 #endif /* FZ_ENABLE_SPOT_RENDERING */ | |
| 2981 switch (n) | |
| 2982 { | |
| 2983 case 1: | |
| 2984 if (da) | |
| 2985 #if FZ_PLOTTERS_G | |
| 2986 fz_paint_glyph_alpha_1_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y); | |
| 2987 #else | |
| 2988 goto fallback; | |
| 2989 #endif /* FZ_PLOTTERS_G */ | |
| 2990 else | |
| 2991 fz_paint_glyph_alpha_1(colorbv, span, dp, glyph, w, h, skip_x, skip_y); | |
| 2992 break; | |
| 2993 #if FZ_PLOTTERS_RGB | |
| 2994 case 3: | |
| 2995 if (da) | |
| 2996 fz_paint_glyph_alpha_3_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y); | |
| 2997 else | |
| 2998 fz_paint_glyph_alpha_3(colorbv, span, dp, glyph, w, h, skip_x, skip_y); | |
| 2999 break; | |
| 3000 #endif /* FZ_PLOTTERS_RGB */ | |
| 3001 #if FZ_PLOTTERS_CMYK | |
| 3002 case 4: | |
| 3003 if (da) | |
| 3004 fz_paint_glyph_alpha_4_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y); | |
| 3005 else | |
| 3006 fz_paint_glyph_alpha_4(colorbv, span, dp, glyph, w, h, skip_x, skip_y); | |
| 3007 break; | |
| 3008 #endif /* FZ_PLOTTERS_CMYK */ | |
| 3009 default: | |
| 3010 { | |
| 3011 #if !FZ_PLOTTERS_G | |
| 3012 fallback:{} | |
| 3013 #endif /* !FZ_PLOTTERS_G */ | |
| 3014 #if FZ_PLOTTERS_N | |
| 3015 if (da) | |
| 3016 fz_paint_glyph_alpha_N_da(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y); | |
| 3017 else | |
| 3018 fz_paint_glyph_alpha_N(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y); | |
| 3019 #endif /* FZ_PLOTTERS_N */ | |
| 3020 break; | |
| 3021 } | |
| 3022 } | |
| 3023 } | |
| 3024 | |
| 3025 static void | |
| 3026 fz_paint_glyph_solid(const unsigned char * FZ_RESTRICT colorbv, int n, int span, unsigned char * FZ_RESTRICT dp, int da, const fz_glyph * FZ_RESTRICT glyph, int w, int h, int skip_x, int skip_y, const fz_overprint * FZ_RESTRICT eop) | |
| 3027 { | |
| 3028 #if FZ_ENABLE_SPOT_RENDERING | |
| 3029 if (fz_overprint_required(eop)) | |
| 3030 { | |
| 3031 if (da) | |
| 3032 fz_paint_glyph_solid_N_da_op(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y, eop); | |
| 3033 else | |
| 3034 fz_paint_glyph_solid_N_op(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y, eop); | |
| 3035 return; | |
| 3036 } | |
| 3037 #endif /* FZ_ENABLE_SPOT_RENDERING */ | |
| 3038 switch (n) | |
| 3039 { | |
| 3040 case 1: | |
| 3041 if (da) | |
| 3042 #if FZ_PLOTTERS_G | |
| 3043 fz_paint_glyph_solid_1_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y); | |
| 3044 #else | |
| 3045 goto fallback; | |
| 3046 #endif /* FZ_PLOTTERS_G */ | |
| 3047 else | |
| 3048 fz_paint_glyph_solid_1(colorbv, span, dp, glyph, w, h, skip_x, skip_y); | |
| 3049 break; | |
| 3050 #if FZ_PLOTTERS_RGB | |
| 3051 case 3: | |
| 3052 if (da) | |
| 3053 fz_paint_glyph_solid_3_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y); | |
| 3054 else | |
| 3055 fz_paint_glyph_solid_3(colorbv, span, dp, glyph, w, h, skip_x, skip_y); | |
| 3056 break; | |
| 3057 #endif /* FZ_PLOTTERS_RGB */ | |
| 3058 #if FZ_PLOTTERS_CMYK | |
| 3059 case 4: | |
| 3060 if (da) | |
| 3061 fz_paint_glyph_solid_4_da(colorbv, span, dp, glyph, w, h, skip_x, skip_y); | |
| 3062 else | |
| 3063 fz_paint_glyph_solid_4(colorbv, span, dp, glyph, w, h, skip_x, skip_y); | |
| 3064 break; | |
| 3065 #endif /* FZ_PLOTTERS_CMYK */ | |
| 3066 default: | |
| 3067 { | |
| 3068 #if !FZ_PLOTTERS_G | |
| 3069 fallback:{} | |
| 3070 #endif /* FZ_PLOTTERS_G */ | |
| 3071 #if FZ_PLOTTERS_N | |
| 3072 if (da) | |
| 3073 fz_paint_glyph_solid_N_da(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y); | |
| 3074 else | |
| 3075 fz_paint_glyph_solid_N(colorbv, n, span, dp, glyph, w, h, skip_x, skip_y); | |
| 3076 break; | |
| 3077 #endif /* FZ_PLOTTERS_N */ | |
| 3078 } | |
| 3079 } | |
| 3080 } | |
| 3081 | |
| 3082 void | |
| 3083 fz_paint_glyph(const unsigned char * FZ_RESTRICT colorbv, fz_pixmap * FZ_RESTRICT dst, unsigned char * FZ_RESTRICT dp, const fz_glyph * FZ_RESTRICT glyph, int w, int h, int skip_x, int skip_y, const fz_overprint * FZ_RESTRICT eop) | |
| 3084 { | |
| 3085 int n = dst->n - dst->alpha; | |
| 3086 if (dst->colorspace) | |
| 3087 { | |
| 3088 assert(n > 0); | |
| 3089 if (colorbv[n] == 255) | |
| 3090 fz_paint_glyph_solid(colorbv, n, dst->stride, dp, dst->alpha, glyph, w, h, skip_x, skip_y, eop); | |
| 3091 else if (colorbv[n] != 0) | |
| 3092 fz_paint_glyph_alpha(colorbv, n, dst->stride, dp, dst->alpha, glyph, w, h, skip_x, skip_y, eop); | |
| 3093 } | |
| 3094 else | |
| 3095 { | |
| 3096 assert(dst->alpha && dst->n == 1 && dst->colorspace == NULL && !fz_overprint_required(eop)); | |
| 3097 if (colorbv == NULL || colorbv[0] == 255) | |
| 3098 fz_paint_glyph_mask(dst->stride, dp, dst->alpha, glyph, w, h, skip_x, skip_y); | |
| 3099 else | |
| 3100 fz_paint_glyph_mask_alpha(dst->stride, dp, dst->alpha, glyph, w, h, skip_x, skip_y, colorbv[0]); | |
| 3101 } | |
| 3102 } |
