|
1 /* |
|
2 * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. |
|
3 * 2005 Lars Knoll & Zack Rusin, Trolltech |
|
4 * |
|
5 * Permission to use, copy, modify, distribute, and sell this software and its |
|
6 * documentation for any purpose is hereby granted without fee, provided that |
|
7 * the above copyright notice appear in all copies and that both that |
|
8 * copyright notice and this permission notice appear in supporting |
|
9 * documentation, and that the name of Keith Packard not be used in |
|
10 * advertising or publicity pertaining to distribution of the software without |
|
11 * specific, written prior permission. Keith Packard makes no |
|
12 * representations about the suitability of this software for any purpose. It |
|
13 * is provided "as is" without express or implied warranty. |
|
14 * |
|
15 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS |
|
16 * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND |
|
17 * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY |
|
18 * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
|
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN |
|
20 * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING |
|
21 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS |
|
22 * SOFTWARE. |
|
23 */ |
|
24 #ifdef HAVE_CONFIG_H |
|
25 #include <config.h> |
|
26 #endif |
|
27 |
|
28 #include <math.h> |
|
29 #include <string.h> |
|
30 |
|
31 #include "pixman-private.h" |
|
32 #include "pixman-combine32.h" |
|
33 |
|
34 /* component alpha helper functions */ |
|
35 |
|
36 static void |
|
37 combine_mask_ca (uint32_t *src, uint32_t *mask) |
|
38 { |
|
39 uint32_t a = *mask; |
|
40 |
|
41 uint32_t x; |
|
42 uint16_t xa; |
|
43 |
|
44 if (!a) |
|
45 { |
|
46 *(src) = 0; |
|
47 return; |
|
48 } |
|
49 |
|
50 x = *(src); |
|
51 if (a == ~0) |
|
52 { |
|
53 x = x >> A_SHIFT; |
|
54 x |= x << G_SHIFT; |
|
55 x |= x << R_SHIFT; |
|
56 *(mask) = x; |
|
57 return; |
|
58 } |
|
59 |
|
60 xa = x >> A_SHIFT; |
|
61 UN8x4_MUL_UN8x4 (x, a); |
|
62 *(src) = x; |
|
63 |
|
64 UN8x4_MUL_UN8 (a, xa); |
|
65 *(mask) = a; |
|
66 } |
|
67 |
|
68 static void |
|
69 combine_mask_value_ca (uint32_t *src, const uint32_t *mask) |
|
70 { |
|
71 uint32_t a = *mask; |
|
72 uint32_t x; |
|
73 |
|
74 if (!a) |
|
75 { |
|
76 *(src) = 0; |
|
77 return; |
|
78 } |
|
79 |
|
80 if (a == ~0) |
|
81 return; |
|
82 |
|
83 x = *(src); |
|
84 UN8x4_MUL_UN8x4 (x, a); |
|
85 *(src) = x; |
|
86 } |
|
87 |
|
88 static void |
|
89 combine_mask_alpha_ca (const uint32_t *src, uint32_t *mask) |
|
90 { |
|
91 uint32_t a = *(mask); |
|
92 uint32_t x; |
|
93 |
|
94 if (!a) |
|
95 return; |
|
96 |
|
97 x = *(src) >> A_SHIFT; |
|
98 if (x == MASK) |
|
99 return; |
|
100 |
|
101 if (a == ~0) |
|
102 { |
|
103 x |= x << G_SHIFT; |
|
104 x |= x << R_SHIFT; |
|
105 *(mask) = x; |
|
106 return; |
|
107 } |
|
108 |
|
109 UN8x4_MUL_UN8 (a, x); |
|
110 *(mask) = a; |
|
111 } |
|
112 |
|
113 /* |
|
114 * There are two ways of handling alpha -- either as a single unified value or |
|
115 * a separate value for each component, hence each macro must have two |
|
116 * versions. The unified alpha version has a 'u' at the end of the name, |
|
117 * the component version has a 'ca'. Similarly, functions which deal with |
|
118 * this difference will have two versions using the same convention. |
|
119 */ |
|
120 |
|
121 static force_inline uint32_t |
|
122 combine_mask (const uint32_t *src, const uint32_t *mask, int i) |
|
123 { |
|
124 uint32_t s, m; |
|
125 |
|
126 if (mask) |
|
127 { |
|
128 m = *(mask + i) >> A_SHIFT; |
|
129 |
|
130 if (!m) |
|
131 return 0; |
|
132 } |
|
133 |
|
134 s = *(src + i); |
|
135 |
|
136 if (mask) |
|
137 UN8x4_MUL_UN8 (s, m); |
|
138 |
|
139 return s; |
|
140 } |
|
141 |
|
142 static void |
|
143 combine_clear (pixman_implementation_t *imp, |
|
144 pixman_op_t op, |
|
145 uint32_t * dest, |
|
146 const uint32_t * src, |
|
147 const uint32_t * mask, |
|
148 int width) |
|
149 { |
|
150 memset (dest, 0, width * sizeof(uint32_t)); |
|
151 } |
|
152 |
|
153 static void |
|
154 combine_dst (pixman_implementation_t *imp, |
|
155 pixman_op_t op, |
|
156 uint32_t * dest, |
|
157 const uint32_t * src, |
|
158 const uint32_t * mask, |
|
159 int width) |
|
160 { |
|
161 return; |
|
162 } |
|
163 |
|
164 static void |
|
165 combine_src_u (pixman_implementation_t *imp, |
|
166 pixman_op_t op, |
|
167 uint32_t * dest, |
|
168 const uint32_t * src, |
|
169 const uint32_t * mask, |
|
170 int width) |
|
171 { |
|
172 int i; |
|
173 |
|
174 if (!mask) |
|
175 { |
|
176 memcpy (dest, src, width * sizeof (uint32_t)); |
|
177 } |
|
178 else |
|
179 { |
|
180 for (i = 0; i < width; ++i) |
|
181 { |
|
182 uint32_t s = combine_mask (src, mask, i); |
|
183 |
|
184 *(dest + i) = s; |
|
185 } |
|
186 } |
|
187 } |
|
188 |
|
189 static void |
|
190 combine_over_u (pixman_implementation_t *imp, |
|
191 pixman_op_t op, |
|
192 uint32_t * dest, |
|
193 const uint32_t * src, |
|
194 const uint32_t * mask, |
|
195 int width) |
|
196 { |
|
197 int i; |
|
198 |
|
199 if (!mask) |
|
200 { |
|
201 for (i = 0; i < width; ++i) |
|
202 { |
|
203 uint32_t s = *(src + i); |
|
204 uint32_t a = ALPHA_8 (s); |
|
205 if (a == 0xFF) |
|
206 { |
|
207 *(dest + i) = s; |
|
208 } |
|
209 else if (s) |
|
210 { |
|
211 uint32_t d = *(dest + i); |
|
212 uint32_t ia = a ^ 0xFF; |
|
213 UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, s); |
|
214 *(dest + i) = d; |
|
215 } |
|
216 } |
|
217 } |
|
218 else |
|
219 { |
|
220 for (i = 0; i < width; ++i) |
|
221 { |
|
222 uint32_t m = ALPHA_8 (*(mask + i)); |
|
223 if (m == 0xFF) |
|
224 { |
|
225 uint32_t s = *(src + i); |
|
226 uint32_t a = ALPHA_8 (s); |
|
227 if (a == 0xFF) |
|
228 { |
|
229 *(dest + i) = s; |
|
230 } |
|
231 else if (s) |
|
232 { |
|
233 uint32_t d = *(dest + i); |
|
234 uint32_t ia = a ^ 0xFF; |
|
235 UN8x4_MUL_UN8_ADD_UN8x4 (d, ia, s); |
|
236 *(dest + i) = d; |
|
237 } |
|
238 } |
|
239 else if (m) |
|
240 { |
|
241 uint32_t s = *(src + i); |
|
242 if (s) |
|
243 { |
|
244 uint32_t d = *(dest + i); |
|
245 UN8x4_MUL_UN8 (s, m); |
|
246 UN8x4_MUL_UN8_ADD_UN8x4 (d, ALPHA_8 (~s), s); |
|
247 *(dest + i) = d; |
|
248 } |
|
249 } |
|
250 } |
|
251 } |
|
252 } |
|
253 |
|
254 static void |
|
255 combine_over_reverse_u (pixman_implementation_t *imp, |
|
256 pixman_op_t op, |
|
257 uint32_t * dest, |
|
258 const uint32_t * src, |
|
259 const uint32_t * mask, |
|
260 int width) |
|
261 { |
|
262 int i; |
|
263 |
|
264 for (i = 0; i < width; ++i) |
|
265 { |
|
266 uint32_t s = combine_mask (src, mask, i); |
|
267 uint32_t d = *(dest + i); |
|
268 uint32_t ia = ALPHA_8 (~*(dest + i)); |
|
269 UN8x4_MUL_UN8_ADD_UN8x4 (s, ia, d); |
|
270 *(dest + i) = s; |
|
271 } |
|
272 } |
|
273 |
|
274 static void |
|
275 combine_in_u (pixman_implementation_t *imp, |
|
276 pixman_op_t op, |
|
277 uint32_t * dest, |
|
278 const uint32_t * src, |
|
279 const uint32_t * mask, |
|
280 int width) |
|
281 { |
|
282 int i; |
|
283 |
|
284 for (i = 0; i < width; ++i) |
|
285 { |
|
286 uint32_t s = combine_mask (src, mask, i); |
|
287 uint32_t a = ALPHA_8 (*(dest + i)); |
|
288 UN8x4_MUL_UN8 (s, a); |
|
289 *(dest + i) = s; |
|
290 } |
|
291 } |
|
292 |
|
293 static void |
|
294 combine_in_reverse_u (pixman_implementation_t *imp, |
|
295 pixman_op_t op, |
|
296 uint32_t * dest, |
|
297 const uint32_t * src, |
|
298 const uint32_t * mask, |
|
299 int width) |
|
300 { |
|
301 int i; |
|
302 |
|
303 for (i = 0; i < width; ++i) |
|
304 { |
|
305 uint32_t s = combine_mask (src, mask, i); |
|
306 uint32_t d = *(dest + i); |
|
307 uint32_t a = ALPHA_8 (s); |
|
308 UN8x4_MUL_UN8 (d, a); |
|
309 *(dest + i) = d; |
|
310 } |
|
311 } |
|
312 |
|
313 static void |
|
314 combine_out_u (pixman_implementation_t *imp, |
|
315 pixman_op_t op, |
|
316 uint32_t * dest, |
|
317 const uint32_t * src, |
|
318 const uint32_t * mask, |
|
319 int width) |
|
320 { |
|
321 int i; |
|
322 |
|
323 for (i = 0; i < width; ++i) |
|
324 { |
|
325 uint32_t s = combine_mask (src, mask, i); |
|
326 uint32_t a = ALPHA_8 (~*(dest + i)); |
|
327 UN8x4_MUL_UN8 (s, a); |
|
328 *(dest + i) = s; |
|
329 } |
|
330 } |
|
331 |
|
332 static void |
|
333 combine_out_reverse_u (pixman_implementation_t *imp, |
|
334 pixman_op_t op, |
|
335 uint32_t * dest, |
|
336 const uint32_t * src, |
|
337 const uint32_t * mask, |
|
338 int width) |
|
339 { |
|
340 int i; |
|
341 |
|
342 for (i = 0; i < width; ++i) |
|
343 { |
|
344 uint32_t s = combine_mask (src, mask, i); |
|
345 uint32_t d = *(dest + i); |
|
346 uint32_t a = ALPHA_8 (~s); |
|
347 UN8x4_MUL_UN8 (d, a); |
|
348 *(dest + i) = d; |
|
349 } |
|
350 } |
|
351 |
|
352 static void |
|
353 combine_atop_u (pixman_implementation_t *imp, |
|
354 pixman_op_t op, |
|
355 uint32_t * dest, |
|
356 const uint32_t * src, |
|
357 const uint32_t * mask, |
|
358 int width) |
|
359 { |
|
360 int i; |
|
361 |
|
362 for (i = 0; i < width; ++i) |
|
363 { |
|
364 uint32_t s = combine_mask (src, mask, i); |
|
365 uint32_t d = *(dest + i); |
|
366 uint32_t dest_a = ALPHA_8 (d); |
|
367 uint32_t src_ia = ALPHA_8 (~s); |
|
368 |
|
369 UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_a, d, src_ia); |
|
370 *(dest + i) = s; |
|
371 } |
|
372 } |
|
373 |
|
374 static void |
|
375 combine_atop_reverse_u (pixman_implementation_t *imp, |
|
376 pixman_op_t op, |
|
377 uint32_t * dest, |
|
378 const uint32_t * src, |
|
379 const uint32_t * mask, |
|
380 int width) |
|
381 { |
|
382 int i; |
|
383 |
|
384 for (i = 0; i < width; ++i) |
|
385 { |
|
386 uint32_t s = combine_mask (src, mask, i); |
|
387 uint32_t d = *(dest + i); |
|
388 uint32_t src_a = ALPHA_8 (s); |
|
389 uint32_t dest_ia = ALPHA_8 (~d); |
|
390 |
|
391 UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_ia, d, src_a); |
|
392 *(dest + i) = s; |
|
393 } |
|
394 } |
|
395 |
|
396 static void |
|
397 combine_xor_u (pixman_implementation_t *imp, |
|
398 pixman_op_t op, |
|
399 uint32_t * dest, |
|
400 const uint32_t * src, |
|
401 const uint32_t * mask, |
|
402 int width) |
|
403 { |
|
404 int i; |
|
405 |
|
406 for (i = 0; i < width; ++i) |
|
407 { |
|
408 uint32_t s = combine_mask (src, mask, i); |
|
409 uint32_t d = *(dest + i); |
|
410 uint32_t src_ia = ALPHA_8 (~s); |
|
411 uint32_t dest_ia = ALPHA_8 (~d); |
|
412 |
|
413 UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (s, dest_ia, d, src_ia); |
|
414 *(dest + i) = s; |
|
415 } |
|
416 } |
|
417 |
|
418 static void |
|
419 combine_add_u (pixman_implementation_t *imp, |
|
420 pixman_op_t op, |
|
421 uint32_t * dest, |
|
422 const uint32_t * src, |
|
423 const uint32_t * mask, |
|
424 int width) |
|
425 { |
|
426 int i; |
|
427 |
|
428 for (i = 0; i < width; ++i) |
|
429 { |
|
430 uint32_t s = combine_mask (src, mask, i); |
|
431 uint32_t d = *(dest + i); |
|
432 UN8x4_ADD_UN8x4 (d, s); |
|
433 *(dest + i) = d; |
|
434 } |
|
435 } |
|
436 |
|
437 static void |
|
438 combine_saturate_u (pixman_implementation_t *imp, |
|
439 pixman_op_t op, |
|
440 uint32_t * dest, |
|
441 const uint32_t * src, |
|
442 const uint32_t * mask, |
|
443 int width) |
|
444 { |
|
445 int i; |
|
446 |
|
447 for (i = 0; i < width; ++i) |
|
448 { |
|
449 uint32_t s = combine_mask (src, mask, i); |
|
450 uint32_t d = *(dest + i); |
|
451 uint16_t sa, da; |
|
452 |
|
453 sa = s >> A_SHIFT; |
|
454 da = ~d >> A_SHIFT; |
|
455 if (sa > da) |
|
456 { |
|
457 sa = DIV_UN8 (da, sa); |
|
458 UN8x4_MUL_UN8 (s, sa); |
|
459 } |
|
460 ; |
|
461 UN8x4_ADD_UN8x4 (d, s); |
|
462 *(dest + i) = d; |
|
463 } |
|
464 } |
|
465 |
|
466 /* |
|
467 * PDF blend modes: |
|
468 * The following blend modes have been taken from the PDF ISO 32000 |
|
469 * specification, which at this point in time is available from |
|
470 * http://www.adobe.com/devnet/acrobat/pdfs/PDF32000_2008.pdf |
|
471 * The relevant chapters are 11.3.5 and 11.3.6. |
|
472 * The formula for computing the final pixel color given in 11.3.6 is: |
|
473 * αr × Cr = (1 – αs) × αb × Cb + (1 – αb) × αs × Cs + αb × αs × B(Cb, Cs) |
|
474 * with B() being the blend function. |
|
475 * Note that OVER is a special case of this operation, using B(Cb, Cs) = Cs |
|
476 * |
|
477 * These blend modes should match the SVG filter draft specification, as |
|
478 * it has been designed to mirror ISO 32000. Note that at the current point |
|
479 * no released draft exists that shows this, as the formulas have not been |
|
480 * updated yet after the release of ISO 32000. |
|
481 * |
|
482 * The default implementation here uses the PDF_SEPARABLE_BLEND_MODE and |
|
483 * PDF_NON_SEPARABLE_BLEND_MODE macros, which take the blend function as an |
|
484 * argument. Note that this implementation operates on premultiplied colors, |
|
485 * while the PDF specification does not. Therefore the code uses the formula |
|
486 * Cra = (1 – as) . Dca + (1 – ad) . Sca + B(Dca, ad, Sca, as) |
|
487 */ |
|
488 |
|
489 /* |
|
490 * Multiply |
|
491 * B(Dca, ad, Sca, as) = Dca.Sca |
|
492 */ |
|
493 static void |
|
494 combine_multiply_u (pixman_implementation_t *imp, |
|
495 pixman_op_t op, |
|
496 uint32_t * dest, |
|
497 const uint32_t * src, |
|
498 const uint32_t * mask, |
|
499 int width) |
|
500 { |
|
501 int i; |
|
502 |
|
503 for (i = 0; i < width; ++i) |
|
504 { |
|
505 uint32_t s = combine_mask (src, mask, i); |
|
506 uint32_t d = *(dest + i); |
|
507 uint32_t ss = s; |
|
508 uint32_t src_ia = ALPHA_8 (~s); |
|
509 uint32_t dest_ia = ALPHA_8 (~d); |
|
510 |
|
511 UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (ss, dest_ia, d, src_ia); |
|
512 UN8x4_MUL_UN8x4 (d, s); |
|
513 UN8x4_ADD_UN8x4 (d, ss); |
|
514 |
|
515 *(dest + i) = d; |
|
516 } |
|
517 } |
|
518 |
|
519 static void |
|
520 combine_multiply_ca (pixman_implementation_t *imp, |
|
521 pixman_op_t op, |
|
522 uint32_t * dest, |
|
523 const uint32_t * src, |
|
524 const uint32_t * mask, |
|
525 int width) |
|
526 { |
|
527 int i; |
|
528 |
|
529 for (i = 0; i < width; ++i) |
|
530 { |
|
531 uint32_t m = *(mask + i); |
|
532 uint32_t s = *(src + i); |
|
533 uint32_t d = *(dest + i); |
|
534 uint32_t r = d; |
|
535 uint32_t dest_ia = ALPHA_8 (~d); |
|
536 |
|
537 combine_mask_ca (&s, &m); |
|
538 |
|
539 UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (r, ~m, s, dest_ia); |
|
540 UN8x4_MUL_UN8x4 (d, s); |
|
541 UN8x4_ADD_UN8x4 (r, d); |
|
542 |
|
543 *(dest + i) = r; |
|
544 } |
|
545 } |
|
546 |
|
547 #define PDF_SEPARABLE_BLEND_MODE(name) \ |
|
548 static void \ |
|
549 combine_ ## name ## _u (pixman_implementation_t *imp, \ |
|
550 pixman_op_t op, \ |
|
551 uint32_t * dest, \ |
|
552 const uint32_t * src, \ |
|
553 const uint32_t * mask, \ |
|
554 int width) \ |
|
555 { \ |
|
556 int i; \ |
|
557 for (i = 0; i < width; ++i) { \ |
|
558 uint32_t s = combine_mask (src, mask, i); \ |
|
559 uint32_t d = *(dest + i); \ |
|
560 uint8_t sa = ALPHA_8 (s); \ |
|
561 uint8_t isa = ~sa; \ |
|
562 uint8_t da = ALPHA_8 (d); \ |
|
563 uint8_t ida = ~da; \ |
|
564 uint32_t result; \ |
|
565 \ |
|
566 result = d; \ |
|
567 UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (result, isa, s, ida); \ |
|
568 \ |
|
569 *(dest + i) = result + \ |
|
570 (DIV_ONE_UN8 (sa * (uint32_t)da) << A_SHIFT) + \ |
|
571 (blend_ ## name (RED_8 (d), da, RED_8 (s), sa) << R_SHIFT) + \ |
|
572 (blend_ ## name (GREEN_8 (d), da, GREEN_8 (s), sa) << G_SHIFT) + \ |
|
573 (blend_ ## name (BLUE_8 (d), da, BLUE_8 (s), sa)); \ |
|
574 } \ |
|
575 } \ |
|
576 \ |
|
577 static void \ |
|
578 combine_ ## name ## _ca (pixman_implementation_t *imp, \ |
|
579 pixman_op_t op, \ |
|
580 uint32_t * dest, \ |
|
581 const uint32_t * src, \ |
|
582 const uint32_t * mask, \ |
|
583 int width) \ |
|
584 { \ |
|
585 int i; \ |
|
586 for (i = 0; i < width; ++i) { \ |
|
587 uint32_t m = *(mask + i); \ |
|
588 uint32_t s = *(src + i); \ |
|
589 uint32_t d = *(dest + i); \ |
|
590 uint8_t da = ALPHA_8 (d); \ |
|
591 uint8_t ida = ~da; \ |
|
592 uint32_t result; \ |
|
593 \ |
|
594 combine_mask_ca (&s, &m); \ |
|
595 \ |
|
596 result = d; \ |
|
597 UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (result, ~m, s, ida); \ |
|
598 \ |
|
599 result += \ |
|
600 (DIV_ONE_UN8 (ALPHA_8 (m) * (uint32_t)da) << A_SHIFT) + \ |
|
601 (blend_ ## name (RED_8 (d), da, RED_8 (s), RED_8 (m)) << R_SHIFT) + \ |
|
602 (blend_ ## name (GREEN_8 (d), da, GREEN_8 (s), GREEN_8 (m)) << G_SHIFT) + \ |
|
603 (blend_ ## name (BLUE_8 (d), da, BLUE_8 (s), BLUE_8 (m))); \ |
|
604 \ |
|
605 *(dest + i) = result; \ |
|
606 } \ |
|
607 } |
|
608 |
|
609 /* |
|
610 * Screen |
|
611 * B(Dca, ad, Sca, as) = Dca.sa + Sca.da - Dca.Sca |
|
612 */ |
|
613 static inline uint32_t |
|
614 blend_screen (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa) |
|
615 { |
|
616 return DIV_ONE_UN8 (sca * da + dca * sa - sca * dca); |
|
617 } |
|
618 |
|
619 PDF_SEPARABLE_BLEND_MODE (screen) |
|
620 |
|
621 /* |
|
622 * Overlay |
|
623 * B(Dca, Da, Sca, Sa) = |
|
624 * if 2.Dca < Da |
|
625 * 2.Sca.Dca |
|
626 * otherwise |
|
627 * Sa.Da - 2.(Da - Dca).(Sa - Sca) |
|
628 */ |
|
629 static inline uint32_t |
|
630 blend_overlay (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa) |
|
631 { |
|
632 uint32_t rca; |
|
633 |
|
634 if (2 * dca < da) |
|
635 rca = 2 * sca * dca; |
|
636 else |
|
637 rca = sa * da - 2 * (da - dca) * (sa - sca); |
|
638 return DIV_ONE_UN8 (rca); |
|
639 } |
|
640 |
|
641 PDF_SEPARABLE_BLEND_MODE (overlay) |
|
642 |
|
643 /* |
|
644 * Darken |
|
645 * B(Dca, Da, Sca, Sa) = min (Sca.Da, Dca.Sa) |
|
646 */ |
|
647 static inline uint32_t |
|
648 blend_darken (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa) |
|
649 { |
|
650 uint32_t s, d; |
|
651 |
|
652 s = sca * da; |
|
653 d = dca * sa; |
|
654 return DIV_ONE_UN8 (s > d ? d : s); |
|
655 } |
|
656 |
|
657 PDF_SEPARABLE_BLEND_MODE (darken) |
|
658 |
|
659 /* |
|
660 * Lighten |
|
661 * B(Dca, Da, Sca, Sa) = max (Sca.Da, Dca.Sa) |
|
662 */ |
|
663 static inline uint32_t |
|
664 blend_lighten (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa) |
|
665 { |
|
666 uint32_t s, d; |
|
667 |
|
668 s = sca * da; |
|
669 d = dca * sa; |
|
670 return DIV_ONE_UN8 (s > d ? s : d); |
|
671 } |
|
672 |
|
673 PDF_SEPARABLE_BLEND_MODE (lighten) |
|
674 |
|
675 /* |
|
676 * Color dodge |
|
677 * B(Dca, Da, Sca, Sa) = |
|
678 * if Dca == 0 |
|
679 * 0 |
|
680 * if Sca == Sa |
|
681 * Sa.Da |
|
682 * otherwise |
|
683 * Sa.Da. min (1, Dca / Da / (1 - Sca/Sa)) |
|
684 */ |
|
685 static inline uint32_t |
|
686 blend_color_dodge (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa) |
|
687 { |
|
688 if (sca >= sa) |
|
689 { |
|
690 return dca == 0 ? 0 : DIV_ONE_UN8 (sa * da); |
|
691 } |
|
692 else |
|
693 { |
|
694 uint32_t rca = dca * sa / (sa - sca); |
|
695 return DIV_ONE_UN8 (sa * MIN (rca, da)); |
|
696 } |
|
697 } |
|
698 |
|
699 PDF_SEPARABLE_BLEND_MODE (color_dodge) |
|
700 |
|
701 /* |
|
702 * Color burn |
|
703 * B(Dca, Da, Sca, Sa) = |
|
704 * if Dca == Da |
|
705 * Sa.Da |
|
706 * if Sca == 0 |
|
707 * 0 |
|
708 * otherwise |
|
709 * Sa.Da.(1 - min (1, (1 - Dca/Da).Sa / Sca)) |
|
710 */ |
|
711 static inline uint32_t |
|
712 blend_color_burn (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa) |
|
713 { |
|
714 if (sca == 0) |
|
715 { |
|
716 return dca < da ? 0 : DIV_ONE_UN8 (sa * da); |
|
717 } |
|
718 else |
|
719 { |
|
720 uint32_t rca = (da - dca) * sa / sca; |
|
721 return DIV_ONE_UN8 (sa * (MAX (rca, da) - rca)); |
|
722 } |
|
723 } |
|
724 |
|
725 PDF_SEPARABLE_BLEND_MODE (color_burn) |
|
726 |
|
727 /* |
|
728 * Hard light |
|
729 * B(Dca, Da, Sca, Sa) = |
|
730 * if 2.Sca < Sa |
|
731 * 2.Sca.Dca |
|
732 * otherwise |
|
733 * Sa.Da - 2.(Da - Dca).(Sa - Sca) |
|
734 */ |
|
735 static inline uint32_t |
|
736 blend_hard_light (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa) |
|
737 { |
|
738 if (2 * sca < sa) |
|
739 return DIV_ONE_UN8 (2 * sca * dca); |
|
740 else |
|
741 return DIV_ONE_UN8 (sa * da - 2 * (da - dca) * (sa - sca)); |
|
742 } |
|
743 |
|
744 PDF_SEPARABLE_BLEND_MODE (hard_light) |
|
745 |
|
746 /* |
|
747 * Soft light |
|
748 * B(Dca, Da, Sca, Sa) = |
|
749 * if (2.Sca <= Sa) |
|
750 * Dca.(Sa - (1 - Dca/Da).(2.Sca - Sa)) |
|
751 * otherwise if Dca.4 <= Da |
|
752 * Dca.(Sa + (2.Sca - Sa).((16.Dca/Da - 12).Dca/Da + 3) |
|
753 * otherwise |
|
754 * (Dca.Sa + (SQRT (Dca/Da).Da - Dca).(2.Sca - Sa)) |
|
755 */ |
|
756 static inline uint32_t |
|
757 blend_soft_light (uint32_t dca_org, |
|
758 uint32_t da_org, |
|
759 uint32_t sca_org, |
|
760 uint32_t sa_org) |
|
761 { |
|
762 double dca = dca_org * (1.0 / MASK); |
|
763 double da = da_org * (1.0 / MASK); |
|
764 double sca = sca_org * (1.0 / MASK); |
|
765 double sa = sa_org * (1.0 / MASK); |
|
766 double rca; |
|
767 |
|
768 if (2 * sca < sa) |
|
769 { |
|
770 if (da == 0) |
|
771 rca = dca * sa; |
|
772 else |
|
773 rca = dca * sa - dca * (da - dca) * (sa - 2 * sca) / da; |
|
774 } |
|
775 else if (da == 0) |
|
776 { |
|
777 rca = 0; |
|
778 } |
|
779 else if (4 * dca <= da) |
|
780 { |
|
781 rca = dca * sa + |
|
782 (2 * sca - sa) * dca * ((16 * dca / da - 12) * dca / da + 3); |
|
783 } |
|
784 else |
|
785 { |
|
786 rca = dca * sa + (sqrt (dca * da) - dca) * (2 * sca - sa); |
|
787 } |
|
788 return rca * MASK + 0.5; |
|
789 } |
|
790 |
|
791 PDF_SEPARABLE_BLEND_MODE (soft_light) |
|
792 |
|
793 /* |
|
794 * Difference |
|
795 * B(Dca, Da, Sca, Sa) = abs (Dca.Sa - Sca.Da) |
|
796 */ |
|
797 static inline uint32_t |
|
798 blend_difference (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa) |
|
799 { |
|
800 uint32_t dcasa = dca * sa; |
|
801 uint32_t scada = sca * da; |
|
802 |
|
803 if (scada < dcasa) |
|
804 return DIV_ONE_UN8 (dcasa - scada); |
|
805 else |
|
806 return DIV_ONE_UN8 (scada - dcasa); |
|
807 } |
|
808 |
|
809 PDF_SEPARABLE_BLEND_MODE (difference) |
|
810 |
|
811 /* |
|
812 * Exclusion |
|
813 * B(Dca, Da, Sca, Sa) = (Sca.Da + Dca.Sa - 2.Sca.Dca) |
|
814 */ |
|
815 |
|
816 /* This can be made faster by writing it directly and not using |
|
817 * PDF_SEPARABLE_BLEND_MODE, but that's a performance optimization */ |
|
818 |
|
819 static inline uint32_t |
|
820 blend_exclusion (uint32_t dca, uint32_t da, uint32_t sca, uint32_t sa) |
|
821 { |
|
822 return DIV_ONE_UN8 (sca * da + dca * sa - 2 * dca * sca); |
|
823 } |
|
824 |
|
825 PDF_SEPARABLE_BLEND_MODE (exclusion) |
|
826 |
|
827 #undef PDF_SEPARABLE_BLEND_MODE |
|
828 |
|
829 /* |
|
830 * PDF nonseperable blend modes are implemented using the following functions |
|
831 * to operate in Hsl space, with Cmax, Cmid, Cmin referring to the max, mid |
|
832 * and min value of the red, green and blue components. |
|
833 * |
|
834 * LUM (C) = 0.3 × Cred + 0.59 × Cgreen + 0.11 × Cblue |
|
835 * |
|
836 * clip_color (C): |
|
837 * l = LUM (C) |
|
838 * min = Cmin |
|
839 * max = Cmax |
|
840 * if n < 0.0 |
|
841 * C = l + ( ( ( C – l ) × l ) ⁄ ( l – min ) ) |
|
842 * if x > 1.0 |
|
843 * C = l + ( ( ( C – l ) × ( 1 – l ) ) ⁄ ( max – l ) ) |
|
844 * return C |
|
845 * |
|
846 * set_lum (C, l): |
|
847 * d = l – LUM (C) |
|
848 * C += d |
|
849 * return clip_color (C) |
|
850 * |
|
851 * SAT (C) = CH_MAX (C) - CH_MIN (C) |
|
852 * |
|
853 * set_sat (C, s): |
|
854 * if Cmax > Cmin |
|
855 * Cmid = ( ( ( Cmid – Cmin ) × s ) ⁄ ( Cmax – Cmin ) ) |
|
856 * Cmax = s |
|
857 * else |
|
858 * Cmid = Cmax = 0.0 |
|
859 * Cmin = 0.0 |
|
860 * return C |
|
861 */ |
|
862 |
|
863 /* For premultiplied colors, we need to know what happens when C is |
|
864 * multiplied by a real number. LUM and SAT are linear: |
|
865 * |
|
866 * LUM (r × C) = r × LUM (C) SAT (r * C) = r * SAT (C) |
|
867 * |
|
868 * If we extend clip_color with an extra argument a and change |
|
869 * |
|
870 * if x >= 1.0 |
|
871 * |
|
872 * into |
|
873 * |
|
874 * if x >= a |
|
875 * |
|
876 * then clip_color is also linear: |
|
877 * |
|
878 * r * clip_color (C, a) = clip_color (r_c, ra); |
|
879 * |
|
880 * for positive r. |
|
881 * |
|
882 * Similarly, we can extend set_lum with an extra argument that is just passed |
|
883 * on to clip_color: |
|
884 * |
|
885 * r * set_lum ( C, l, a) |
|
886 * |
|
887 * = r × clip_color ( C + l - LUM (C), a) |
|
888 * |
|
889 * = clip_color ( r * C + r × l - r * LUM (C), r * a) |
|
890 * |
|
891 * = set_lum ( r * C, r * l, r * a) |
|
892 * |
|
893 * Finally, set_sat: |
|
894 * |
|
895 * r * set_sat (C, s) = set_sat (x * C, r * s) |
|
896 * |
|
897 * The above holds for all non-zero x, because the x'es in the fraction for |
|
898 * C_mid cancel out. Specifically, it holds for x = r: |
|
899 * |
|
900 * r * set_sat (C, s) = set_sat (r_c, rs) |
|
901 * |
|
902 */ |
|
903 |
|
904 /* So, for the non-separable PDF blend modes, we have (using s, d for |
|
905 * non-premultiplied colors, and S, D for premultiplied: |
|
906 * |
|
907 * Color: |
|
908 * |
|
909 * a_s * a_d * B(s, d) |
|
910 * = a_s * a_d * set_lum (S/a_s, LUM (D/a_d), 1) |
|
911 * = set_lum (S * a_d, a_s * LUM (D), a_s * a_d) |
|
912 * |
|
913 * |
|
914 * Luminosity: |
|
915 * |
|
916 * a_s * a_d * B(s, d) |
|
917 * = a_s * a_d * set_lum (D/a_d, LUM(S/a_s), 1) |
|
918 * = set_lum (a_s * D, a_d * LUM(S), a_s * a_d) |
|
919 * |
|
920 * |
|
921 * Saturation: |
|
922 * |
|
923 * a_s * a_d * B(s, d) |
|
924 * = a_s * a_d * set_lum (set_sat (D/a_d, SAT (S/a_s)), LUM (D/a_d), 1) |
|
925 * = set_lum (a_s * a_d * set_sat (D/a_d, SAT (S/a_s)), |
|
926 * a_s * LUM (D), a_s * a_d) |
|
927 * = set_lum (set_sat (a_s * D, a_d * SAT (S), a_s * LUM (D), a_s * a_d)) |
|
928 * |
|
929 * Hue: |
|
930 * |
|
931 * a_s * a_d * B(s, d) |
|
932 * = a_s * a_d * set_lum (set_sat (S/a_s, SAT (D/a_d)), LUM (D/a_d), 1) |
|
933 * = set_lum (set_sat (a_d * S, a_s * SAT (D)), a_s * LUM (D), a_s * a_d) |
|
934 * |
|
935 */ |
|
936 |
|
937 #define CH_MIN(c) (c[0] < c[1] ? (c[0] < c[2] ? c[0] : c[2]) : (c[1] < c[2] ? c[1] : c[2])) |
|
938 #define CH_MAX(c) (c[0] > c[1] ? (c[0] > c[2] ? c[0] : c[2]) : (c[1] > c[2] ? c[1] : c[2])) |
|
939 #define LUM(c) ((c[0] * 30 + c[1] * 59 + c[2] * 11) / 100) |
|
940 #define SAT(c) (CH_MAX (c) - CH_MIN (c)) |
|
941 |
|
942 #define PDF_NON_SEPARABLE_BLEND_MODE(name) \ |
|
943 static void \ |
|
944 combine_ ## name ## _u (pixman_implementation_t *imp, \ |
|
945 pixman_op_t op, \ |
|
946 uint32_t *dest, \ |
|
947 const uint32_t *src, \ |
|
948 const uint32_t *mask, \ |
|
949 int width) \ |
|
950 { \ |
|
951 int i; \ |
|
952 for (i = 0; i < width; ++i) \ |
|
953 { \ |
|
954 uint32_t s = combine_mask (src, mask, i); \ |
|
955 uint32_t d = *(dest + i); \ |
|
956 uint8_t sa = ALPHA_8 (s); \ |
|
957 uint8_t isa = ~sa; \ |
|
958 uint8_t da = ALPHA_8 (d); \ |
|
959 uint8_t ida = ~da; \ |
|
960 uint32_t result; \ |
|
961 uint32_t sc[3], dc[3], c[3]; \ |
|
962 \ |
|
963 result = d; \ |
|
964 UN8x4_MUL_UN8_ADD_UN8x4_MUL_UN8 (result, isa, s, ida); \ |
|
965 dc[0] = RED_8 (d); \ |
|
966 sc[0] = RED_8 (s); \ |
|
967 dc[1] = GREEN_8 (d); \ |
|
968 sc[1] = GREEN_8 (s); \ |
|
969 dc[2] = BLUE_8 (d); \ |
|
970 sc[2] = BLUE_8 (s); \ |
|
971 blend_ ## name (c, dc, da, sc, sa); \ |
|
972 \ |
|
973 *(dest + i) = result + \ |
|
974 (DIV_ONE_UN8 (sa * (uint32_t)da) << A_SHIFT) + \ |
|
975 (DIV_ONE_UN8 (c[0]) << R_SHIFT) + \ |
|
976 (DIV_ONE_UN8 (c[1]) << G_SHIFT) + \ |
|
977 (DIV_ONE_UN8 (c[2])); \ |
|
978 } \ |
|
979 } |
|
980 |
|
981 static void |
|
982 set_lum (uint32_t dest[3], uint32_t src[3], uint32_t sa, uint32_t lum) |
|
983 { |
|
984 double a, l, min, max; |
|
985 double tmp[3]; |
|
986 |
|
987 a = sa * (1.0 / MASK); |
|
988 |
|
989 l = lum * (1.0 / MASK); |
|
990 tmp[0] = src[0] * (1.0 / MASK); |
|
991 tmp[1] = src[1] * (1.0 / MASK); |
|
992 tmp[2] = src[2] * (1.0 / MASK); |
|
993 |
|
994 l = l - LUM (tmp); |
|
995 tmp[0] += l; |
|
996 tmp[1] += l; |
|
997 tmp[2] += l; |
|
998 |
|
999 /* clip_color */ |
|
1000 l = LUM (tmp); |
|
1001 min = CH_MIN (tmp); |
|
1002 max = CH_MAX (tmp); |
|
1003 |
|
1004 if (min < 0) |
|
1005 { |
|
1006 if (l - min == 0.0) |
|
1007 { |
|
1008 tmp[0] = 0; |
|
1009 tmp[1] = 0; |
|
1010 tmp[2] = 0; |
|
1011 } |
|
1012 else |
|
1013 { |
|
1014 tmp[0] = l + (tmp[0] - l) * l / (l - min); |
|
1015 tmp[1] = l + (tmp[1] - l) * l / (l - min); |
|
1016 tmp[2] = l + (tmp[2] - l) * l / (l - min); |
|
1017 } |
|
1018 } |
|
1019 if (max > a) |
|
1020 { |
|
1021 if (max - l == 0.0) |
|
1022 { |
|
1023 tmp[0] = a; |
|
1024 tmp[1] = a; |
|
1025 tmp[2] = a; |
|
1026 } |
|
1027 else |
|
1028 { |
|
1029 tmp[0] = l + (tmp[0] - l) * (a - l) / (max - l); |
|
1030 tmp[1] = l + (tmp[1] - l) * (a - l) / (max - l); |
|
1031 tmp[2] = l + (tmp[2] - l) * (a - l) / (max - l); |
|
1032 } |
|
1033 } |
|
1034 |
|
1035 dest[0] = tmp[0] * MASK + 0.5; |
|
1036 dest[1] = tmp[1] * MASK + 0.5; |
|
1037 dest[2] = tmp[2] * MASK + 0.5; |
|
1038 } |
|
1039 |
|
1040 static void |
|
1041 set_sat (uint32_t dest[3], uint32_t src[3], uint32_t sat) |
|
1042 { |
|
1043 int id[3]; |
|
1044 uint32_t min, max; |
|
1045 |
|
1046 if (src[0] > src[1]) |
|
1047 { |
|
1048 if (src[0] > src[2]) |
|
1049 { |
|
1050 id[0] = 0; |
|
1051 if (src[1] > src[2]) |
|
1052 { |
|
1053 id[1] = 1; |
|
1054 id[2] = 2; |
|
1055 } |
|
1056 else |
|
1057 { |
|
1058 id[1] = 2; |
|
1059 id[2] = 1; |
|
1060 } |
|
1061 } |
|
1062 else |
|
1063 { |
|
1064 id[0] = 2; |
|
1065 id[1] = 0; |
|
1066 id[2] = 1; |
|
1067 } |
|
1068 } |
|
1069 else |
|
1070 { |
|
1071 if (src[0] > src[2]) |
|
1072 { |
|
1073 id[0] = 1; |
|
1074 id[1] = 0; |
|
1075 id[2] = 2; |
|
1076 } |
|
1077 else |
|
1078 { |
|
1079 id[2] = 0; |
|
1080 if (src[1] > src[2]) |
|
1081 { |
|
1082 id[0] = 1; |
|
1083 id[1] = 2; |
|
1084 } |
|
1085 else |
|
1086 { |
|
1087 id[0] = 2; |
|
1088 id[1] = 1; |
|
1089 } |
|
1090 } |
|
1091 } |
|
1092 |
|
1093 max = dest[id[0]]; |
|
1094 min = dest[id[2]]; |
|
1095 if (max > min) |
|
1096 { |
|
1097 dest[id[1]] = (dest[id[1]] - min) * sat / (max - min); |
|
1098 dest[id[0]] = sat; |
|
1099 dest[id[2]] = 0; |
|
1100 } |
|
1101 else |
|
1102 { |
|
1103 dest[0] = dest[1] = dest[2] = 0; |
|
1104 } |
|
1105 } |
|
1106 |
|
1107 /* |
|
1108 * Hue: |
|
1109 * B(Cb, Cs) = set_lum (set_sat (Cs, SAT (Cb)), LUM (Cb)) |
|
1110 */ |
|
1111 static inline void |
|
1112 blend_hsl_hue (uint32_t c[3], |
|
1113 uint32_t dc[3], |
|
1114 uint32_t da, |
|
1115 uint32_t sc[3], |
|
1116 uint32_t sa) |
|
1117 { |
|
1118 c[0] = sc[0] * da; |
|
1119 c[1] = sc[1] * da; |
|
1120 c[2] = sc[2] * da; |
|
1121 set_sat (c, c, SAT (dc) * sa); |
|
1122 set_lum (c, c, sa * da, LUM (dc) * sa); |
|
1123 } |
|
1124 |
|
1125 PDF_NON_SEPARABLE_BLEND_MODE (hsl_hue) |
|
1126 |
|
1127 /* |
|
1128 * Saturation: |
|
1129 * B(Cb, Cs) = set_lum (set_sat (Cb, SAT (Cs)), LUM (Cb)) |
|
1130 */ |
|
1131 static inline void |
|
1132 blend_hsl_saturation (uint32_t c[3], |
|
1133 uint32_t dc[3], |
|
1134 uint32_t da, |
|
1135 uint32_t sc[3], |
|
1136 uint32_t sa) |
|
1137 { |
|
1138 c[0] = dc[0] * sa; |
|
1139 c[1] = dc[1] * sa; |
|
1140 c[2] = dc[2] * sa; |
|
1141 set_sat (c, c, SAT (sc) * da); |
|
1142 set_lum (c, c, sa * da, LUM (dc) * sa); |
|
1143 } |
|
1144 |
|
1145 PDF_NON_SEPARABLE_BLEND_MODE (hsl_saturation) |
|
1146 |
|
1147 /* |
|
1148 * Color: |
|
1149 * B(Cb, Cs) = set_lum (Cs, LUM (Cb)) |
|
1150 */ |
|
1151 static inline void |
|
1152 blend_hsl_color (uint32_t c[3], |
|
1153 uint32_t dc[3], |
|
1154 uint32_t da, |
|
1155 uint32_t sc[3], |
|
1156 uint32_t sa) |
|
1157 { |
|
1158 c[0] = sc[0] * da; |
|
1159 c[1] = sc[1] * da; |
|
1160 c[2] = sc[2] * da; |
|
1161 set_lum (c, c, sa * da, LUM (dc) * sa); |
|
1162 } |
|
1163 |
|
1164 PDF_NON_SEPARABLE_BLEND_MODE (hsl_color) |
|
1165 |
|
1166 /* |
|
1167 * Luminosity: |
|
1168 * B(Cb, Cs) = set_lum (Cb, LUM (Cs)) |
|
1169 */ |
|
1170 static inline void |
|
1171 blend_hsl_luminosity (uint32_t c[3], |
|
1172 uint32_t dc[3], |
|
1173 uint32_t da, |
|
1174 uint32_t sc[3], |
|
1175 uint32_t sa) |
|
1176 { |
|
1177 c[0] = dc[0] * sa; |
|
1178 c[1] = dc[1] * sa; |
|
1179 c[2] = dc[2] * sa; |
|
1180 set_lum (c, c, sa * da, LUM (sc) * da); |
|
1181 } |
|
1182 |
|
1183 PDF_NON_SEPARABLE_BLEND_MODE (hsl_luminosity) |
|
1184 |
|
1185 #undef SAT |
|
1186 #undef LUM |
|
1187 #undef CH_MAX |
|
1188 #undef CH_MIN |
|
1189 #undef PDF_NON_SEPARABLE_BLEND_MODE |
|
1190 |
|
1191 /* All of the disjoint/conjoint composing functions |
|
1192 * |
|
1193 * The four entries in the first column indicate what source contributions |
|
1194 * come from each of the four areas of the picture -- areas covered by neither |
|
1195 * A nor B, areas covered only by A, areas covered only by B and finally |
|
1196 * areas covered by both A and B. |
|
1197 * |
|
1198 * Disjoint Conjoint |
|
1199 * Fa Fb Fa Fb |
|
1200 * (0,0,0,0) 0 0 0 0 |
|
1201 * (0,A,0,A) 1 0 1 0 |
|
1202 * (0,0,B,B) 0 1 0 1 |
|
1203 * (0,A,B,A) 1 min((1-a)/b,1) 1 max(1-a/b,0) |
|
1204 * (0,A,B,B) min((1-b)/a,1) 1 max(1-b/a,0) 1 |
|
1205 * (0,0,0,A) max(1-(1-b)/a,0) 0 min(1,b/a) 0 |
|
1206 * (0,0,0,B) 0 max(1-(1-a)/b,0) 0 min(a/b,1) |
|
1207 * (0,A,0,0) min(1,(1-b)/a) 0 max(1-b/a,0) 0 |
|
1208 * (0,0,B,0) 0 min(1,(1-a)/b) 0 max(1-a/b,0) |
|
1209 * (0,0,B,A) max(1-(1-b)/a,0) min(1,(1-a)/b) min(1,b/a) max(1-a/b,0) |
|
1210 * (0,A,0,B) min(1,(1-b)/a) max(1-(1-a)/b,0) max(1-b/a,0) min(1,a/b) |
|
1211 * (0,A,B,0) min(1,(1-b)/a) min(1,(1-a)/b) max(1-b/a,0) max(1-a/b,0) |
|
1212 * |
|
1213 * See http://marc.info/?l=xfree-render&m=99792000027857&w=2 for more |
|
1214 * information about these operators. |
|
1215 */ |
|
1216 |
|
1217 #define COMBINE_A_OUT 1 |
|
1218 #define COMBINE_A_IN 2 |
|
1219 #define COMBINE_B_OUT 4 |
|
1220 #define COMBINE_B_IN 8 |
|
1221 |
|
1222 #define COMBINE_CLEAR 0 |
|
1223 #define COMBINE_A (COMBINE_A_OUT | COMBINE_A_IN) |
|
1224 #define COMBINE_B (COMBINE_B_OUT | COMBINE_B_IN) |
|
1225 #define COMBINE_A_OVER (COMBINE_A_OUT | COMBINE_B_OUT | COMBINE_A_IN) |
|
1226 #define COMBINE_B_OVER (COMBINE_A_OUT | COMBINE_B_OUT | COMBINE_B_IN) |
|
1227 #define COMBINE_A_ATOP (COMBINE_B_OUT | COMBINE_A_IN) |
|
1228 #define COMBINE_B_ATOP (COMBINE_A_OUT | COMBINE_B_IN) |
|
1229 #define COMBINE_XOR (COMBINE_A_OUT | COMBINE_B_OUT) |
|
1230 |
|
1231 /* portion covered by a but not b */ |
|
1232 static uint8_t |
|
1233 combine_disjoint_out_part (uint8_t a, uint8_t b) |
|
1234 { |
|
1235 /* min (1, (1-b) / a) */ |
|
1236 |
|
1237 b = ~b; /* 1 - b */ |
|
1238 if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */ |
|
1239 return MASK; /* 1 */ |
|
1240 return DIV_UN8 (b, a); /* (1-b) / a */ |
|
1241 } |
|
1242 |
|
1243 /* portion covered by both a and b */ |
|
1244 static uint8_t |
|
1245 combine_disjoint_in_part (uint8_t a, uint8_t b) |
|
1246 { |
|
1247 /* max (1-(1-b)/a,0) */ |
|
1248 /* = - min ((1-b)/a - 1, 0) */ |
|
1249 /* = 1 - min (1, (1-b)/a) */ |
|
1250 |
|
1251 b = ~b; /* 1 - b */ |
|
1252 if (b >= a) /* 1 - b >= a -> (1-b)/a >= 1 */ |
|
1253 return 0; /* 1 - 1 */ |
|
1254 return ~DIV_UN8(b, a); /* 1 - (1-b) / a */ |
|
1255 } |
|
1256 |
|
1257 /* portion covered by a but not b */ |
|
1258 static uint8_t |
|
1259 combine_conjoint_out_part (uint8_t a, uint8_t b) |
|
1260 { |
|
1261 /* max (1-b/a,0) */ |
|
1262 /* = 1-min(b/a,1) */ |
|
1263 |
|
1264 /* min (1, (1-b) / a) */ |
|
1265 |
|
1266 if (b >= a) /* b >= a -> b/a >= 1 */ |
|
1267 return 0x00; /* 0 */ |
|
1268 return ~DIV_UN8(b, a); /* 1 - b/a */ |
|
1269 } |
|
1270 |
|
1271 /* portion covered by both a and b */ |
|
1272 static uint8_t |
|
1273 combine_conjoint_in_part (uint8_t a, uint8_t b) |
|
1274 { |
|
1275 /* min (1,b/a) */ |
|
1276 |
|
1277 if (b >= a) /* b >= a -> b/a >= 1 */ |
|
1278 return MASK; /* 1 */ |
|
1279 return DIV_UN8 (b, a); /* b/a */ |
|
1280 } |
|
1281 |
|
1282 #define GET_COMP(v, i) ((uint16_t) (uint8_t) ((v) >> i)) |
|
1283 |
|
1284 #define ADD(x, y, i, t) \ |
|
1285 ((t) = GET_COMP (x, i) + GET_COMP (y, i), \ |
|
1286 (uint32_t) ((uint8_t) ((t) | (0 - ((t) >> G_SHIFT)))) << (i)) |
|
1287 |
|
1288 #define GENERIC(x, y, i, ax, ay, t, u, v) \ |
|
1289 ((t) = (MUL_UN8 (GET_COMP (y, i), ay, (u)) + \ |
|
1290 MUL_UN8 (GET_COMP (x, i), ax, (v))), \ |
|
1291 (uint32_t) ((uint8_t) ((t) | \ |
|
1292 (0 - ((t) >> G_SHIFT)))) << (i)) |
|
1293 |
|
1294 static void |
|
1295 combine_disjoint_general_u (uint32_t * dest, |
|
1296 const uint32_t *src, |
|
1297 const uint32_t *mask, |
|
1298 int width, |
|
1299 uint8_t combine) |
|
1300 { |
|
1301 int i; |
|
1302 |
|
1303 for (i = 0; i < width; ++i) |
|
1304 { |
|
1305 uint32_t s = combine_mask (src, mask, i); |
|
1306 uint32_t d = *(dest + i); |
|
1307 uint32_t m, n, o, p; |
|
1308 uint16_t Fa, Fb, t, u, v; |
|
1309 uint8_t sa = s >> A_SHIFT; |
|
1310 uint8_t da = d >> A_SHIFT; |
|
1311 |
|
1312 switch (combine & COMBINE_A) |
|
1313 { |
|
1314 default: |
|
1315 Fa = 0; |
|
1316 break; |
|
1317 |
|
1318 case COMBINE_A_OUT: |
|
1319 Fa = combine_disjoint_out_part (sa, da); |
|
1320 break; |
|
1321 |
|
1322 case COMBINE_A_IN: |
|
1323 Fa = combine_disjoint_in_part (sa, da); |
|
1324 break; |
|
1325 |
|
1326 case COMBINE_A: |
|
1327 Fa = MASK; |
|
1328 break; |
|
1329 } |
|
1330 |
|
1331 switch (combine & COMBINE_B) |
|
1332 { |
|
1333 default: |
|
1334 Fb = 0; |
|
1335 break; |
|
1336 |
|
1337 case COMBINE_B_OUT: |
|
1338 Fb = combine_disjoint_out_part (da, sa); |
|
1339 break; |
|
1340 |
|
1341 case COMBINE_B_IN: |
|
1342 Fb = combine_disjoint_in_part (da, sa); |
|
1343 break; |
|
1344 |
|
1345 case COMBINE_B: |
|
1346 Fb = MASK; |
|
1347 break; |
|
1348 } |
|
1349 m = GENERIC (s, d, 0, Fa, Fb, t, u, v); |
|
1350 n = GENERIC (s, d, G_SHIFT, Fa, Fb, t, u, v); |
|
1351 o = GENERIC (s, d, R_SHIFT, Fa, Fb, t, u, v); |
|
1352 p = GENERIC (s, d, A_SHIFT, Fa, Fb, t, u, v); |
|
1353 s = m | n | o | p; |
|
1354 *(dest + i) = s; |
|
1355 } |
|
1356 } |
|
1357 |
|
1358 static void |
|
1359 combine_disjoint_over_u (pixman_implementation_t *imp, |
|
1360 pixman_op_t op, |
|
1361 uint32_t * dest, |
|
1362 const uint32_t * src, |
|
1363 const uint32_t * mask, |
|
1364 int width) |
|
1365 { |
|
1366 int i; |
|
1367 |
|
1368 for (i = 0; i < width; ++i) |
|
1369 { |
|
1370 uint32_t s = combine_mask (src, mask, i); |
|
1371 uint16_t a = s >> A_SHIFT; |
|
1372 |
|
1373 if (s != 0x00) |
|
1374 { |
|
1375 uint32_t d = *(dest + i); |
|
1376 a = combine_disjoint_out_part (d >> A_SHIFT, a); |
|
1377 UN8x4_MUL_UN8_ADD_UN8x4 (d, a, s); |
|
1378 |
|
1379 *(dest + i) = d; |
|
1380 } |
|
1381 } |
|
1382 } |
|
1383 |
|
1384 static void |
|
1385 combine_disjoint_in_u (pixman_implementation_t *imp, |
|
1386 pixman_op_t op, |
|
1387 uint32_t * dest, |
|
1388 const uint32_t * src, |
|
1389 const uint32_t * mask, |
|
1390 int width) |
|
1391 { |
|
1392 combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_IN); |
|
1393 } |
|
1394 |
|
1395 static void |
|
1396 combine_disjoint_in_reverse_u (pixman_implementation_t *imp, |
|
1397 pixman_op_t op, |
|
1398 uint32_t * dest, |
|
1399 const uint32_t * src, |
|
1400 const uint32_t * mask, |
|
1401 int width) |
|
1402 { |
|
1403 combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_IN); |
|
1404 } |
|
1405 |
|
1406 static void |
|
1407 combine_disjoint_out_u (pixman_implementation_t *imp, |
|
1408 pixman_op_t op, |
|
1409 uint32_t * dest, |
|
1410 const uint32_t * src, |
|
1411 const uint32_t * mask, |
|
1412 int width) |
|
1413 { |
|
1414 combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_OUT); |
|
1415 } |
|
1416 |
|
1417 static void |
|
1418 combine_disjoint_out_reverse_u (pixman_implementation_t *imp, |
|
1419 pixman_op_t op, |
|
1420 uint32_t * dest, |
|
1421 const uint32_t * src, |
|
1422 const uint32_t * mask, |
|
1423 int width) |
|
1424 { |
|
1425 combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_OUT); |
|
1426 } |
|
1427 |
|
1428 static void |
|
1429 combine_disjoint_atop_u (pixman_implementation_t *imp, |
|
1430 pixman_op_t op, |
|
1431 uint32_t * dest, |
|
1432 const uint32_t * src, |
|
1433 const uint32_t * mask, |
|
1434 int width) |
|
1435 { |
|
1436 combine_disjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP); |
|
1437 } |
|
1438 |
|
1439 static void |
|
1440 combine_disjoint_atop_reverse_u (pixman_implementation_t *imp, |
|
1441 pixman_op_t op, |
|
1442 uint32_t * dest, |
|
1443 const uint32_t * src, |
|
1444 const uint32_t * mask, |
|
1445 int width) |
|
1446 { |
|
1447 combine_disjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP); |
|
1448 } |
|
1449 |
|
1450 static void |
|
1451 combine_disjoint_xor_u (pixman_implementation_t *imp, |
|
1452 pixman_op_t op, |
|
1453 uint32_t * dest, |
|
1454 const uint32_t * src, |
|
1455 const uint32_t * mask, |
|
1456 int width) |
|
1457 { |
|
1458 combine_disjoint_general_u (dest, src, mask, width, COMBINE_XOR); |
|
1459 } |
|
1460 |
|
1461 static void |
|
1462 combine_conjoint_general_u (uint32_t * dest, |
|
1463 const uint32_t *src, |
|
1464 const uint32_t *mask, |
|
1465 int width, |
|
1466 uint8_t combine) |
|
1467 { |
|
1468 int i; |
|
1469 |
|
1470 for (i = 0; i < width; ++i) |
|
1471 { |
|
1472 uint32_t s = combine_mask (src, mask, i); |
|
1473 uint32_t d = *(dest + i); |
|
1474 uint32_t m, n, o, p; |
|
1475 uint16_t Fa, Fb, t, u, v; |
|
1476 uint8_t sa = s >> A_SHIFT; |
|
1477 uint8_t da = d >> A_SHIFT; |
|
1478 |
|
1479 switch (combine & COMBINE_A) |
|
1480 { |
|
1481 default: |
|
1482 Fa = 0; |
|
1483 break; |
|
1484 |
|
1485 case COMBINE_A_OUT: |
|
1486 Fa = combine_conjoint_out_part (sa, da); |
|
1487 break; |
|
1488 |
|
1489 case COMBINE_A_IN: |
|
1490 Fa = combine_conjoint_in_part (sa, da); |
|
1491 break; |
|
1492 |
|
1493 case COMBINE_A: |
|
1494 Fa = MASK; |
|
1495 break; |
|
1496 } |
|
1497 |
|
1498 switch (combine & COMBINE_B) |
|
1499 { |
|
1500 default: |
|
1501 Fb = 0; |
|
1502 break; |
|
1503 |
|
1504 case COMBINE_B_OUT: |
|
1505 Fb = combine_conjoint_out_part (da, sa); |
|
1506 break; |
|
1507 |
|
1508 case COMBINE_B_IN: |
|
1509 Fb = combine_conjoint_in_part (da, sa); |
|
1510 break; |
|
1511 |
|
1512 case COMBINE_B: |
|
1513 Fb = MASK; |
|
1514 break; |
|
1515 } |
|
1516 |
|
1517 m = GENERIC (s, d, 0, Fa, Fb, t, u, v); |
|
1518 n = GENERIC (s, d, G_SHIFT, Fa, Fb, t, u, v); |
|
1519 o = GENERIC (s, d, R_SHIFT, Fa, Fb, t, u, v); |
|
1520 p = GENERIC (s, d, A_SHIFT, Fa, Fb, t, u, v); |
|
1521 |
|
1522 s = m | n | o | p; |
|
1523 |
|
1524 *(dest + i) = s; |
|
1525 } |
|
1526 } |
|
1527 |
|
1528 static void |
|
1529 combine_conjoint_over_u (pixman_implementation_t *imp, |
|
1530 pixman_op_t op, |
|
1531 uint32_t * dest, |
|
1532 const uint32_t * src, |
|
1533 const uint32_t * mask, |
|
1534 int width) |
|
1535 { |
|
1536 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OVER); |
|
1537 } |
|
1538 |
|
1539 static void |
|
1540 combine_conjoint_over_reverse_u (pixman_implementation_t *imp, |
|
1541 pixman_op_t op, |
|
1542 uint32_t * dest, |
|
1543 const uint32_t * src, |
|
1544 const uint32_t * mask, |
|
1545 int width) |
|
1546 { |
|
1547 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OVER); |
|
1548 } |
|
1549 |
|
1550 static void |
|
1551 combine_conjoint_in_u (pixman_implementation_t *imp, |
|
1552 pixman_op_t op, |
|
1553 uint32_t * dest, |
|
1554 const uint32_t * src, |
|
1555 const uint32_t * mask, |
|
1556 int width) |
|
1557 { |
|
1558 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_IN); |
|
1559 } |
|
1560 |
|
1561 static void |
|
1562 combine_conjoint_in_reverse_u (pixman_implementation_t *imp, |
|
1563 pixman_op_t op, |
|
1564 uint32_t * dest, |
|
1565 const uint32_t * src, |
|
1566 const uint32_t * mask, |
|
1567 int width) |
|
1568 { |
|
1569 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_IN); |
|
1570 } |
|
1571 |
|
1572 static void |
|
1573 combine_conjoint_out_u (pixman_implementation_t *imp, |
|
1574 pixman_op_t op, |
|
1575 uint32_t * dest, |
|
1576 const uint32_t * src, |
|
1577 const uint32_t * mask, |
|
1578 int width) |
|
1579 { |
|
1580 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_OUT); |
|
1581 } |
|
1582 |
|
1583 static void |
|
1584 combine_conjoint_out_reverse_u (pixman_implementation_t *imp, |
|
1585 pixman_op_t op, |
|
1586 uint32_t * dest, |
|
1587 const uint32_t * src, |
|
1588 const uint32_t * mask, |
|
1589 int width) |
|
1590 { |
|
1591 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_OUT); |
|
1592 } |
|
1593 |
|
1594 static void |
|
1595 combine_conjoint_atop_u (pixman_implementation_t *imp, |
|
1596 pixman_op_t op, |
|
1597 uint32_t * dest, |
|
1598 const uint32_t * src, |
|
1599 const uint32_t * mask, |
|
1600 int width) |
|
1601 { |
|
1602 combine_conjoint_general_u (dest, src, mask, width, COMBINE_A_ATOP); |
|
1603 } |
|
1604 |
|
1605 static void |
|
1606 combine_conjoint_atop_reverse_u (pixman_implementation_t *imp, |
|
1607 pixman_op_t op, |
|
1608 uint32_t * dest, |
|
1609 const uint32_t * src, |
|
1610 const uint32_t * mask, |
|
1611 int width) |
|
1612 { |
|
1613 combine_conjoint_general_u (dest, src, mask, width, COMBINE_B_ATOP); |
|
1614 } |
|
1615 |
|
1616 static void |
|
1617 combine_conjoint_xor_u (pixman_implementation_t *imp, |
|
1618 pixman_op_t op, |
|
1619 uint32_t * dest, |
|
1620 const uint32_t * src, |
|
1621 const uint32_t * mask, |
|
1622 int width) |
|
1623 { |
|
1624 combine_conjoint_general_u (dest, src, mask, width, COMBINE_XOR); |
|
1625 } |
|
1626 |
|
1627 |
|
1628 /* Component alpha combiners */ |
|
1629 |
|
1630 static void |
|
1631 combine_clear_ca (pixman_implementation_t *imp, |
|
1632 pixman_op_t op, |
|
1633 uint32_t * dest, |
|
1634 const uint32_t * src, |
|
1635 const uint32_t * mask, |
|
1636 int width) |
|
1637 { |
|
1638 memset (dest, 0, width * sizeof(uint32_t)); |
|
1639 } |
|
1640 |
|
1641 static void |
|
1642 combine_src_ca (pixman_implementation_t *imp, |
|
1643 pixman_op_t op, |
|
1644 uint32_t * dest, |
|
1645 const uint32_t * src, |
|
1646 const uint32_t * mask, |
|
1647 int width) |
|
1648 { |
|
1649 int i; |
|
1650 |
|
1651 for (i = 0; i < width; ++i) |
|
1652 { |
|
1653 uint32_t s = *(src + i); |
|
1654 uint32_t m = *(mask + i); |
|
1655 |
|
1656 combine_mask_value_ca (&s, &m); |
|
1657 |
|
1658 *(dest + i) = s; |
|
1659 } |
|
1660 } |
|
1661 |
|
1662 static void |
|
1663 combine_over_ca (pixman_implementation_t *imp, |
|
1664 pixman_op_t op, |
|
1665 uint32_t * dest, |
|
1666 const uint32_t * src, |
|
1667 const uint32_t * mask, |
|
1668 int width) |
|
1669 { |
|
1670 int i; |
|
1671 |
|
1672 for (i = 0; i < width; ++i) |
|
1673 { |
|
1674 uint32_t s = *(src + i); |
|
1675 uint32_t m = *(mask + i); |
|
1676 uint32_t a; |
|
1677 |
|
1678 combine_mask_ca (&s, &m); |
|
1679 |
|
1680 a = ~m; |
|
1681 if (a) |
|
1682 { |
|
1683 uint32_t d = *(dest + i); |
|
1684 UN8x4_MUL_UN8x4_ADD_UN8x4 (d, a, s); |
|
1685 s = d; |
|
1686 } |
|
1687 |
|
1688 *(dest + i) = s; |
|
1689 } |
|
1690 } |
|
1691 |
|
1692 static void |
|
1693 combine_over_reverse_ca (pixman_implementation_t *imp, |
|
1694 pixman_op_t op, |
|
1695 uint32_t * dest, |
|
1696 const uint32_t * src, |
|
1697 const uint32_t * mask, |
|
1698 int width) |
|
1699 { |
|
1700 int i; |
|
1701 |
|
1702 for (i = 0; i < width; ++i) |
|
1703 { |
|
1704 uint32_t d = *(dest + i); |
|
1705 uint32_t a = ~d >> A_SHIFT; |
|
1706 |
|
1707 if (a) |
|
1708 { |
|
1709 uint32_t s = *(src + i); |
|
1710 uint32_t m = *(mask + i); |
|
1711 |
|
1712 UN8x4_MUL_UN8x4 (s, m); |
|
1713 UN8x4_MUL_UN8_ADD_UN8x4 (s, a, d); |
|
1714 |
|
1715 *(dest + i) = s; |
|
1716 } |
|
1717 } |
|
1718 } |
|
1719 |
|
1720 static void |
|
1721 combine_in_ca (pixman_implementation_t *imp, |
|
1722 pixman_op_t op, |
|
1723 uint32_t * dest, |
|
1724 const uint32_t * src, |
|
1725 const uint32_t * mask, |
|
1726 int width) |
|
1727 { |
|
1728 int i; |
|
1729 |
|
1730 for (i = 0; i < width; ++i) |
|
1731 { |
|
1732 uint32_t d = *(dest + i); |
|
1733 uint16_t a = d >> A_SHIFT; |
|
1734 uint32_t s = 0; |
|
1735 |
|
1736 if (a) |
|
1737 { |
|
1738 uint32_t m = *(mask + i); |
|
1739 |
|
1740 s = *(src + i); |
|
1741 combine_mask_value_ca (&s, &m); |
|
1742 |
|
1743 if (a != MASK) |
|
1744 UN8x4_MUL_UN8 (s, a); |
|
1745 } |
|
1746 |
|
1747 *(dest + i) = s; |
|
1748 } |
|
1749 } |
|
1750 |
|
1751 static void |
|
1752 combine_in_reverse_ca (pixman_implementation_t *imp, |
|
1753 pixman_op_t op, |
|
1754 uint32_t * dest, |
|
1755 const uint32_t * src, |
|
1756 const uint32_t * mask, |
|
1757 int width) |
|
1758 { |
|
1759 int i; |
|
1760 |
|
1761 for (i = 0; i < width; ++i) |
|
1762 { |
|
1763 uint32_t s = *(src + i); |
|
1764 uint32_t m = *(mask + i); |
|
1765 uint32_t a; |
|
1766 |
|
1767 combine_mask_alpha_ca (&s, &m); |
|
1768 |
|
1769 a = m; |
|
1770 if (a != ~0) |
|
1771 { |
|
1772 uint32_t d = 0; |
|
1773 |
|
1774 if (a) |
|
1775 { |
|
1776 d = *(dest + i); |
|
1777 UN8x4_MUL_UN8x4 (d, a); |
|
1778 } |
|
1779 |
|
1780 *(dest + i) = d; |
|
1781 } |
|
1782 } |
|
1783 } |
|
1784 |
|
1785 static void |
|
1786 combine_out_ca (pixman_implementation_t *imp, |
|
1787 pixman_op_t op, |
|
1788 uint32_t * dest, |
|
1789 const uint32_t * src, |
|
1790 const uint32_t * mask, |
|
1791 int width) |
|
1792 { |
|
1793 int i; |
|
1794 |
|
1795 for (i = 0; i < width; ++i) |
|
1796 { |
|
1797 uint32_t d = *(dest + i); |
|
1798 uint16_t a = ~d >> A_SHIFT; |
|
1799 uint32_t s = 0; |
|
1800 |
|
1801 if (a) |
|
1802 { |
|
1803 uint32_t m = *(mask + i); |
|
1804 |
|
1805 s = *(src + i); |
|
1806 combine_mask_value_ca (&s, &m); |
|
1807 |
|
1808 if (a != MASK) |
|
1809 UN8x4_MUL_UN8 (s, a); |
|
1810 } |
|
1811 |
|
1812 *(dest + i) = s; |
|
1813 } |
|
1814 } |
|
1815 |
|
1816 static void |
|
1817 combine_out_reverse_ca (pixman_implementation_t *imp, |
|
1818 pixman_op_t op, |
|
1819 uint32_t * dest, |
|
1820 const uint32_t * src, |
|
1821 const uint32_t * mask, |
|
1822 int width) |
|
1823 { |
|
1824 int i; |
|
1825 |
|
1826 for (i = 0; i < width; ++i) |
|
1827 { |
|
1828 uint32_t s = *(src + i); |
|
1829 uint32_t m = *(mask + i); |
|
1830 uint32_t a; |
|
1831 |
|
1832 combine_mask_alpha_ca (&s, &m); |
|
1833 |
|
1834 a = ~m; |
|
1835 if (a != ~0) |
|
1836 { |
|
1837 uint32_t d = 0; |
|
1838 |
|
1839 if (a) |
|
1840 { |
|
1841 d = *(dest + i); |
|
1842 UN8x4_MUL_UN8x4 (d, a); |
|
1843 } |
|
1844 |
|
1845 *(dest + i) = d; |
|
1846 } |
|
1847 } |
|
1848 } |
|
1849 |
|
1850 static void |
|
1851 combine_atop_ca (pixman_implementation_t *imp, |
|
1852 pixman_op_t op, |
|
1853 uint32_t * dest, |
|
1854 const uint32_t * src, |
|
1855 const uint32_t * mask, |
|
1856 int width) |
|
1857 { |
|
1858 int i; |
|
1859 |
|
1860 for (i = 0; i < width; ++i) |
|
1861 { |
|
1862 uint32_t d = *(dest + i); |
|
1863 uint32_t s = *(src + i); |
|
1864 uint32_t m = *(mask + i); |
|
1865 uint32_t ad; |
|
1866 uint16_t as = d >> A_SHIFT; |
|
1867 |
|
1868 combine_mask_ca (&s, &m); |
|
1869 |
|
1870 ad = ~m; |
|
1871 |
|
1872 UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ad, s, as); |
|
1873 |
|
1874 *(dest + i) = d; |
|
1875 } |
|
1876 } |
|
1877 |
|
1878 static void |
|
1879 combine_atop_reverse_ca (pixman_implementation_t *imp, |
|
1880 pixman_op_t op, |
|
1881 uint32_t * dest, |
|
1882 const uint32_t * src, |
|
1883 const uint32_t * mask, |
|
1884 int width) |
|
1885 { |
|
1886 int i; |
|
1887 |
|
1888 for (i = 0; i < width; ++i) |
|
1889 { |
|
1890 uint32_t d = *(dest + i); |
|
1891 uint32_t s = *(src + i); |
|
1892 uint32_t m = *(mask + i); |
|
1893 uint32_t ad; |
|
1894 uint16_t as = ~d >> A_SHIFT; |
|
1895 |
|
1896 combine_mask_ca (&s, &m); |
|
1897 |
|
1898 ad = m; |
|
1899 |
|
1900 UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ad, s, as); |
|
1901 |
|
1902 *(dest + i) = d; |
|
1903 } |
|
1904 } |
|
1905 |
|
1906 static void |
|
1907 combine_xor_ca (pixman_implementation_t *imp, |
|
1908 pixman_op_t op, |
|
1909 uint32_t * dest, |
|
1910 const uint32_t * src, |
|
1911 const uint32_t * mask, |
|
1912 int width) |
|
1913 { |
|
1914 int i; |
|
1915 |
|
1916 for (i = 0; i < width; ++i) |
|
1917 { |
|
1918 uint32_t d = *(dest + i); |
|
1919 uint32_t s = *(src + i); |
|
1920 uint32_t m = *(mask + i); |
|
1921 uint32_t ad; |
|
1922 uint16_t as = ~d >> A_SHIFT; |
|
1923 |
|
1924 combine_mask_ca (&s, &m); |
|
1925 |
|
1926 ad = ~m; |
|
1927 |
|
1928 UN8x4_MUL_UN8x4_ADD_UN8x4_MUL_UN8 (d, ad, s, as); |
|
1929 |
|
1930 *(dest + i) = d; |
|
1931 } |
|
1932 } |
|
1933 |
|
1934 static void |
|
1935 combine_add_ca (pixman_implementation_t *imp, |
|
1936 pixman_op_t op, |
|
1937 uint32_t * dest, |
|
1938 const uint32_t * src, |
|
1939 const uint32_t * mask, |
|
1940 int width) |
|
1941 { |
|
1942 int i; |
|
1943 |
|
1944 for (i = 0; i < width; ++i) |
|
1945 { |
|
1946 uint32_t s = *(src + i); |
|
1947 uint32_t m = *(mask + i); |
|
1948 uint32_t d = *(dest + i); |
|
1949 |
|
1950 combine_mask_value_ca (&s, &m); |
|
1951 |
|
1952 UN8x4_ADD_UN8x4 (d, s); |
|
1953 |
|
1954 *(dest + i) = d; |
|
1955 } |
|
1956 } |
|
1957 |
|
1958 static void |
|
1959 combine_saturate_ca (pixman_implementation_t *imp, |
|
1960 pixman_op_t op, |
|
1961 uint32_t * dest, |
|
1962 const uint32_t * src, |
|
1963 const uint32_t * mask, |
|
1964 int width) |
|
1965 { |
|
1966 int i; |
|
1967 |
|
1968 for (i = 0; i < width; ++i) |
|
1969 { |
|
1970 uint32_t s, d; |
|
1971 uint16_t sa, sr, sg, sb, da; |
|
1972 uint16_t t, u, v; |
|
1973 uint32_t m, n, o, p; |
|
1974 |
|
1975 d = *(dest + i); |
|
1976 s = *(src + i); |
|
1977 m = *(mask + i); |
|
1978 |
|
1979 combine_mask_ca (&s, &m); |
|
1980 |
|
1981 sa = (m >> A_SHIFT); |
|
1982 sr = (m >> R_SHIFT) & MASK; |
|
1983 sg = (m >> G_SHIFT) & MASK; |
|
1984 sb = m & MASK; |
|
1985 da = ~d >> A_SHIFT; |
|
1986 |
|
1987 if (sb <= da) |
|
1988 m = ADD (s, d, 0, t); |
|
1989 else |
|
1990 m = GENERIC (s, d, 0, (da << G_SHIFT) / sb, MASK, t, u, v); |
|
1991 |
|
1992 if (sg <= da) |
|
1993 n = ADD (s, d, G_SHIFT, t); |
|
1994 else |
|
1995 n = GENERIC (s, d, G_SHIFT, (da << G_SHIFT) / sg, MASK, t, u, v); |
|
1996 |
|
1997 if (sr <= da) |
|
1998 o = ADD (s, d, R_SHIFT, t); |
|
1999 else |
|
2000 o = GENERIC (s, d, R_SHIFT, (da << G_SHIFT) / sr, MASK, t, u, v); |
|
2001 |
|
2002 if (sa <= da) |
|
2003 p = ADD (s, d, A_SHIFT, t); |
|
2004 else |
|
2005 p = GENERIC (s, d, A_SHIFT, (da << G_SHIFT) / sa, MASK, t, u, v); |
|
2006 |
|
2007 *(dest + i) = m | n | o | p; |
|
2008 } |
|
2009 } |
|
2010 |
|
2011 static void |
|
2012 combine_disjoint_general_ca (uint32_t * dest, |
|
2013 const uint32_t *src, |
|
2014 const uint32_t *mask, |
|
2015 int width, |
|
2016 uint8_t combine) |
|
2017 { |
|
2018 int i; |
|
2019 |
|
2020 for (i = 0; i < width; ++i) |
|
2021 { |
|
2022 uint32_t s, d; |
|
2023 uint32_t m, n, o, p; |
|
2024 uint32_t Fa, Fb; |
|
2025 uint16_t t, u, v; |
|
2026 uint32_t sa; |
|
2027 uint8_t da; |
|
2028 |
|
2029 s = *(src + i); |
|
2030 m = *(mask + i); |
|
2031 d = *(dest + i); |
|
2032 da = d >> A_SHIFT; |
|
2033 |
|
2034 combine_mask_ca (&s, &m); |
|
2035 |
|
2036 sa = m; |
|
2037 |
|
2038 switch (combine & COMBINE_A) |
|
2039 { |
|
2040 default: |
|
2041 Fa = 0; |
|
2042 break; |
|
2043 |
|
2044 case COMBINE_A_OUT: |
|
2045 m = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> 0), da); |
|
2046 n = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT; |
|
2047 o = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT; |
|
2048 p = (uint32_t)combine_disjoint_out_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT; |
|
2049 Fa = m | n | o | p; |
|
2050 break; |
|
2051 |
|
2052 case COMBINE_A_IN: |
|
2053 m = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> 0), da); |
|
2054 n = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT; |
|
2055 o = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT; |
|
2056 p = (uint32_t)combine_disjoint_in_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT; |
|
2057 Fa = m | n | o | p; |
|
2058 break; |
|
2059 |
|
2060 case COMBINE_A: |
|
2061 Fa = ~0; |
|
2062 break; |
|
2063 } |
|
2064 |
|
2065 switch (combine & COMBINE_B) |
|
2066 { |
|
2067 default: |
|
2068 Fb = 0; |
|
2069 break; |
|
2070 |
|
2071 case COMBINE_B_OUT: |
|
2072 m = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> 0)); |
|
2073 n = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT; |
|
2074 o = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT; |
|
2075 p = (uint32_t)combine_disjoint_out_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT; |
|
2076 Fb = m | n | o | p; |
|
2077 break; |
|
2078 |
|
2079 case COMBINE_B_IN: |
|
2080 m = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> 0)); |
|
2081 n = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT; |
|
2082 o = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT; |
|
2083 p = (uint32_t)combine_disjoint_in_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT; |
|
2084 Fb = m | n | o | p; |
|
2085 break; |
|
2086 |
|
2087 case COMBINE_B: |
|
2088 Fb = ~0; |
|
2089 break; |
|
2090 } |
|
2091 m = GENERIC (s, d, 0, GET_COMP (Fa, 0), GET_COMP (Fb, 0), t, u, v); |
|
2092 n = GENERIC (s, d, G_SHIFT, GET_COMP (Fa, G_SHIFT), GET_COMP (Fb, G_SHIFT), t, u, v); |
|
2093 o = GENERIC (s, d, R_SHIFT, GET_COMP (Fa, R_SHIFT), GET_COMP (Fb, R_SHIFT), t, u, v); |
|
2094 p = GENERIC (s, d, A_SHIFT, GET_COMP (Fa, A_SHIFT), GET_COMP (Fb, A_SHIFT), t, u, v); |
|
2095 |
|
2096 s = m | n | o | p; |
|
2097 |
|
2098 *(dest + i) = s; |
|
2099 } |
|
2100 } |
|
2101 |
|
2102 static void |
|
2103 combine_disjoint_over_ca (pixman_implementation_t *imp, |
|
2104 pixman_op_t op, |
|
2105 uint32_t * dest, |
|
2106 const uint32_t * src, |
|
2107 const uint32_t * mask, |
|
2108 int width) |
|
2109 { |
|
2110 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER); |
|
2111 } |
|
2112 |
|
2113 static void |
|
2114 combine_disjoint_in_ca (pixman_implementation_t *imp, |
|
2115 pixman_op_t op, |
|
2116 uint32_t * dest, |
|
2117 const uint32_t * src, |
|
2118 const uint32_t * mask, |
|
2119 int width) |
|
2120 { |
|
2121 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_IN); |
|
2122 } |
|
2123 |
|
2124 static void |
|
2125 combine_disjoint_in_reverse_ca (pixman_implementation_t *imp, |
|
2126 pixman_op_t op, |
|
2127 uint32_t * dest, |
|
2128 const uint32_t * src, |
|
2129 const uint32_t * mask, |
|
2130 int width) |
|
2131 { |
|
2132 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_IN); |
|
2133 } |
|
2134 |
|
2135 static void |
|
2136 combine_disjoint_out_ca (pixman_implementation_t *imp, |
|
2137 pixman_op_t op, |
|
2138 uint32_t * dest, |
|
2139 const uint32_t * src, |
|
2140 const uint32_t * mask, |
|
2141 int width) |
|
2142 { |
|
2143 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT); |
|
2144 } |
|
2145 |
|
2146 static void |
|
2147 combine_disjoint_out_reverse_ca (pixman_implementation_t *imp, |
|
2148 pixman_op_t op, |
|
2149 uint32_t * dest, |
|
2150 const uint32_t * src, |
|
2151 const uint32_t * mask, |
|
2152 int width) |
|
2153 { |
|
2154 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT); |
|
2155 } |
|
2156 |
|
2157 static void |
|
2158 combine_disjoint_atop_ca (pixman_implementation_t *imp, |
|
2159 pixman_op_t op, |
|
2160 uint32_t * dest, |
|
2161 const uint32_t * src, |
|
2162 const uint32_t * mask, |
|
2163 int width) |
|
2164 { |
|
2165 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP); |
|
2166 } |
|
2167 |
|
2168 static void |
|
2169 combine_disjoint_atop_reverse_ca (pixman_implementation_t *imp, |
|
2170 pixman_op_t op, |
|
2171 uint32_t * dest, |
|
2172 const uint32_t * src, |
|
2173 const uint32_t * mask, |
|
2174 int width) |
|
2175 { |
|
2176 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP); |
|
2177 } |
|
2178 |
|
2179 static void |
|
2180 combine_disjoint_xor_ca (pixman_implementation_t *imp, |
|
2181 pixman_op_t op, |
|
2182 uint32_t * dest, |
|
2183 const uint32_t * src, |
|
2184 const uint32_t * mask, |
|
2185 int width) |
|
2186 { |
|
2187 combine_disjoint_general_ca (dest, src, mask, width, COMBINE_XOR); |
|
2188 } |
|
2189 |
|
2190 static void |
|
2191 combine_conjoint_general_ca (uint32_t * dest, |
|
2192 const uint32_t *src, |
|
2193 const uint32_t *mask, |
|
2194 int width, |
|
2195 uint8_t combine) |
|
2196 { |
|
2197 int i; |
|
2198 |
|
2199 for (i = 0; i < width; ++i) |
|
2200 { |
|
2201 uint32_t s, d; |
|
2202 uint32_t m, n, o, p; |
|
2203 uint32_t Fa, Fb; |
|
2204 uint16_t t, u, v; |
|
2205 uint32_t sa; |
|
2206 uint8_t da; |
|
2207 |
|
2208 s = *(src + i); |
|
2209 m = *(mask + i); |
|
2210 d = *(dest + i); |
|
2211 da = d >> A_SHIFT; |
|
2212 |
|
2213 combine_mask_ca (&s, &m); |
|
2214 |
|
2215 sa = m; |
|
2216 |
|
2217 switch (combine & COMBINE_A) |
|
2218 { |
|
2219 default: |
|
2220 Fa = 0; |
|
2221 break; |
|
2222 |
|
2223 case COMBINE_A_OUT: |
|
2224 m = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> 0), da); |
|
2225 n = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT; |
|
2226 o = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT; |
|
2227 p = (uint32_t)combine_conjoint_out_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT; |
|
2228 Fa = m | n | o | p; |
|
2229 break; |
|
2230 |
|
2231 case COMBINE_A_IN: |
|
2232 m = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> 0), da); |
|
2233 n = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> G_SHIFT), da) << G_SHIFT; |
|
2234 o = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> R_SHIFT), da) << R_SHIFT; |
|
2235 p = (uint32_t)combine_conjoint_in_part ((uint8_t) (sa >> A_SHIFT), da) << A_SHIFT; |
|
2236 Fa = m | n | o | p; |
|
2237 break; |
|
2238 |
|
2239 case COMBINE_A: |
|
2240 Fa = ~0; |
|
2241 break; |
|
2242 } |
|
2243 |
|
2244 switch (combine & COMBINE_B) |
|
2245 { |
|
2246 default: |
|
2247 Fb = 0; |
|
2248 break; |
|
2249 |
|
2250 case COMBINE_B_OUT: |
|
2251 m = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> 0)); |
|
2252 n = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT; |
|
2253 o = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT; |
|
2254 p = (uint32_t)combine_conjoint_out_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT; |
|
2255 Fb = m | n | o | p; |
|
2256 break; |
|
2257 |
|
2258 case COMBINE_B_IN: |
|
2259 m = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> 0)); |
|
2260 n = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> G_SHIFT)) << G_SHIFT; |
|
2261 o = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> R_SHIFT)) << R_SHIFT; |
|
2262 p = (uint32_t)combine_conjoint_in_part (da, (uint8_t) (sa >> A_SHIFT)) << A_SHIFT; |
|
2263 Fb = m | n | o | p; |
|
2264 break; |
|
2265 |
|
2266 case COMBINE_B: |
|
2267 Fb = ~0; |
|
2268 break; |
|
2269 } |
|
2270 m = GENERIC (s, d, 0, GET_COMP (Fa, 0), GET_COMP (Fb, 0), t, u, v); |
|
2271 n = GENERIC (s, d, G_SHIFT, GET_COMP (Fa, G_SHIFT), GET_COMP (Fb, G_SHIFT), t, u, v); |
|
2272 o = GENERIC (s, d, R_SHIFT, GET_COMP (Fa, R_SHIFT), GET_COMP (Fb, R_SHIFT), t, u, v); |
|
2273 p = GENERIC (s, d, A_SHIFT, GET_COMP (Fa, A_SHIFT), GET_COMP (Fb, A_SHIFT), t, u, v); |
|
2274 |
|
2275 s = m | n | o | p; |
|
2276 |
|
2277 *(dest + i) = s; |
|
2278 } |
|
2279 } |
|
2280 |
|
2281 static void |
|
2282 combine_conjoint_over_ca (pixman_implementation_t *imp, |
|
2283 pixman_op_t op, |
|
2284 uint32_t * dest, |
|
2285 const uint32_t * src, |
|
2286 const uint32_t * mask, |
|
2287 int width) |
|
2288 { |
|
2289 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OVER); |
|
2290 } |
|
2291 |
|
2292 static void |
|
2293 combine_conjoint_over_reverse_ca (pixman_implementation_t *imp, |
|
2294 pixman_op_t op, |
|
2295 uint32_t * dest, |
|
2296 const uint32_t * src, |
|
2297 const uint32_t * mask, |
|
2298 int width) |
|
2299 { |
|
2300 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OVER); |
|
2301 } |
|
2302 |
|
2303 static void |
|
2304 combine_conjoint_in_ca (pixman_implementation_t *imp, |
|
2305 pixman_op_t op, |
|
2306 uint32_t * dest, |
|
2307 const uint32_t * src, |
|
2308 const uint32_t * mask, |
|
2309 int width) |
|
2310 { |
|
2311 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_IN); |
|
2312 } |
|
2313 |
|
2314 static void |
|
2315 combine_conjoint_in_reverse_ca (pixman_implementation_t *imp, |
|
2316 pixman_op_t op, |
|
2317 uint32_t * dest, |
|
2318 const uint32_t * src, |
|
2319 const uint32_t * mask, |
|
2320 int width) |
|
2321 { |
|
2322 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_IN); |
|
2323 } |
|
2324 |
|
2325 static void |
|
2326 combine_conjoint_out_ca (pixman_implementation_t *imp, |
|
2327 pixman_op_t op, |
|
2328 uint32_t * dest, |
|
2329 const uint32_t * src, |
|
2330 const uint32_t * mask, |
|
2331 int width) |
|
2332 { |
|
2333 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_OUT); |
|
2334 } |
|
2335 |
|
2336 static void |
|
2337 combine_conjoint_out_reverse_ca (pixman_implementation_t *imp, |
|
2338 pixman_op_t op, |
|
2339 uint32_t * dest, |
|
2340 const uint32_t * src, |
|
2341 const uint32_t * mask, |
|
2342 int width) |
|
2343 { |
|
2344 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_OUT); |
|
2345 } |
|
2346 |
|
2347 static void |
|
2348 combine_conjoint_atop_ca (pixman_implementation_t *imp, |
|
2349 pixman_op_t op, |
|
2350 uint32_t * dest, |
|
2351 const uint32_t * src, |
|
2352 const uint32_t * mask, |
|
2353 int width) |
|
2354 { |
|
2355 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_A_ATOP); |
|
2356 } |
|
2357 |
|
2358 static void |
|
2359 combine_conjoint_atop_reverse_ca (pixman_implementation_t *imp, |
|
2360 pixman_op_t op, |
|
2361 uint32_t * dest, |
|
2362 const uint32_t * src, |
|
2363 const uint32_t * mask, |
|
2364 int width) |
|
2365 { |
|
2366 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_B_ATOP); |
|
2367 } |
|
2368 |
|
2369 static void |
|
2370 combine_conjoint_xor_ca (pixman_implementation_t *imp, |
|
2371 pixman_op_t op, |
|
2372 uint32_t * dest, |
|
2373 const uint32_t * src, |
|
2374 const uint32_t * mask, |
|
2375 int width) |
|
2376 { |
|
2377 combine_conjoint_general_ca (dest, src, mask, width, COMBINE_XOR); |
|
2378 } |
|
2379 |
|
2380 void |
|
2381 _pixman_setup_combiner_functions_32 (pixman_implementation_t *imp) |
|
2382 { |
|
2383 /* Unified alpha */ |
|
2384 imp->combine_32[PIXMAN_OP_CLEAR] = combine_clear; |
|
2385 imp->combine_32[PIXMAN_OP_SRC] = combine_src_u; |
|
2386 imp->combine_32[PIXMAN_OP_DST] = combine_dst; |
|
2387 imp->combine_32[PIXMAN_OP_OVER] = combine_over_u; |
|
2388 imp->combine_32[PIXMAN_OP_OVER_REVERSE] = combine_over_reverse_u; |
|
2389 imp->combine_32[PIXMAN_OP_IN] = combine_in_u; |
|
2390 imp->combine_32[PIXMAN_OP_IN_REVERSE] = combine_in_reverse_u; |
|
2391 imp->combine_32[PIXMAN_OP_OUT] = combine_out_u; |
|
2392 imp->combine_32[PIXMAN_OP_OUT_REVERSE] = combine_out_reverse_u; |
|
2393 imp->combine_32[PIXMAN_OP_ATOP] = combine_atop_u; |
|
2394 imp->combine_32[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_u; |
|
2395 imp->combine_32[PIXMAN_OP_XOR] = combine_xor_u; |
|
2396 imp->combine_32[PIXMAN_OP_ADD] = combine_add_u; |
|
2397 imp->combine_32[PIXMAN_OP_SATURATE] = combine_saturate_u; |
|
2398 |
|
2399 /* Disjoint, unified */ |
|
2400 imp->combine_32[PIXMAN_OP_DISJOINT_CLEAR] = combine_clear; |
|
2401 imp->combine_32[PIXMAN_OP_DISJOINT_SRC] = combine_src_u; |
|
2402 imp->combine_32[PIXMAN_OP_DISJOINT_DST] = combine_dst; |
|
2403 imp->combine_32[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_u; |
|
2404 imp->combine_32[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_saturate_u; |
|
2405 imp->combine_32[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_u; |
|
2406 imp->combine_32[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_u; |
|
2407 imp->combine_32[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_u; |
|
2408 imp->combine_32[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_u; |
|
2409 imp->combine_32[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_u; |
|
2410 imp->combine_32[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_u; |
|
2411 imp->combine_32[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_u; |
|
2412 |
|
2413 /* Conjoint, unified */ |
|
2414 imp->combine_32[PIXMAN_OP_CONJOINT_CLEAR] = combine_clear; |
|
2415 imp->combine_32[PIXMAN_OP_CONJOINT_SRC] = combine_src_u; |
|
2416 imp->combine_32[PIXMAN_OP_CONJOINT_DST] = combine_dst; |
|
2417 imp->combine_32[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_u; |
|
2418 imp->combine_32[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_u; |
|
2419 imp->combine_32[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_u; |
|
2420 imp->combine_32[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_u; |
|
2421 imp->combine_32[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_u; |
|
2422 imp->combine_32[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_u; |
|
2423 imp->combine_32[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_u; |
|
2424 imp->combine_32[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_u; |
|
2425 imp->combine_32[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_u; |
|
2426 |
|
2427 imp->combine_32[PIXMAN_OP_MULTIPLY] = combine_multiply_u; |
|
2428 imp->combine_32[PIXMAN_OP_SCREEN] = combine_screen_u; |
|
2429 imp->combine_32[PIXMAN_OP_OVERLAY] = combine_overlay_u; |
|
2430 imp->combine_32[PIXMAN_OP_DARKEN] = combine_darken_u; |
|
2431 imp->combine_32[PIXMAN_OP_LIGHTEN] = combine_lighten_u; |
|
2432 imp->combine_32[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_u; |
|
2433 imp->combine_32[PIXMAN_OP_COLOR_BURN] = combine_color_burn_u; |
|
2434 imp->combine_32[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_u; |
|
2435 imp->combine_32[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_u; |
|
2436 imp->combine_32[PIXMAN_OP_DIFFERENCE] = combine_difference_u; |
|
2437 imp->combine_32[PIXMAN_OP_EXCLUSION] = combine_exclusion_u; |
|
2438 imp->combine_32[PIXMAN_OP_HSL_HUE] = combine_hsl_hue_u; |
|
2439 imp->combine_32[PIXMAN_OP_HSL_SATURATION] = combine_hsl_saturation_u; |
|
2440 imp->combine_32[PIXMAN_OP_HSL_COLOR] = combine_hsl_color_u; |
|
2441 imp->combine_32[PIXMAN_OP_HSL_LUMINOSITY] = combine_hsl_luminosity_u; |
|
2442 |
|
2443 /* Component alpha combiners */ |
|
2444 imp->combine_32_ca[PIXMAN_OP_CLEAR] = combine_clear_ca; |
|
2445 imp->combine_32_ca[PIXMAN_OP_SRC] = combine_src_ca; |
|
2446 /* dest */ |
|
2447 imp->combine_32_ca[PIXMAN_OP_OVER] = combine_over_ca; |
|
2448 imp->combine_32_ca[PIXMAN_OP_OVER_REVERSE] = combine_over_reverse_ca; |
|
2449 imp->combine_32_ca[PIXMAN_OP_IN] = combine_in_ca; |
|
2450 imp->combine_32_ca[PIXMAN_OP_IN_REVERSE] = combine_in_reverse_ca; |
|
2451 imp->combine_32_ca[PIXMAN_OP_OUT] = combine_out_ca; |
|
2452 imp->combine_32_ca[PIXMAN_OP_OUT_REVERSE] = combine_out_reverse_ca; |
|
2453 imp->combine_32_ca[PIXMAN_OP_ATOP] = combine_atop_ca; |
|
2454 imp->combine_32_ca[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_ca; |
|
2455 imp->combine_32_ca[PIXMAN_OP_XOR] = combine_xor_ca; |
|
2456 imp->combine_32_ca[PIXMAN_OP_ADD] = combine_add_ca; |
|
2457 imp->combine_32_ca[PIXMAN_OP_SATURATE] = combine_saturate_ca; |
|
2458 |
|
2459 /* Disjoint CA */ |
|
2460 imp->combine_32_ca[PIXMAN_OP_DISJOINT_CLEAR] = combine_clear_ca; |
|
2461 imp->combine_32_ca[PIXMAN_OP_DISJOINT_SRC] = combine_src_ca; |
|
2462 imp->combine_32_ca[PIXMAN_OP_DISJOINT_DST] = combine_dst; |
|
2463 imp->combine_32_ca[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_ca; |
|
2464 imp->combine_32_ca[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_saturate_ca; |
|
2465 imp->combine_32_ca[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_ca; |
|
2466 imp->combine_32_ca[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_ca; |
|
2467 imp->combine_32_ca[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_ca; |
|
2468 imp->combine_32_ca[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_ca; |
|
2469 imp->combine_32_ca[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_ca; |
|
2470 imp->combine_32_ca[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_ca; |
|
2471 imp->combine_32_ca[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_ca; |
|
2472 |
|
2473 /* Conjoint CA */ |
|
2474 imp->combine_32_ca[PIXMAN_OP_CONJOINT_CLEAR] = combine_clear_ca; |
|
2475 imp->combine_32_ca[PIXMAN_OP_CONJOINT_SRC] = combine_src_ca; |
|
2476 imp->combine_32_ca[PIXMAN_OP_CONJOINT_DST] = combine_dst; |
|
2477 imp->combine_32_ca[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_ca; |
|
2478 imp->combine_32_ca[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_ca; |
|
2479 imp->combine_32_ca[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_ca; |
|
2480 imp->combine_32_ca[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_ca; |
|
2481 imp->combine_32_ca[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_ca; |
|
2482 imp->combine_32_ca[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_ca; |
|
2483 imp->combine_32_ca[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_ca; |
|
2484 imp->combine_32_ca[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_ca; |
|
2485 imp->combine_32_ca[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_ca; |
|
2486 |
|
2487 imp->combine_32_ca[PIXMAN_OP_MULTIPLY] = combine_multiply_ca; |
|
2488 imp->combine_32_ca[PIXMAN_OP_SCREEN] = combine_screen_ca; |
|
2489 imp->combine_32_ca[PIXMAN_OP_OVERLAY] = combine_overlay_ca; |
|
2490 imp->combine_32_ca[PIXMAN_OP_DARKEN] = combine_darken_ca; |
|
2491 imp->combine_32_ca[PIXMAN_OP_LIGHTEN] = combine_lighten_ca; |
|
2492 imp->combine_32_ca[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_ca; |
|
2493 imp->combine_32_ca[PIXMAN_OP_COLOR_BURN] = combine_color_burn_ca; |
|
2494 imp->combine_32_ca[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_ca; |
|
2495 imp->combine_32_ca[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_ca; |
|
2496 imp->combine_32_ca[PIXMAN_OP_DIFFERENCE] = combine_difference_ca; |
|
2497 imp->combine_32_ca[PIXMAN_OP_EXCLUSION] = combine_exclusion_ca; |
|
2498 |
|
2499 /* It is not clear that these make sense, so make them noops for now */ |
|
2500 imp->combine_32_ca[PIXMAN_OP_HSL_HUE] = combine_dst; |
|
2501 imp->combine_32_ca[PIXMAN_OP_HSL_SATURATION] = combine_dst; |
|
2502 imp->combine_32_ca[PIXMAN_OP_HSL_COLOR] = combine_dst; |
|
2503 imp->combine_32_ca[PIXMAN_OP_HSL_LUMINOSITY] = combine_dst; |
|
2504 } |