RadialGradient: if fr > cr, nothing is rendered
ZhUyU1997 opened this issue · comments
Yu Zhu commented
fr: 100, cr: 5
#include "plutovg.h"
int main(void)
{
const int width = 150;
const int height = 150;
plutovg_surface_t *surface = plutovg_surface_create(width, height);
plutovg_t *pluto = plutovg_create(surface);
plutovg_save(pluto);
plutovg_gradient_t *g = plutovg_gradient_create_radial(75, 50, 5, 75, 50, 100);
plutovg_gradient_add_stop_rgba(g, 0, 1, 0, 0, 1);
plutovg_gradient_add_stop_rgba(g, 1, 1, 1, 1, 1);
plutovg_set_source_gradient(pluto, g);
plutovg_rect(pluto, 10, 10, 150, 100);
plutovg_fill_preserve(pluto);
plutovg_restore(pluto);
plutovg_surface_write_to_png(surface, "smiley.png");
plutovg_surface_destroy(surface);
plutovg_destroy(pluto);
return 0;
}
I can get the result from html canvas with same input.
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var grd = ctx.createRadialGradient(90, 60, 100, 75, 50, 5);
grd.addColorStop(0, "red");
grd.addColorStop(1, "white");
ctx.fillStyle = grd;
ctx.fillRect(10, 10, 150, 100);
</script>
</body>
</html>
I tried to fix it, although I am not an expert in it. Just for reference.
Note: I removed if(gradient->radial.fr + v->dr * w >= 0)
, but lack mathematical proof
diff --git a/source/plutovg-blend.c b/source/plutovg-blend.c
index 9dd7541..c43b4c4 100644
--- a/source/plutovg-blend.c
+++ b/source/plutovg-blend.c
@@ -239,22 +239,39 @@ static void fetch_radial_gradient(uint32_t* buffer, const radial_gradient_values
const uint32_t* end = buffer + length;
if(v->extended)
{
- while(buffer < end)
+ if(v->dr >= 0)
{
- uint32_t result = 0;
- if(det >= 0)
+ while(buffer < end)
{
- double w = sqrt(det) - b;
- if(gradient->radial.fr + v->dr * w >= 0)
- result = gradient_pixel(gradient, w);
+ uint32_t result = 0;
+ if(det >= 0)
+ {
+ result = gradient_pixel(gradient, sqrt(det) - b);
+ }
+ *buffer = result;
+ det += delta_det;
+ delta_det += delta_delta_det;
+ b += delta_b;
+ ++buffer;
}
-
- *buffer = result;
- det += delta_det;
- delta_det += delta_delta_det;
- b += delta_b;
- ++buffer;
}
+ else
+ {
+ while(buffer < end)
+ {
+ uint32_t result = 0;
+ if(det >= 0)
+ {
+ result = gradient_pixel(gradient, -sqrt(det) - b);
+ }
+ *buffer = result;
+ det += delta_det;
+ delta_det += delta_delta_det;
+ b += delta_b;
+ ++buffer;
+ }
+ }
+
}
else
{