diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2010-10-05 13:04:21 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2010-10-05 13:04:21 -0400 |
commit | 67599cc03195212a4241cf510691b4234b00132a (patch) | |
tree | 2ea287b664ad48665a3a490fc643f031d453d18e | |
parent | 32f2c996980ac547a56e5627e9062c000adf5f05 (diff) |
a bunch of stuffcomposite-test-more-ops
-rw-r--r-- | pixman/pixman-combine.c.template | 32 | ||||
-rw-r--r-- | test/composite.c | 150 |
2 files changed, 168 insertions, 14 deletions
diff --git a/pixman/pixman-combine.c.template b/pixman/pixman-combine.c.template index 0d3b95d4..8409f113 100644 --- a/pixman/pixman-combine.c.template +++ b/pixman/pixman-combine.c.template @@ -477,13 +477,13 @@ combine_multiply_ca (pixman_implementation_t *imp, comp4_t d = *(dest + i); comp4_t r = d; comp4_t dest_ia = ALPHA_c (~d); - - combine_mask_value_ca (&s, &m); - + + combine_mask_ca (&s, &m); + UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (r, ~m, s, dest_ia); UNcx4_MUL_UNcx4 (d, s); UNcx4_ADD_UNcx4 (r, d); - + *(dest + i) = r; } } @@ -506,15 +506,17 @@ combine_multiply_ca (pixman_implementation_t *imp, comp1_t da = ALPHA_c (d); \ comp1_t ida = ~da; \ comp4_t result; \ - \ + comp4_t tmp; \ + \ result = d; \ UNcx4_MUL_UNc_ADD_UNcx4_MUL_UNc (result, isa, s, ida); \ \ - *(dest + i) = result + \ - (DIV_ONE_UNc (sa * da) << A_SHIFT) + \ - (blend_ ## name (RED_c (d), da, RED_c (s), sa) << R_SHIFT) + \ - (blend_ ## name (GREEN_c (d), da, GREEN_c (s), sa) << G_SHIFT) + \ + tmp = (DIV_ONE_UNc (sa * da) << A_SHIFT) | \ + (blend_ ## name (RED_c (d), da, RED_c (s), sa) << R_SHIFT) | \ + (blend_ ## name (GREEN_c (d), da, GREEN_c (s), sa) << G_SHIFT) | \ (blend_ ## name (BLUE_c (d), da, BLUE_c (s), sa)); \ + UNcx4_ADD_UNcx4 (result, tmp); \ + *(dest + i) = result; \ } \ } \ \ @@ -534,17 +536,19 @@ combine_multiply_ca (pixman_implementation_t *imp, comp1_t da = ALPHA_c (d); \ comp1_t ida = ~da; \ comp4_t result; \ + comp4_t tmp; \ \ - combine_mask_value_ca (&s, &m); \ + combine_mask_ca (&s, &m); \ \ result = d; \ UNcx4_MUL_UNcx4_ADD_UNcx4_MUL_UNc (result, ~m, s, ida); \ \ - result += \ - (DIV_ONE_UNc (ALPHA_c (m) * da) << A_SHIFT) + \ - (blend_ ## name (RED_c (d), da, RED_c (s), RED_c (m)) << R_SHIFT) + \ - (blend_ ## name (GREEN_c (d), da, GREEN_c (s), GREEN_c (m)) << G_SHIFT) + \ + tmp = \ + (DIV_ONE_UNc (ALPHA_c (m) * da) << A_SHIFT) | \ + (blend_ ## name (RED_c (d), da, RED_c (s), RED_c (m)) << R_SHIFT) | \ + (blend_ ## name (GREEN_c (d), da, GREEN_c (s), GREEN_c (m)) << G_SHIFT) | \ (blend_ ## name (BLUE_c (d), da, BLUE_c (s), BLUE_c (m))); \ + UNcx4_ADD_UNcx4 (result, tmp); \ \ *(dest + i) = result; \ } \ diff --git a/test/composite.c b/test/composite.c index de195339..b2e1c113 100644 --- a/test/composite.c +++ b/test/composite.c @@ -53,7 +53,9 @@ struct format_t static const color_t colors[] = { { 1.0, 1.0, 1.0, 1.0 }, +#if 0 { 1.0, 1.0, 1.0, 0.0 }, +#endif { 0.0, 0.0, 0.0, 1.0 }, { 0.0, 0.0, 0.0, 0.0 }, { 1.0, 0.0, 0.0, 1.0 }, @@ -204,6 +206,19 @@ static const operator_t operators[] = P(CONJOINT_ATOP), P(CONJOINT_ATOP_REVERSE), P(CONJOINT_XOR), + + P(MULTIPLY), + P(SCREEN), + P(OVERLAY), + P(DARKEN), + P(LIGHTEN), + P(COLOR_DODGE), + P(COLOR_BURN), + P(HARD_LIGHT), + P(SOFT_LIGHT), + P(DIFFERENCE), + P(EXCLUSION), + #undef P }; @@ -433,6 +448,124 @@ calc_op_porter_duff (pixman_op_t op, double src, double dst, double srca, double #undef mult_chan } +static double +calc_op_separable_pdf (pixman_op_t op, double src, double dst, double srca, double dsta) +{ + double result = (1 - srca) * dst + (1 - dsta) * src; + double dsa, sda; + + switch (op) + { + case PIXMAN_OP_MULTIPLY: + result += src * dst; + break; + + case PIXMAN_OP_SCREEN: + result += srca * dst + dsta * src - src * dst; + break; + + case PIXMAN_OP_OVERLAY: + if (2 * dst < dsta) + result += 2 * src * dst; + else + result += srca * dsta - 2 * (dsta - dst) * (srca - src); + break; + + case PIXMAN_OP_DARKEN: + if (src * dsta > dst * srca) + result += dst * srca; + else + result += src * dsta; + break; + + case PIXMAN_OP_LIGHTEN: + if (src * dsta > dst * srca) + result += src * dsta; + else + result += dst * srca; + break; + + case PIXMAN_OP_COLOR_DODGE: + if (src >= srca) + { + if (dst != 0.0) + result += srca * dsta; + } + else + { + double r = dst * srca / (srca - src); + + result += srca * min (r, dsta); + } + break; + + case PIXMAN_OP_COLOR_BURN: + if (src == 0.0) + { + if (dst >= dsta) + result += srca * dsta; + } + else + { + double r = (dsta - dst) * srca / src; + + result += srca * (max (r, dsta) - r); + } + break; + + case PIXMAN_OP_HARD_LIGHT: + if (2 * src < srca) + result += 2 * src * dst; + else + result += srca * dsta - 2 * (dsta - dst) * (srca - src); + break; + + case PIXMAN_OP_SOFT_LIGHT: + if (2 * src < srca) + { + if (dsta == 0.0) + result += dst * srca; + else + result += dst * srca - dst * (dsta - dst) * (srca - 2 * src) / dsta; + } + else if (dsta == 0.0) + { + result += 0.0; + } + else if (4 * dst <= dsta) + { + result += dst * srca + (2 * src - srca) * dst * ((16 * dst / dsta - 12) * dst / dsta + 3); + } + else + { + result += dst * srca + (sqrt (dst * dsta) - dst) * (2 * src - srca); + } + break; + + case PIXMAN_OP_DIFFERENCE: + dsa = dst * srca; + sda = src * dsta; + + result += fabs (sda - dsa); + break; + + case PIXMAN_OP_EXCLUSION: + result += src * dsta + dst * srca - 2 * dst * src; + break; + + default: + abort(); + break; + } + + if (result > 1) + result = 1; + if (result < 0) + result = 0; + + return result; +} + static void calc_op (pixman_op_t op, color_t *result, const color_t *src, @@ -486,6 +619,23 @@ calc_op (pixman_op_t op, color_t *result, result->b = calc_op_porter_duff (op, src->b, dst->b, src_a->b, dst_a); break; + case PIXMAN_OP_MULTIPLY: + case PIXMAN_OP_SCREEN: + case PIXMAN_OP_OVERLAY: + case PIXMAN_OP_DARKEN: + case PIXMAN_OP_LIGHTEN: + case PIXMAN_OP_COLOR_DODGE: + case PIXMAN_OP_COLOR_BURN: + case PIXMAN_OP_HARD_LIGHT: + case PIXMAN_OP_SOFT_LIGHT: + case PIXMAN_OP_DIFFERENCE: + case PIXMAN_OP_EXCLUSION: + result->a = src->a + dst->a - src->a * dst->a; + result->r = calc_op_separable_pdf (op, src->r, dst->r, src_a->r, dst_a); + result->g = calc_op_separable_pdf (op, src->g, dst->g, src_a->g, dst_a); + result->b = calc_op_separable_pdf (op, src->b, dst->b, src_a->b, dst_a); + break; + default: abort(); } |