summaryrefslogtreecommitdiffstats
path: root/src/sp-gradient.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/sp-gradient.cpp')
-rw-r--r--src/sp-gradient.cpp31
1 files changed, 25 insertions, 6 deletions
diff --git a/src/sp-gradient.cpp b/src/sp-gradient.cpp
index 5efa3c84f..d7add805d 100644
--- a/src/sp-gradient.cpp
+++ b/src/sp-gradient.cpp
@@ -2051,13 +2051,32 @@ sp_radialgradient_create_pattern(SPPaintServer *ps,
double scale = 1.0;
double tolerance = cairo_get_tolerance(ct);
+ // NOTE: SVG2 will allow the use of a focus circle which can
+ // have its center outside the first circle.
+
// code below suggested by Cairo devs to overcome tolerance problems
// more: https://bugs.freedesktop.org/show_bug.cgi?id=40918
+
+ // Corrected for
+ // https://bugs.launchpad.net/inkscape/+bug/970355
+
+ Geom::Affine gs2user = gr->gradientTransform;
+ Geom::Scale gs2user_scale;
+
+ if (gr->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;
- if (d.length() + tolerance > radius) {
- scale = radius / d.length();
+ Geom::Point d_user = d * gs2user_scale;
+ Geom::Point r_user( radius, 0 );
+ r_user *= gs2user_scale;
- double dx = d.x(), dy = d.y();
+ if (d_user.length() + tolerance > 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))
@@ -2104,15 +2123,15 @@ static cairo_pattern_t *sp_meshgradient_create_pattern(SPPaintServer *ps,
cp = cairo_pattern_create_mesh();
- for( uint i = 0; i < array->patch_rows(); ++i ) {
- for( uint j = 0; j < array->patch_columns(); ++j ) {
+ for( unsigned int i = 0; i < array->patch_rows(); ++i ) {
+ for( unsigned int j = 0; j < array->patch_columns(); ++j ) {
SPMeshPatchI patch( &(array->nodes), i, j );
cairo_mesh_pattern_begin_patch( cp );
cairo_mesh_pattern_move_to( cp, patch.getPoint( 0, 0 )[X], patch.getPoint( 0, 0 )[Y] );
- for( uint k = 0; k < 4; ++k ) {
+ for( unsigned int k = 0; k < 4; ++k ) {
#ifdef DEBUG_MESH
std::cout << i << " " << j << " "
<< patch.getPathType( k ) << " (";