[patch] gl: use original data to compute gradient uniforms
"Henry (Yu) Song - SISA" <[email protected]>
| Newsgroups | gmane.comp.lib.cairo |
|---|---|
| Message-ID | <3955FA337689574EB32F94B12A7E6E9E434B529F@sisaex01sj> |
From 29e62f9edce2ee5a19f878b46e26e385c4b0e467 Mon Sep 17 00:00:00 2001 From: Henry Song <[email protected]> Date: Wed, 2 Jan 2013 17:57:34 +0100 Subject: [PATCH] gl: Scale radial gradient parameters down may introduce rounding error. gl: Use original data to compute gradient uniforms. Instead of using scaled parametes to generate uniform values, we compute them from origin radial gradient pattern. Scaled data may introduce rounding error. For example, operand->gradient.a may not be exactly 0 when using scaled data. This causes operand type to use CAIRO_GL_OPERAND_RADIAL_GRADIENT_EXT/NONE instead of CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0, which produces different image. --- src/cairo-gl-operand.c | 33 ++++++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 7 deletions(-) diff --git a/src/cairo-gl-operand.c b/src/cairo-gl-operand.c index 502737a..1ef2cd5 100644 --- a/src/cairo-gl-operand.c +++ b/src/cairo-gl-operand.c @@ -682,6 +682,8 @@ _cairo_gl_gradient_operand_init (cairo_gl_operand_t *operand, cairo_matrix_t m; cairo_circle_double_t circles[2]; double x0, y0, r0, dx, dy, dr; + double scale = 1.0; + cairo_radial_pattern_t *radial_pattern = (cairo_radial_pattern_t *)gradient; /* * Some fragment shader implementations use half-floats to @@ -695,18 +697,35 @@ _cairo_gl_gradient_operand_init (cairo_gl_operand_t *operand, _cairo_gradient_pattern_fit_to_range (gradient, 8., &operand->gradient.m, circles); + /* + * Instead of using scaled data that might introducing rounding + * errors, we use original data directly + */ + if (circles[0].center.x) + scale = radial_pattern->cd1.center.x / circles[0].center.x; + else if (circles[0].center.y) + scale = radial_pattern->cd1.center.y / circles[0].center.y; + else if (circles[0].radius) + scale = radial_pattern->cd1.radius / circles[0].radius; + else if (circles[1].center.x) + scale = radial_pattern->cd2.center.x / circles[1].center.x; + else if (circles[1].center.y) + scale = radial_pattern->cd2.center.y / circles[1].center.y; + else if (circles[1].radius) + scale = radial_pattern->cd2.radius / circles[1].radius; + x0 = circles[0].center.x; y0 = circles[0].center.y; r0 = circles[0].radius; - dx = circles[1].center.x - x0; - dy = circles[1].center.y - y0; - dr = circles[1].radius - r0; + dx = radial_pattern->cd2.center.x - radial_pattern->cd1.center.x; + dy = radial_pattern->cd2.center.y - radial_pattern->cd1.center.y; + dr = radial_pattern->cd2.radius - radial_pattern->cd1.radius; - operand->gradient.a = dx * dx + dy * dy - dr * dr; + operand->gradient.a = (dx * dx + dy * dy - dr * dr)/(scale * scale); operand->gradient.radius_0 = r0; - operand->gradient.circle_d.center.x = dx; - operand->gradient.circle_d.center.y = dy; - operand->gradient.circle_d.radius = dr; + operand->gradient.circle_d.center.x = dx / scale; + operand->gradient.circle_d.center.y = dy / scale; + operand->gradient.circle_d.radius = dr / scale; if (operand->gradient.a == 0) operand->type = CAIRO_GL_OPERAND_RADIAL_GRADIENT_A0; -- 1.7.9.5 -- cairo mailing list [email protected] http://lists.cairographics.org/mailman/listinfo/cairo