summaryrefslogtreecommitdiffstats
path: root/src/sp-radial-gradient.cpp
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2013-10-02 22:35:52 +0000
committerJabiertxof <jtx@jtx.marker.es>2013-10-02 22:35:52 +0000
commit9240dbde4547c7e7529f31645ea916faae72bafa (patch)
tree82c7e2e222dd3bd92dea9a21ed60c0479f0149b8 /src/sp-radial-gradient.cpp
parentupdate to trunk (diff)
parentFix segment welding in the node tool hanging when a two-point segment (diff)
downloadinkscape-9240dbde4547c7e7529f31645ea916faae72bafa.tar.gz
inkscape-9240dbde4547c7e7529f31645ea916faae72bafa.zip
update to trunk
(bzr r12588.1.10)
Diffstat (limited to 'src/sp-radial-gradient.cpp')
-rw-r--r--src/sp-radial-gradient.cpp36
1 files changed, 22 insertions, 14 deletions
diff --git a/src/sp-radial-gradient.cpp b/src/sp-radial-gradient.cpp
index c8bf5db81..7c481fead 100644
--- a/src/sp-radial-gradient.cpp
+++ b/src/sp-radial-gradient.cpp
@@ -156,28 +156,36 @@ cairo_pattern_t* SPRadialGradient::pattern_new(cairo_t *ct, Geom::OptRect const
// https://bugs.launchpad.net/inkscape/+bug/970355
Geom::Affine gs2user = this->gradientTransform;
- Geom::Scale gs2user_scale;
if (this->getUnits() == SP_GRADIENT_UNITS_OBJECTBOUNDINGBOX && bbox) {
Geom::Affine bbox2user(bbox->width(), 0, 0, bbox->height(), bbox->left(), bbox->top());
gs2user *= bbox2user;
- gs2user_scale = Geom::Scale( gs2user[0], gs2user[3] );
}
- Geom::Point d = focus - center;
- Geom::Point d_user = d * gs2user_scale;
- Geom::Point r_user( radius, 0 );
- r_user *= gs2user_scale;
-
- if (d_user.length() + tolerance > r_user.length()) {
+ // we need to use vectors with the same direction to represent the transformed
+ // radius and the focus-center delta, because gs2user might contain non-uniform scaling
+ Geom::Point d(focus - center);
+ Geom::Point d_user(d.length(), 0);
+ Geom::Point r_user(radius, 0);
+ d_user *= gs2user.withoutTranslation();
+ r_user *= gs2user.withoutTranslation();
+
+ double dx = d_user.x(), dy = d_user.y();
+ cairo_user_to_device_distance(ct, &dx, &dy);
+
+ // compute the tolerance distance in user space
+ // create a vector with the same direction as the transformed d,
+ // with the length equal to tolerance
+ double dl = hypot(dx, dy);
+ double tx = tolerance * dx / dl, ty = tolerance * dy / dl;
+ cairo_device_to_user_distance(ct, &tx, &ty);
+ double tolerance_user = hypot(tx, ty);
+
+ if (d_user.length() + tolerance_user > r_user.length()) {
scale = r_user.length() / d_user.length();
- double dx = d_user.x(), dy = d_user.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);
- }
+ // nudge the focus slightly inside
+ scale *= 1.0 - 2.0 * tolerance / dl;
}
cairo_pattern_t *cp = cairo_pattern_create_radial(