1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/cairo/libpixman/src/pixman-combine-float.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1018 @@ 1.4 +/* -*- Mode: c; c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t; -*- */ 1.5 +/* 1.6 + * Copyright © 2010, 2012 Soren Sandmann Pedersen 1.7 + * Copyright © 2010, 2012 Red Hat, Inc. 1.8 + * 1.9 + * Permission is hereby granted, free of charge, to any person obtaining a 1.10 + * copy of this software and associated documentation files (the "Software"), 1.11 + * to deal in the Software without restriction, including without limitation 1.12 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, 1.13 + * and/or sell copies of the Software, and to permit persons to whom the 1.14 + * Software is furnished to do so, subject to the following conditions: 1.15 + * 1.16 + * The above copyright notice and this permission notice (including the next 1.17 + * paragraph) shall be included in all copies or substantial portions of the 1.18 + * Software. 1.19 + * 1.20 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1.21 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1.22 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 1.23 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1.24 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 1.25 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 1.26 + * DEALINGS IN THE SOFTWARE. 1.27 + * 1.28 + * Author: Soren Sandmann Pedersen (sandmann@cs.au.dk) 1.29 + */ 1.30 + 1.31 +#ifdef HAVE_CONFIG_H 1.32 +#include <config.h> 1.33 +#endif 1.34 + 1.35 +#include <math.h> 1.36 +#include <string.h> 1.37 +#include <float.h> 1.38 + 1.39 +#include "pixman-private.h" 1.40 + 1.41 +/* Workaround for http://gcc.gnu.org/PR54965 */ 1.42 +/* GCC 4.6 has problems with force_inline, so just use normal inline instead */ 1.43 +#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 6) 1.44 +#undef force_inline 1.45 +#define force_inline __inline__ 1.46 +#endif 1.47 + 1.48 +#define IS_ZERO(f) (-FLT_MIN < (f) && (f) < FLT_MIN) 1.49 + 1.50 +typedef float (* combine_channel_t) (float sa, float s, float da, float d); 1.51 + 1.52 +static force_inline void 1.53 +combine_inner (pixman_bool_t component, 1.54 + float *dest, const float *src, const float *mask, int n_pixels, 1.55 + combine_channel_t combine_a, combine_channel_t combine_c) 1.56 +{ 1.57 + int i; 1.58 + 1.59 + if (!mask) 1.60 + { 1.61 + for (i = 0; i < 4 * n_pixels; i += 4) 1.62 + { 1.63 + float sa = src[i + 0]; 1.64 + float sr = src[i + 1]; 1.65 + float sg = src[i + 2]; 1.66 + float sb = src[i + 3]; 1.67 + 1.68 + float da = dest[i + 0]; 1.69 + float dr = dest[i + 1]; 1.70 + float dg = dest[i + 2]; 1.71 + float db = dest[i + 3]; 1.72 + 1.73 + dest[i + 0] = combine_a (sa, sa, da, da); 1.74 + dest[i + 1] = combine_c (sa, sr, da, dr); 1.75 + dest[i + 2] = combine_c (sa, sg, da, dg); 1.76 + dest[i + 3] = combine_c (sa, sb, da, db); 1.77 + } 1.78 + } 1.79 + else 1.80 + { 1.81 + for (i = 0; i < 4 * n_pixels; i += 4) 1.82 + { 1.83 + float sa, sr, sg, sb; 1.84 + float ma, mr, mg, mb; 1.85 + float da, dr, dg, db; 1.86 + 1.87 + sa = src[i + 0]; 1.88 + sr = src[i + 1]; 1.89 + sg = src[i + 2]; 1.90 + sb = src[i + 3]; 1.91 + 1.92 + if (component) 1.93 + { 1.94 + ma = mask[i + 0]; 1.95 + mr = mask[i + 1]; 1.96 + mg = mask[i + 2]; 1.97 + mb = mask[i + 3]; 1.98 + 1.99 + sr *= mr; 1.100 + sg *= mg; 1.101 + sb *= mb; 1.102 + 1.103 + ma *= sa; 1.104 + mr *= sa; 1.105 + mg *= sa; 1.106 + mb *= sa; 1.107 + 1.108 + sa = ma; 1.109 + } 1.110 + else 1.111 + { 1.112 + ma = mask[i + 0]; 1.113 + 1.114 + sa *= ma; 1.115 + sr *= ma; 1.116 + sg *= ma; 1.117 + sb *= ma; 1.118 + 1.119 + ma = mr = mg = mb = sa; 1.120 + } 1.121 + 1.122 + da = dest[i + 0]; 1.123 + dr = dest[i + 1]; 1.124 + dg = dest[i + 2]; 1.125 + db = dest[i + 3]; 1.126 + 1.127 + dest[i + 0] = combine_a (ma, sa, da, da); 1.128 + dest[i + 1] = combine_c (mr, sr, da, dr); 1.129 + dest[i + 2] = combine_c (mg, sg, da, dg); 1.130 + dest[i + 3] = combine_c (mb, sb, da, db); 1.131 + } 1.132 + } 1.133 +} 1.134 + 1.135 +#define MAKE_COMBINER(name, component, combine_a, combine_c) \ 1.136 + static void \ 1.137 + combine_ ## name ## _float (pixman_implementation_t *imp, \ 1.138 + pixman_op_t op, \ 1.139 + float *dest, \ 1.140 + const float *src, \ 1.141 + const float *mask, \ 1.142 + int n_pixels) \ 1.143 + { \ 1.144 + combine_inner (component, dest, src, mask, n_pixels, \ 1.145 + combine_a, combine_c); \ 1.146 + } 1.147 + 1.148 +#define MAKE_COMBINERS(name, combine_a, combine_c) \ 1.149 + MAKE_COMBINER(name ## _ca, TRUE, combine_a, combine_c) \ 1.150 + MAKE_COMBINER(name ## _u, FALSE, combine_a, combine_c) 1.151 + 1.152 + 1.153 +/* 1.154 + * Porter/Duff operators 1.155 + */ 1.156 +typedef enum 1.157 +{ 1.158 + ZERO, 1.159 + ONE, 1.160 + SRC_ALPHA, 1.161 + DEST_ALPHA, 1.162 + INV_SA, 1.163 + INV_DA, 1.164 + SA_OVER_DA, 1.165 + DA_OVER_SA, 1.166 + INV_SA_OVER_DA, 1.167 + INV_DA_OVER_SA, 1.168 + ONE_MINUS_SA_OVER_DA, 1.169 + ONE_MINUS_DA_OVER_SA, 1.170 + ONE_MINUS_INV_DA_OVER_SA, 1.171 + ONE_MINUS_INV_SA_OVER_DA 1.172 +} combine_factor_t; 1.173 + 1.174 +#define CLAMP(f) \ 1.175 + (((f) < 0)? 0 : (((f) > 1.0) ? 1.0 : (f))) 1.176 + 1.177 +static force_inline float 1.178 +get_factor (combine_factor_t factor, float sa, float da) 1.179 +{ 1.180 + float f = -1; 1.181 + 1.182 + switch (factor) 1.183 + { 1.184 + case ZERO: 1.185 + f = 0.0f; 1.186 + break; 1.187 + 1.188 + case ONE: 1.189 + f = 1.0f; 1.190 + break; 1.191 + 1.192 + case SRC_ALPHA: 1.193 + f = sa; 1.194 + break; 1.195 + 1.196 + case DEST_ALPHA: 1.197 + f = da; 1.198 + break; 1.199 + 1.200 + case INV_SA: 1.201 + f = 1 - sa; 1.202 + break; 1.203 + 1.204 + case INV_DA: 1.205 + f = 1 - da; 1.206 + break; 1.207 + 1.208 + case SA_OVER_DA: 1.209 + if (IS_ZERO (da)) 1.210 + f = 1.0f; 1.211 + else 1.212 + f = CLAMP (sa / da); 1.213 + break; 1.214 + 1.215 + case DA_OVER_SA: 1.216 + if (IS_ZERO (sa)) 1.217 + f = 1.0f; 1.218 + else 1.219 + f = CLAMP (da / sa); 1.220 + break; 1.221 + 1.222 + case INV_SA_OVER_DA: 1.223 + if (IS_ZERO (da)) 1.224 + f = 1.0f; 1.225 + else 1.226 + f = CLAMP ((1.0f - sa) / da); 1.227 + break; 1.228 + 1.229 + case INV_DA_OVER_SA: 1.230 + if (IS_ZERO (sa)) 1.231 + f = 1.0f; 1.232 + else 1.233 + f = CLAMP ((1.0f - da) / sa); 1.234 + break; 1.235 + 1.236 + case ONE_MINUS_SA_OVER_DA: 1.237 + if (IS_ZERO (da)) 1.238 + f = 0.0f; 1.239 + else 1.240 + f = CLAMP (1.0f - sa / da); 1.241 + break; 1.242 + 1.243 + case ONE_MINUS_DA_OVER_SA: 1.244 + if (IS_ZERO (sa)) 1.245 + f = 0.0f; 1.246 + else 1.247 + f = CLAMP (1.0f - da / sa); 1.248 + break; 1.249 + 1.250 + case ONE_MINUS_INV_DA_OVER_SA: 1.251 + if (IS_ZERO (sa)) 1.252 + f = 0.0f; 1.253 + else 1.254 + f = CLAMP (1.0f - (1.0f - da) / sa); 1.255 + break; 1.256 + 1.257 + case ONE_MINUS_INV_SA_OVER_DA: 1.258 + if (IS_ZERO (da)) 1.259 + f = 0.0f; 1.260 + else 1.261 + f = CLAMP (1.0f - (1.0f - sa) / da); 1.262 + break; 1.263 + } 1.264 + 1.265 + return f; 1.266 +} 1.267 + 1.268 +#define MAKE_PD_COMBINERS(name, a, b) \ 1.269 + static float force_inline \ 1.270 + pd_combine_ ## name (float sa, float s, float da, float d) \ 1.271 + { \ 1.272 + const float fa = get_factor (a, sa, da); \ 1.273 + const float fb = get_factor (b, sa, da); \ 1.274 + \ 1.275 + return MIN (1.0f, s * fa + d * fb); \ 1.276 + } \ 1.277 + \ 1.278 + MAKE_COMBINERS(name, pd_combine_ ## name, pd_combine_ ## name) 1.279 + 1.280 +MAKE_PD_COMBINERS (clear, ZERO, ZERO) 1.281 +MAKE_PD_COMBINERS (src, ONE, ZERO) 1.282 +MAKE_PD_COMBINERS (dst, ZERO, ONE) 1.283 +MAKE_PD_COMBINERS (over, ONE, INV_SA) 1.284 +MAKE_PD_COMBINERS (over_reverse, INV_DA, ONE) 1.285 +MAKE_PD_COMBINERS (in, DEST_ALPHA, ZERO) 1.286 +MAKE_PD_COMBINERS (in_reverse, ZERO, SRC_ALPHA) 1.287 +MAKE_PD_COMBINERS (out, INV_DA, ZERO) 1.288 +MAKE_PD_COMBINERS (out_reverse, ZERO, INV_SA) 1.289 +MAKE_PD_COMBINERS (atop, DEST_ALPHA, INV_SA) 1.290 +MAKE_PD_COMBINERS (atop_reverse, INV_DA, SRC_ALPHA) 1.291 +MAKE_PD_COMBINERS (xor, INV_DA, INV_SA) 1.292 +MAKE_PD_COMBINERS (add, ONE, ONE) 1.293 + 1.294 +MAKE_PD_COMBINERS (saturate, INV_DA_OVER_SA, ONE) 1.295 + 1.296 +MAKE_PD_COMBINERS (disjoint_clear, ZERO, ZERO) 1.297 +MAKE_PD_COMBINERS (disjoint_src, ONE, ZERO) 1.298 +MAKE_PD_COMBINERS (disjoint_dst, ZERO, ONE) 1.299 +MAKE_PD_COMBINERS (disjoint_over, ONE, INV_SA_OVER_DA) 1.300 +MAKE_PD_COMBINERS (disjoint_over_reverse, INV_DA_OVER_SA, ONE) 1.301 +MAKE_PD_COMBINERS (disjoint_in, ONE_MINUS_INV_DA_OVER_SA, ZERO) 1.302 +MAKE_PD_COMBINERS (disjoint_in_reverse, ZERO, ONE_MINUS_INV_SA_OVER_DA) 1.303 +MAKE_PD_COMBINERS (disjoint_out, INV_DA_OVER_SA, ZERO) 1.304 +MAKE_PD_COMBINERS (disjoint_out_reverse, ZERO, INV_SA_OVER_DA) 1.305 +MAKE_PD_COMBINERS (disjoint_atop, ONE_MINUS_INV_DA_OVER_SA, INV_SA_OVER_DA) 1.306 +MAKE_PD_COMBINERS (disjoint_atop_reverse, INV_DA_OVER_SA, ONE_MINUS_INV_SA_OVER_DA) 1.307 +MAKE_PD_COMBINERS (disjoint_xor, INV_DA_OVER_SA, INV_SA_OVER_DA) 1.308 + 1.309 +MAKE_PD_COMBINERS (conjoint_clear, ZERO, ZERO) 1.310 +MAKE_PD_COMBINERS (conjoint_src, ONE, ZERO) 1.311 +MAKE_PD_COMBINERS (conjoint_dst, ZERO, ONE) 1.312 +MAKE_PD_COMBINERS (conjoint_over, ONE, ONE_MINUS_SA_OVER_DA) 1.313 +MAKE_PD_COMBINERS (conjoint_over_reverse, ONE_MINUS_DA_OVER_SA, ONE) 1.314 +MAKE_PD_COMBINERS (conjoint_in, DA_OVER_SA, ZERO) 1.315 +MAKE_PD_COMBINERS (conjoint_in_reverse, ZERO, SA_OVER_DA) 1.316 +MAKE_PD_COMBINERS (conjoint_out, ONE_MINUS_DA_OVER_SA, ZERO) 1.317 +MAKE_PD_COMBINERS (conjoint_out_reverse, ZERO, ONE_MINUS_SA_OVER_DA) 1.318 +MAKE_PD_COMBINERS (conjoint_atop, DA_OVER_SA, ONE_MINUS_SA_OVER_DA) 1.319 +MAKE_PD_COMBINERS (conjoint_atop_reverse, ONE_MINUS_DA_OVER_SA, SA_OVER_DA) 1.320 +MAKE_PD_COMBINERS (conjoint_xor, ONE_MINUS_DA_OVER_SA, ONE_MINUS_SA_OVER_DA) 1.321 + 1.322 +/* 1.323 + * PDF blend modes: 1.324 + * 1.325 + * The following blend modes have been taken from the PDF ISO 32000 1.326 + * specification, which at this point in time is available from 1.327 + * http://www.adobe.com/devnet/acrobat/pdfs/PDF32000_2008.pdf 1.328 + * The relevant chapters are 11.3.5 and 11.3.6. 1.329 + * The formula for computing the final pixel color given in 11.3.6 is: 1.330 + * αr × Cr = (1 – αs) × αb × Cb + (1 – αb) × αs × Cs + αb × αs × B(Cb, Cs) 1.331 + * with B() being the blend function. 1.332 + * Note that OVER is a special case of this operation, using B(Cb, Cs) = Cs 1.333 + * 1.334 + * These blend modes should match the SVG filter draft specification, as 1.335 + * it has been designed to mirror ISO 32000. Note that at the current point 1.336 + * no released draft exists that shows this, as the formulas have not been 1.337 + * updated yet after the release of ISO 32000. 1.338 + * 1.339 + * The default implementation here uses the PDF_SEPARABLE_BLEND_MODE and 1.340 + * PDF_NON_SEPARABLE_BLEND_MODE macros, which take the blend function as an 1.341 + * argument. Note that this implementation operates on premultiplied colors, 1.342 + * while the PDF specification does not. Therefore the code uses the formula 1.343 + * ar.Cra = (1 – as) . Dca + (1 – ad) . Sca + B(Dca, ad, Sca, as) 1.344 + */ 1.345 + 1.346 +#define MAKE_SEPARABLE_PDF_COMBINERS(name) \ 1.347 + static force_inline float \ 1.348 + combine_ ## name ## _a (float sa, float s, float da, float d) \ 1.349 + { \ 1.350 + return da + sa - da * sa; \ 1.351 + } \ 1.352 + \ 1.353 + static force_inline float \ 1.354 + combine_ ## name ## _c (float sa, float s, float da, float d) \ 1.355 + { \ 1.356 + float f = (1 - sa) * d + (1 - da) * s; \ 1.357 + \ 1.358 + return f + blend_ ## name (sa, s, da, d); \ 1.359 + } \ 1.360 + \ 1.361 + MAKE_COMBINERS (name, combine_ ## name ## _a, combine_ ## name ## _c) 1.362 + 1.363 +static force_inline float 1.364 +blend_multiply (float sa, float s, float da, float d) 1.365 +{ 1.366 + return d * s; 1.367 +} 1.368 + 1.369 +static force_inline float 1.370 +blend_screen (float sa, float s, float da, float d) 1.371 +{ 1.372 + return d * sa + s * da - s * d; 1.373 +} 1.374 + 1.375 +static force_inline float 1.376 +blend_overlay (float sa, float s, float da, float d) 1.377 +{ 1.378 + if (2 * d < da) 1.379 + return 2 * s * d; 1.380 + else 1.381 + return sa * da - 2 * (da - d) * (sa - s); 1.382 +} 1.383 + 1.384 +static force_inline float 1.385 +blend_darken (float sa, float s, float da, float d) 1.386 +{ 1.387 + s = s * da; 1.388 + d = d * sa; 1.389 + 1.390 + if (s > d) 1.391 + return d; 1.392 + else 1.393 + return s; 1.394 +} 1.395 + 1.396 +static force_inline float 1.397 +blend_lighten (float sa, float s, float da, float d) 1.398 +{ 1.399 + s = s * da; 1.400 + d = d * sa; 1.401 + 1.402 + if (s > d) 1.403 + return s; 1.404 + else 1.405 + return d; 1.406 +} 1.407 + 1.408 +static force_inline float 1.409 +blend_color_dodge (float sa, float s, float da, float d) 1.410 +{ 1.411 + if (IS_ZERO (d)) 1.412 + return 0.0f; 1.413 + else if (d * sa >= sa * da - s * da) 1.414 + return sa * da; 1.415 + else if (IS_ZERO (sa - s)) 1.416 + return sa * da; 1.417 + else 1.418 + return sa * sa * d / (sa - s); 1.419 +} 1.420 + 1.421 +static force_inline float 1.422 +blend_color_burn (float sa, float s, float da, float d) 1.423 +{ 1.424 + if (d >= da) 1.425 + return sa * da; 1.426 + else if (sa * (da - d) >= s * da) 1.427 + return 0.0f; 1.428 + else if (IS_ZERO (s)) 1.429 + return 0.0f; 1.430 + else 1.431 + return sa * (da - sa * (da - d) / s); 1.432 +} 1.433 + 1.434 +static force_inline float 1.435 +blend_hard_light (float sa, float s, float da, float d) 1.436 +{ 1.437 + if (2 * s < sa) 1.438 + return 2 * s * d; 1.439 + else 1.440 + return sa * da - 2 * (da - d) * (sa - s); 1.441 +} 1.442 + 1.443 +static force_inline float 1.444 +blend_soft_light (float sa, float s, float da, float d) 1.445 +{ 1.446 + if (2 * s < sa) 1.447 + { 1.448 + if (IS_ZERO (da)) 1.449 + return d * sa; 1.450 + else 1.451 + return d * sa - d * (da - d) * (sa - 2 * s) / da; 1.452 + } 1.453 + else 1.454 + { 1.455 + if (IS_ZERO (da)) 1.456 + { 1.457 + return 0.0f; 1.458 + } 1.459 + else 1.460 + { 1.461 + if (4 * d <= da) 1.462 + return d * sa + (2 * s - sa) * d * ((16 * d / da - 12) * d / da + 3); 1.463 + else 1.464 + return d * sa + (sqrtf (d * da) - d) * (2 * s - sa); 1.465 + } 1.466 + } 1.467 +} 1.468 + 1.469 +static force_inline float 1.470 +blend_difference (float sa, float s, float da, float d) 1.471 +{ 1.472 + float dsa = d * sa; 1.473 + float sda = s * da; 1.474 + 1.475 + if (sda < dsa) 1.476 + return dsa - sda; 1.477 + else 1.478 + return sda - dsa; 1.479 +} 1.480 + 1.481 +static force_inline float 1.482 +blend_exclusion (float sa, float s, float da, float d) 1.483 +{ 1.484 + return s * da + d * sa - 2 * d * s; 1.485 +} 1.486 + 1.487 +MAKE_SEPARABLE_PDF_COMBINERS (multiply) 1.488 +MAKE_SEPARABLE_PDF_COMBINERS (screen) 1.489 +MAKE_SEPARABLE_PDF_COMBINERS (overlay) 1.490 +MAKE_SEPARABLE_PDF_COMBINERS (darken) 1.491 +MAKE_SEPARABLE_PDF_COMBINERS (lighten) 1.492 +MAKE_SEPARABLE_PDF_COMBINERS (color_dodge) 1.493 +MAKE_SEPARABLE_PDF_COMBINERS (color_burn) 1.494 +MAKE_SEPARABLE_PDF_COMBINERS (hard_light) 1.495 +MAKE_SEPARABLE_PDF_COMBINERS (soft_light) 1.496 +MAKE_SEPARABLE_PDF_COMBINERS (difference) 1.497 +MAKE_SEPARABLE_PDF_COMBINERS (exclusion) 1.498 + 1.499 +/* 1.500 + * PDF nonseperable blend modes. 1.501 + * 1.502 + * These are implemented using the following functions to operate in Hsl 1.503 + * space, with Cmax, Cmid, Cmin referring to the max, mid and min value 1.504 + * of the red, green and blue components. 1.505 + * 1.506 + * LUM (C) = 0.3 × Cred + 0.59 × Cgreen + 0.11 × Cblue 1.507 + * 1.508 + * clip_color (C): 1.509 + * l = LUM (C) 1.510 + * min = Cmin 1.511 + * max = Cmax 1.512 + * if n < 0.0 1.513 + * C = l + (((C – l) × l) ⁄ (l – min)) 1.514 + * if x > 1.0 1.515 + * C = l + (((C – l) × (1 – l)) (max – l)) 1.516 + * return C 1.517 + * 1.518 + * set_lum (C, l): 1.519 + * d = l – LUM (C) 1.520 + * C += d 1.521 + * return clip_color (C) 1.522 + * 1.523 + * SAT (C) = CH_MAX (C) - CH_MIN (C) 1.524 + * 1.525 + * set_sat (C, s): 1.526 + * if Cmax > Cmin 1.527 + * Cmid = ( ( ( Cmid – Cmin ) × s ) ⁄ ( Cmax – Cmin ) ) 1.528 + * Cmax = s 1.529 + * else 1.530 + * Cmid = Cmax = 0.0 1.531 + * Cmin = 0.0 1.532 + * return C 1.533 + */ 1.534 + 1.535 +/* For premultiplied colors, we need to know what happens when C is 1.536 + * multiplied by a real number. LUM and SAT are linear: 1.537 + * 1.538 + * LUM (r × C) = r × LUM (C) SAT (r × C) = r × SAT (C) 1.539 + * 1.540 + * If we extend clip_color with an extra argument a and change 1.541 + * 1.542 + * if x >= 1.0 1.543 + * 1.544 + * into 1.545 + * 1.546 + * if x >= a 1.547 + * 1.548 + * then clip_color is also linear: 1.549 + * 1.550 + * r * clip_color (C, a) = clip_color (r_c, ra); 1.551 + * 1.552 + * for positive r. 1.553 + * 1.554 + * Similarly, we can extend set_lum with an extra argument that is just passed 1.555 + * on to clip_color: 1.556 + * 1.557 + * r × set_lum ( C, l, a) 1.558 + * 1.559 + * = r × clip_color ( C + l - LUM (C), a) 1.560 + * 1.561 + * = clip_color ( r * C + r × l - LUM (r × C), r * a) 1.562 + * 1.563 + * = set_lum ( r * C, r * l, r * a) 1.564 + * 1.565 + * Finally, set_sat: 1.566 + * 1.567 + * r * set_sat (C, s) = set_sat (x * C, r * s) 1.568 + * 1.569 + * The above holds for all non-zero x because they x'es in the fraction for 1.570 + * C_mid cancel out. Specifically, it holds for x = r: 1.571 + * 1.572 + * r * set_sat (C, s) = set_sat (r_c, rs) 1.573 + * 1.574 + * 1.575 + * 1.576 + * 1.577 + * So, for the non-separable PDF blend modes, we have (using s, d for 1.578 + * non-premultiplied colors, and S, D for premultiplied: 1.579 + * 1.580 + * Color: 1.581 + * 1.582 + * a_s * a_d * B(s, d) 1.583 + * = a_s * a_d * set_lum (S/a_s, LUM (D/a_d), 1) 1.584 + * = set_lum (S * a_d, a_s * LUM (D), a_s * a_d) 1.585 + * 1.586 + * 1.587 + * Luminosity: 1.588 + * 1.589 + * a_s * a_d * B(s, d) 1.590 + * = a_s * a_d * set_lum (D/a_d, LUM(S/a_s), 1) 1.591 + * = set_lum (a_s * D, a_d * LUM(S), a_s * a_d) 1.592 + * 1.593 + * 1.594 + * Saturation: 1.595 + * 1.596 + * a_s * a_d * B(s, d) 1.597 + * = a_s * a_d * set_lum (set_sat (D/a_d, SAT (S/a_s)), LUM (D/a_d), 1) 1.598 + * = set_lum (a_s * a_d * set_sat (D/a_d, SAT (S/a_s)), 1.599 + * a_s * LUM (D), a_s * a_d) 1.600 + * = set_lum (set_sat (a_s * D, a_d * SAT (S), a_s * LUM (D), a_s * a_d)) 1.601 + * 1.602 + * Hue: 1.603 + * 1.604 + * a_s * a_d * B(s, d) 1.605 + * = a_s * a_d * set_lum (set_sat (S/a_s, SAT (D/a_d)), LUM (D/a_d), 1) 1.606 + * = set_lum (set_sat (a_d * S, a_s * SAT (D)), a_s * LUM (D), a_s * a_d) 1.607 + * 1.608 + */ 1.609 + 1.610 +typedef struct 1.611 +{ 1.612 + float r; 1.613 + float g; 1.614 + float b; 1.615 +} rgb_t; 1.616 + 1.617 +static force_inline float 1.618 +minf (float a, float b) 1.619 +{ 1.620 + return a < b? a : b; 1.621 +} 1.622 + 1.623 +static force_inline float 1.624 +maxf (float a, float b) 1.625 +{ 1.626 + return a > b? a : b; 1.627 +} 1.628 + 1.629 +static force_inline float 1.630 +channel_min (const rgb_t *c) 1.631 +{ 1.632 + return minf (minf (c->r, c->g), c->b); 1.633 +} 1.634 + 1.635 +static force_inline float 1.636 +channel_max (const rgb_t *c) 1.637 +{ 1.638 + return maxf (maxf (c->r, c->g), c->b); 1.639 +} 1.640 + 1.641 +static force_inline float 1.642 +get_lum (const rgb_t *c) 1.643 +{ 1.644 + return c->r * 0.3f + c->g * 0.59f + c->b * 0.11f; 1.645 +} 1.646 + 1.647 +static force_inline float 1.648 +get_sat (const rgb_t *c) 1.649 +{ 1.650 + return channel_max (c) - channel_min (c); 1.651 +} 1.652 + 1.653 +static void 1.654 +clip_color (rgb_t *color, float a) 1.655 +{ 1.656 + float l = get_lum (color); 1.657 + float n = channel_min (color); 1.658 + float x = channel_max (color); 1.659 + float t; 1.660 + 1.661 + if (n < 0.0f) 1.662 + { 1.663 + t = l - n; 1.664 + if (IS_ZERO (t)) 1.665 + { 1.666 + color->r = 0.0f; 1.667 + color->g = 0.0f; 1.668 + color->b = 0.0f; 1.669 + } 1.670 + else 1.671 + { 1.672 + color->r = l + (((color->r - l) * l) / t); 1.673 + color->g = l + (((color->g - l) * l) / t); 1.674 + color->b = l + (((color->b - l) * l) / t); 1.675 + } 1.676 + } 1.677 + if (x > a) 1.678 + { 1.679 + t = x - l; 1.680 + if (IS_ZERO (t)) 1.681 + { 1.682 + color->r = a; 1.683 + color->g = a; 1.684 + color->b = a; 1.685 + } 1.686 + else 1.687 + { 1.688 + color->r = l + (((color->r - l) * (a - l) / t)); 1.689 + color->g = l + (((color->g - l) * (a - l) / t)); 1.690 + color->b = l + (((color->b - l) * (a - l) / t)); 1.691 + } 1.692 + } 1.693 +} 1.694 + 1.695 +static void 1.696 +set_lum (rgb_t *color, float sa, float l) 1.697 +{ 1.698 + float d = l - get_lum (color); 1.699 + 1.700 + color->r = color->r + d; 1.701 + color->g = color->g + d; 1.702 + color->b = color->b + d; 1.703 + 1.704 + clip_color (color, sa); 1.705 +} 1.706 + 1.707 +static void 1.708 +set_sat (rgb_t *src, float sat) 1.709 +{ 1.710 + float *max, *mid, *min; 1.711 + float t; 1.712 + 1.713 + if (src->r > src->g) 1.714 + { 1.715 + if (src->r > src->b) 1.716 + { 1.717 + max = &(src->r); 1.718 + 1.719 + if (src->g > src->b) 1.720 + { 1.721 + mid = &(src->g); 1.722 + min = &(src->b); 1.723 + } 1.724 + else 1.725 + { 1.726 + mid = &(src->b); 1.727 + min = &(src->g); 1.728 + } 1.729 + } 1.730 + else 1.731 + { 1.732 + max = &(src->b); 1.733 + mid = &(src->r); 1.734 + min = &(src->g); 1.735 + } 1.736 + } 1.737 + else 1.738 + { 1.739 + if (src->r > src->b) 1.740 + { 1.741 + max = &(src->g); 1.742 + mid = &(src->r); 1.743 + min = &(src->b); 1.744 + } 1.745 + else 1.746 + { 1.747 + min = &(src->r); 1.748 + 1.749 + if (src->g > src->b) 1.750 + { 1.751 + max = &(src->g); 1.752 + mid = &(src->b); 1.753 + } 1.754 + else 1.755 + { 1.756 + max = &(src->b); 1.757 + mid = &(src->g); 1.758 + } 1.759 + } 1.760 + } 1.761 + 1.762 + t = *max - *min; 1.763 + 1.764 + if (IS_ZERO (t)) 1.765 + { 1.766 + *mid = *max = 0.0f; 1.767 + } 1.768 + else 1.769 + { 1.770 + *mid = ((*mid - *min) * sat) / t; 1.771 + *max = sat; 1.772 + } 1.773 + 1.774 + *min = 0.0f; 1.775 +} 1.776 + 1.777 +/* 1.778 + * Hue: 1.779 + * B(Cb, Cs) = set_lum (set_sat (Cs, SAT (Cb)), LUM (Cb)) 1.780 + */ 1.781 +static force_inline void 1.782 +blend_hsl_hue (rgb_t *res, 1.783 + const rgb_t *dest, float da, 1.784 + const rgb_t *src, float sa) 1.785 +{ 1.786 + res->r = src->r * da; 1.787 + res->g = src->g * da; 1.788 + res->b = src->b * da; 1.789 + 1.790 + set_sat (res, get_sat (dest) * sa); 1.791 + set_lum (res, sa * da, get_lum (dest) * sa); 1.792 +} 1.793 + 1.794 +/* 1.795 + * Saturation: 1.796 + * B(Cb, Cs) = set_lum (set_sat (Cb, SAT (Cs)), LUM (Cb)) 1.797 + */ 1.798 +static force_inline void 1.799 +blend_hsl_saturation (rgb_t *res, 1.800 + const rgb_t *dest, float da, 1.801 + const rgb_t *src, float sa) 1.802 +{ 1.803 + res->r = dest->r * sa; 1.804 + res->g = dest->g * sa; 1.805 + res->b = dest->b * sa; 1.806 + 1.807 + set_sat (res, get_sat (src) * da); 1.808 + set_lum (res, sa * da, get_lum (dest) * sa); 1.809 +} 1.810 + 1.811 +/* 1.812 + * Color: 1.813 + * B(Cb, Cs) = set_lum (Cs, LUM (Cb)) 1.814 + */ 1.815 +static force_inline void 1.816 +blend_hsl_color (rgb_t *res, 1.817 + const rgb_t *dest, float da, 1.818 + const rgb_t *src, float sa) 1.819 +{ 1.820 + res->r = src->r * da; 1.821 + res->g = src->g * da; 1.822 + res->b = src->b * da; 1.823 + 1.824 + set_lum (res, sa * da, get_lum (dest) * sa); 1.825 +} 1.826 + 1.827 +/* 1.828 + * Luminosity: 1.829 + * B(Cb, Cs) = set_lum (Cb, LUM (Cs)) 1.830 + */ 1.831 +static force_inline void 1.832 +blend_hsl_luminosity (rgb_t *res, 1.833 + const rgb_t *dest, float da, 1.834 + const rgb_t *src, float sa) 1.835 +{ 1.836 + res->r = dest->r * sa; 1.837 + res->g = dest->g * sa; 1.838 + res->b = dest->b * sa; 1.839 + 1.840 + set_lum (res, sa * da, get_lum (src) * da); 1.841 +} 1.842 + 1.843 +#define MAKE_NON_SEPARABLE_PDF_COMBINERS(name) \ 1.844 + static void \ 1.845 + combine_ ## name ## _u_float (pixman_implementation_t *imp, \ 1.846 + pixman_op_t op, \ 1.847 + float *dest, \ 1.848 + const float *src, \ 1.849 + const float *mask, \ 1.850 + int n_pixels) \ 1.851 + { \ 1.852 + int i; \ 1.853 + \ 1.854 + for (i = 0; i < 4 * n_pixels; i += 4) \ 1.855 + { \ 1.856 + float sa, da; \ 1.857 + rgb_t sc, dc, rc; \ 1.858 + \ 1.859 + sa = src[i + 0]; \ 1.860 + sc.r = src[i + 1]; \ 1.861 + sc.g = src[i + 2]; \ 1.862 + sc.b = src[i + 3]; \ 1.863 + \ 1.864 + da = dest[i + 0]; \ 1.865 + dc.r = dest[i + 1]; \ 1.866 + dc.g = dest[i + 2]; \ 1.867 + dc.b = dest[i + 3]; \ 1.868 + \ 1.869 + if (mask) \ 1.870 + { \ 1.871 + float ma = mask[i + 0]; \ 1.872 + \ 1.873 + /* Component alpha is not supported for HSL modes */ \ 1.874 + sa *= ma; \ 1.875 + sc.r *= ma; \ 1.876 + sc.g *= ma; \ 1.877 + sc.g *= ma; \ 1.878 + } \ 1.879 + \ 1.880 + blend_ ## name (&rc, &dc, da, &sc, sa); \ 1.881 + \ 1.882 + dest[i + 0] = sa + da - sa * da; \ 1.883 + dest[i + 1] = (1 - sa) * dc.r + (1 - da) * sc.r + rc.r; \ 1.884 + dest[i + 2] = (1 - sa) * dc.g + (1 - da) * sc.g + rc.g; \ 1.885 + dest[i + 3] = (1 - sa) * dc.b + (1 - da) * sc.b + rc.b; \ 1.886 + } \ 1.887 + } 1.888 + 1.889 +MAKE_NON_SEPARABLE_PDF_COMBINERS(hsl_hue) 1.890 +MAKE_NON_SEPARABLE_PDF_COMBINERS(hsl_saturation) 1.891 +MAKE_NON_SEPARABLE_PDF_COMBINERS(hsl_color) 1.892 +MAKE_NON_SEPARABLE_PDF_COMBINERS(hsl_luminosity) 1.893 + 1.894 +void 1.895 +_pixman_setup_combiner_functions_float (pixman_implementation_t *imp) 1.896 +{ 1.897 + /* Unified alpha */ 1.898 + imp->combine_float[PIXMAN_OP_CLEAR] = combine_clear_u_float; 1.899 + imp->combine_float[PIXMAN_OP_SRC] = combine_src_u_float; 1.900 + imp->combine_float[PIXMAN_OP_DST] = combine_dst_u_float; 1.901 + imp->combine_float[PIXMAN_OP_OVER] = combine_over_u_float; 1.902 + imp->combine_float[PIXMAN_OP_OVER_REVERSE] = combine_over_reverse_u_float; 1.903 + imp->combine_float[PIXMAN_OP_IN] = combine_in_u_float; 1.904 + imp->combine_float[PIXMAN_OP_IN_REVERSE] = combine_in_reverse_u_float; 1.905 + imp->combine_float[PIXMAN_OP_OUT] = combine_out_u_float; 1.906 + imp->combine_float[PIXMAN_OP_OUT_REVERSE] = combine_out_reverse_u_float; 1.907 + imp->combine_float[PIXMAN_OP_ATOP] = combine_atop_u_float; 1.908 + imp->combine_float[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_u_float; 1.909 + imp->combine_float[PIXMAN_OP_XOR] = combine_xor_u_float; 1.910 + imp->combine_float[PIXMAN_OP_ADD] = combine_add_u_float; 1.911 + imp->combine_float[PIXMAN_OP_SATURATE] = combine_saturate_u_float; 1.912 + 1.913 + /* Disjoint, unified */ 1.914 + imp->combine_float[PIXMAN_OP_DISJOINT_CLEAR] = combine_disjoint_clear_u_float; 1.915 + imp->combine_float[PIXMAN_OP_DISJOINT_SRC] = combine_disjoint_src_u_float; 1.916 + imp->combine_float[PIXMAN_OP_DISJOINT_DST] = combine_disjoint_dst_u_float; 1.917 + imp->combine_float[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_u_float; 1.918 + imp->combine_float[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_disjoint_over_reverse_u_float; 1.919 + imp->combine_float[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_u_float; 1.920 + imp->combine_float[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_u_float; 1.921 + imp->combine_float[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_u_float; 1.922 + imp->combine_float[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_u_float; 1.923 + imp->combine_float[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_u_float; 1.924 + imp->combine_float[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_u_float; 1.925 + imp->combine_float[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_u_float; 1.926 + 1.927 + /* Conjoint, unified */ 1.928 + imp->combine_float[PIXMAN_OP_CONJOINT_CLEAR] = combine_conjoint_clear_u_float; 1.929 + imp->combine_float[PIXMAN_OP_CONJOINT_SRC] = combine_conjoint_src_u_float; 1.930 + imp->combine_float[PIXMAN_OP_CONJOINT_DST] = combine_conjoint_dst_u_float; 1.931 + imp->combine_float[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_u_float; 1.932 + imp->combine_float[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_u_float; 1.933 + imp->combine_float[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_u_float; 1.934 + imp->combine_float[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_u_float; 1.935 + imp->combine_float[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_u_float; 1.936 + imp->combine_float[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_u_float; 1.937 + imp->combine_float[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_u_float; 1.938 + imp->combine_float[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_u_float; 1.939 + imp->combine_float[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_u_float; 1.940 + 1.941 + /* PDF operators, unified */ 1.942 + imp->combine_float[PIXMAN_OP_MULTIPLY] = combine_multiply_u_float; 1.943 + imp->combine_float[PIXMAN_OP_SCREEN] = combine_screen_u_float; 1.944 + imp->combine_float[PIXMAN_OP_OVERLAY] = combine_overlay_u_float; 1.945 + imp->combine_float[PIXMAN_OP_DARKEN] = combine_darken_u_float; 1.946 + imp->combine_float[PIXMAN_OP_LIGHTEN] = combine_lighten_u_float; 1.947 + imp->combine_float[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_u_float; 1.948 + imp->combine_float[PIXMAN_OP_COLOR_BURN] = combine_color_burn_u_float; 1.949 + imp->combine_float[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_u_float; 1.950 + imp->combine_float[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_u_float; 1.951 + imp->combine_float[PIXMAN_OP_DIFFERENCE] = combine_difference_u_float; 1.952 + imp->combine_float[PIXMAN_OP_EXCLUSION] = combine_exclusion_u_float; 1.953 + 1.954 + imp->combine_float[PIXMAN_OP_HSL_HUE] = combine_hsl_hue_u_float; 1.955 + imp->combine_float[PIXMAN_OP_HSL_SATURATION] = combine_hsl_saturation_u_float; 1.956 + imp->combine_float[PIXMAN_OP_HSL_COLOR] = combine_hsl_color_u_float; 1.957 + imp->combine_float[PIXMAN_OP_HSL_LUMINOSITY] = combine_hsl_luminosity_u_float; 1.958 + 1.959 + /* Component alpha combiners */ 1.960 + imp->combine_float_ca[PIXMAN_OP_CLEAR] = combine_clear_ca_float; 1.961 + imp->combine_float_ca[PIXMAN_OP_SRC] = combine_src_ca_float; 1.962 + imp->combine_float_ca[PIXMAN_OP_DST] = combine_dst_ca_float; 1.963 + imp->combine_float_ca[PIXMAN_OP_OVER] = combine_over_ca_float; 1.964 + imp->combine_float_ca[PIXMAN_OP_OVER_REVERSE] = combine_over_reverse_ca_float; 1.965 + imp->combine_float_ca[PIXMAN_OP_IN] = combine_in_ca_float; 1.966 + imp->combine_float_ca[PIXMAN_OP_IN_REVERSE] = combine_in_reverse_ca_float; 1.967 + imp->combine_float_ca[PIXMAN_OP_OUT] = combine_out_ca_float; 1.968 + imp->combine_float_ca[PIXMAN_OP_OUT_REVERSE] = combine_out_reverse_ca_float; 1.969 + imp->combine_float_ca[PIXMAN_OP_ATOP] = combine_atop_ca_float; 1.970 + imp->combine_float_ca[PIXMAN_OP_ATOP_REVERSE] = combine_atop_reverse_ca_float; 1.971 + imp->combine_float_ca[PIXMAN_OP_XOR] = combine_xor_ca_float; 1.972 + imp->combine_float_ca[PIXMAN_OP_ADD] = combine_add_ca_float; 1.973 + imp->combine_float_ca[PIXMAN_OP_SATURATE] = combine_saturate_ca_float; 1.974 + 1.975 + /* Disjoint CA */ 1.976 + imp->combine_float_ca[PIXMAN_OP_DISJOINT_CLEAR] = combine_disjoint_clear_ca_float; 1.977 + imp->combine_float_ca[PIXMAN_OP_DISJOINT_SRC] = combine_disjoint_src_ca_float; 1.978 + imp->combine_float_ca[PIXMAN_OP_DISJOINT_DST] = combine_disjoint_dst_ca_float; 1.979 + imp->combine_float_ca[PIXMAN_OP_DISJOINT_OVER] = combine_disjoint_over_ca_float; 1.980 + imp->combine_float_ca[PIXMAN_OP_DISJOINT_OVER_REVERSE] = combine_disjoint_over_reverse_ca_float; 1.981 + imp->combine_float_ca[PIXMAN_OP_DISJOINT_IN] = combine_disjoint_in_ca_float; 1.982 + imp->combine_float_ca[PIXMAN_OP_DISJOINT_IN_REVERSE] = combine_disjoint_in_reverse_ca_float; 1.983 + imp->combine_float_ca[PIXMAN_OP_DISJOINT_OUT] = combine_disjoint_out_ca_float; 1.984 + imp->combine_float_ca[PIXMAN_OP_DISJOINT_OUT_REVERSE] = combine_disjoint_out_reverse_ca_float; 1.985 + imp->combine_float_ca[PIXMAN_OP_DISJOINT_ATOP] = combine_disjoint_atop_ca_float; 1.986 + imp->combine_float_ca[PIXMAN_OP_DISJOINT_ATOP_REVERSE] = combine_disjoint_atop_reverse_ca_float; 1.987 + imp->combine_float_ca[PIXMAN_OP_DISJOINT_XOR] = combine_disjoint_xor_ca_float; 1.988 + 1.989 + /* Conjoint CA */ 1.990 + imp->combine_float_ca[PIXMAN_OP_CONJOINT_CLEAR] = combine_conjoint_clear_ca_float; 1.991 + imp->combine_float_ca[PIXMAN_OP_CONJOINT_SRC] = combine_conjoint_src_ca_float; 1.992 + imp->combine_float_ca[PIXMAN_OP_CONJOINT_DST] = combine_conjoint_dst_ca_float; 1.993 + imp->combine_float_ca[PIXMAN_OP_CONJOINT_OVER] = combine_conjoint_over_ca_float; 1.994 + imp->combine_float_ca[PIXMAN_OP_CONJOINT_OVER_REVERSE] = combine_conjoint_over_reverse_ca_float; 1.995 + imp->combine_float_ca[PIXMAN_OP_CONJOINT_IN] = combine_conjoint_in_ca_float; 1.996 + imp->combine_float_ca[PIXMAN_OP_CONJOINT_IN_REVERSE] = combine_conjoint_in_reverse_ca_float; 1.997 + imp->combine_float_ca[PIXMAN_OP_CONJOINT_OUT] = combine_conjoint_out_ca_float; 1.998 + imp->combine_float_ca[PIXMAN_OP_CONJOINT_OUT_REVERSE] = combine_conjoint_out_reverse_ca_float; 1.999 + imp->combine_float_ca[PIXMAN_OP_CONJOINT_ATOP] = combine_conjoint_atop_ca_float; 1.1000 + imp->combine_float_ca[PIXMAN_OP_CONJOINT_ATOP_REVERSE] = combine_conjoint_atop_reverse_ca_float; 1.1001 + imp->combine_float_ca[PIXMAN_OP_CONJOINT_XOR] = combine_conjoint_xor_ca_float; 1.1002 + 1.1003 + /* PDF operators CA */ 1.1004 + imp->combine_float_ca[PIXMAN_OP_MULTIPLY] = combine_multiply_ca_float; 1.1005 + imp->combine_float_ca[PIXMAN_OP_SCREEN] = combine_screen_ca_float; 1.1006 + imp->combine_float_ca[PIXMAN_OP_OVERLAY] = combine_overlay_ca_float; 1.1007 + imp->combine_float_ca[PIXMAN_OP_DARKEN] = combine_darken_ca_float; 1.1008 + imp->combine_float_ca[PIXMAN_OP_LIGHTEN] = combine_lighten_ca_float; 1.1009 + imp->combine_float_ca[PIXMAN_OP_COLOR_DODGE] = combine_color_dodge_ca_float; 1.1010 + imp->combine_float_ca[PIXMAN_OP_COLOR_BURN] = combine_color_burn_ca_float; 1.1011 + imp->combine_float_ca[PIXMAN_OP_HARD_LIGHT] = combine_hard_light_ca_float; 1.1012 + imp->combine_float_ca[PIXMAN_OP_SOFT_LIGHT] = combine_soft_light_ca_float; 1.1013 + imp->combine_float_ca[PIXMAN_OP_DIFFERENCE] = combine_difference_ca_float; 1.1014 + imp->combine_float_ca[PIXMAN_OP_EXCLUSION] = combine_exclusion_ca_float; 1.1015 + 1.1016 + /* It is not clear that these make sense, so make them noops for now */ 1.1017 + imp->combine_float_ca[PIXMAN_OP_HSL_HUE] = combine_dst_u_float; 1.1018 + imp->combine_float_ca[PIXMAN_OP_HSL_SATURATION] = combine_dst_u_float; 1.1019 + imp->combine_float_ca[PIXMAN_OP_HSL_COLOR] = combine_dst_u_float; 1.1020 + imp->combine_float_ca[PIXMAN_OP_HSL_LUMINOSITY] = combine_dst_u_float; 1.1021 +}