diff options
| author | Krzysztof Kosi??ski <tweenk.pl@gmail.com> | 2011-11-14 18:47:11 +0000 |
|---|---|---|
| committer | Krzysztof KosiĆski <tweenk.pl@gmail.com> | 2011-11-14 18:47:11 +0000 |
| commit | 263beb7e8c7a5f658672ffaee2ae8f172c00fd23 (patch) | |
| tree | d46dd02257b581de0f63efd61fd4a9e539cc2e38 /src/sp-gradient.cpp | |
| parent | Fix text redraw problems (LP #837291) (diff) | |
| download | inkscape-263beb7e8c7a5f658672ffaee2ae8f172c00fd23.tar.gz inkscape-263beb7e8c7a5f658672ffaee2ae8f172c00fd23.zip | |
Add a tolerance-based hack, so that radial gradients with focus outside
the outer circle work reliably. Fixes #845153
Fixed bugs:
- https://launchpad.net/bugs/845153
(bzr r10740)
Diffstat (limited to 'src/sp-gradient.cpp')
| -rw-r--r-- | src/sp-gradient.cpp | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/src/sp-gradient.cpp b/src/sp-gradient.cpp index b42768f30..0acdac76e 100644 --- a/src/sp-gradient.cpp +++ b/src/sp-gradient.cpp @@ -1531,7 +1531,7 @@ sp_gradient_pattern_common_setup(cairo_pattern_t *cp, static cairo_pattern_t * sp_radialgradient_create_pattern(SPPaintServer *ps, - cairo_t */* ct */, + cairo_t *ct, Geom::OptRect const &bbox, double opacity) { @@ -1540,9 +1540,30 @@ sp_radialgradient_create_pattern(SPPaintServer *ps, gr->ensureVector(); + Geom::Point focus(rg->fx.computed, rg->fy.computed); + Geom::Point center(rg->cx.computed, rg->cy.computed); + double radius = rg->r.computed; + double scale = 1.0; + double tolerance = cairo_get_tolerance(ct); + + // code below suggested by Cairo devs to overcome tolerance problems + // more: https://bugs.freedesktop.org/show_bug.cgi?id=40918 + Geom::Point d = focus - center; + if (d.length() + tolerance > radius) { + scale = radius / d.length(); + + double dx = d.x(), dy = d.y(); + cairo_user_to_device_distance(ct, &dx, &dy); + if (!Geom::are_near(dx, 0, tolerance) || + !Geom::are_near(dy, 0, tolerance)) + { + scale *= 1.0 - 2.0 * tolerance / hypot(dx, dy); + } + } + cairo_pattern_t *cp = cairo_pattern_create_radial( - rg->fx.computed, rg->fy.computed, 0, - rg->cx.computed, rg->cy.computed, rg->r.computed); + scale * d.x() + center.x(), scale * d.y() + center.y(), 0, + center.x(), center.y(), radius); sp_gradient_pattern_common_setup(cp, gr, bbox, opacity); |
