SVG - improve handling of gradientUnits and gradientTransform attributes (radial gradient) + correct default values [skip ci]
This commit is contained in:
parent
1c6d14eb85
commit
dcfb2d692c
4 changed files with 33 additions and 25 deletions
|
@ -64,6 +64,8 @@ MAPNIK_DISABLE_WARNING_PUSH
|
||||||
#include "agg_span_interpolator_linear.h"
|
#include "agg_span_interpolator_linear.h"
|
||||||
MAPNIK_DISABLE_WARNING_POP
|
MAPNIK_DISABLE_WARNING_POP
|
||||||
|
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
namespace svg {
|
namespace svg {
|
||||||
|
|
||||||
|
@ -222,16 +224,14 @@ class renderer_agg : util::noncopyable
|
||||||
}
|
}
|
||||||
if (m_gradient_lut.build_lut())
|
if (m_gradient_lut.build_lut())
|
||||||
{
|
{
|
||||||
agg::trans_affine transform = mtx;
|
agg::trans_affine tr = mtx;
|
||||||
double scale = mtx.scale();
|
agg::trans_affine transform = grad.get_transform();
|
||||||
transform.invert();
|
|
||||||
agg::trans_affine tr;
|
|
||||||
tr = grad.get_transform();
|
|
||||||
tr.invert();
|
|
||||||
transform *= tr;
|
transform *= tr;
|
||||||
|
transform.invert();
|
||||||
|
|
||||||
if (grad.get_units() != USER_SPACE_ON_USE)
|
if (grad.get_units() != USER_SPACE_ON_USE)
|
||||||
{
|
{
|
||||||
|
double scale = mtx.scale();
|
||||||
double bx1 = symbol_bbox.minx();
|
double bx1 = symbol_bbox.minx();
|
||||||
double by1 = symbol_bbox.miny();
|
double by1 = symbol_bbox.miny();
|
||||||
double bx2 = symbol_bbox.maxx();
|
double bx2 = symbol_bbox.maxx();
|
||||||
|
@ -244,7 +244,17 @@ class renderer_agg : util::noncopyable
|
||||||
transform.translate(-bx1 / scale, -by1 / scale);
|
transform.translate(-bx1 / scale, -by1 / scale);
|
||||||
transform.scale(scale / (bx2 - bx1), scale / (by2 - by1));
|
transform.scale(scale / (bx2 - bx1), scale / (by2 - by1));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double scaledown = 255;
|
||||||
|
x1 /= scaledown; // fx
|
||||||
|
y1 /= scaledown; // fy
|
||||||
|
x2 /= scaledown; // cx
|
||||||
|
y2 /= scaledown; // cy
|
||||||
|
radius /= scaledown;
|
||||||
|
transform.translate(-symbol_bbox.minx(), -symbol_bbox.miny());
|
||||||
|
transform.scale(1 / scaledown, 1 / scaledown);
|
||||||
|
}
|
||||||
if (grad.get_gradient_type() == RADIAL)
|
if (grad.get_gradient_type() == RADIAL)
|
||||||
{
|
{
|
||||||
using gradient_adaptor_type = agg::gradient_radial_focus;
|
using gradient_adaptor_type = agg::gradient_radial_focus;
|
||||||
|
@ -253,7 +263,6 @@ class renderer_agg : util::noncopyable
|
||||||
|
|
||||||
// the agg radial gradient assumes it is centred on 0
|
// the agg radial gradient assumes it is centred on 0
|
||||||
transform.translate(-x2, -y2);
|
transform.translate(-x2, -y2);
|
||||||
|
|
||||||
// scale everything up since agg turns things into integers a bit too soon
|
// scale everything up since agg turns things into integers a bit too soon
|
||||||
int scaleup = 255;
|
int scaleup = 255;
|
||||||
radius *= scaleup;
|
radius *= scaleup;
|
||||||
|
@ -261,7 +270,6 @@ class renderer_agg : util::noncopyable
|
||||||
y1 *= scaleup;
|
y1 *= scaleup;
|
||||||
x2 *= scaleup;
|
x2 *= scaleup;
|
||||||
y2 *= scaleup;
|
y2 *= scaleup;
|
||||||
|
|
||||||
transform.scale(scaleup, scaleup);
|
transform.scale(scaleup, scaleup);
|
||||||
|
|
||||||
interpolator_type span_interpolator(transform);
|
interpolator_type span_interpolator(transform);
|
||||||
|
|
|
@ -70,8 +70,8 @@ gradient& gradient::operator=(gradient rhs)
|
||||||
bool gradient::operator==(gradient const& other) const
|
bool gradient::operator==(gradient const& other) const
|
||||||
{
|
{
|
||||||
return transform_ == other.transform_ && x1_ == other.x1_ && y1_ == other.y1_ && x2_ == other.x2_ &&
|
return transform_ == other.transform_ && x1_ == other.x1_ && y1_ == other.y1_ && x2_ == other.x2_ &&
|
||||||
y2_ == other.y2_ && r_ == other.r_ && std::equal(stops_.begin(), stops_.end(), other.stops_.begin()) &&
|
y2_ == other.y2_ && r_ == other.r_ && std::equal(stops_.begin(), stops_.end(), other.stops_.begin()) &&
|
||||||
units_ == other.units_ && gradient_type_ == other.gradient_type_;
|
units_ == other.units_ && gradient_type_ == other.gradient_type_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void gradient::set_gradient_type(gradient_e grad)
|
void gradient::set_gradient_type(gradient_e grad)
|
||||||
|
|
|
@ -1533,8 +1533,8 @@ void parse_radial_gradient(svg_parser& parser, rapidxml::xml_node<char> const* n
|
||||||
return;
|
return;
|
||||||
double cx = 0.5;
|
double cx = 0.5;
|
||||||
double cy = 0.5;
|
double cy = 0.5;
|
||||||
double fx = 0.0;
|
double fx = 0.5;
|
||||||
double fy = 0.0;
|
double fy = 0.5;
|
||||||
double r = 0.5;
|
double r = 0.5;
|
||||||
bool has_percent = false;
|
bool has_percent = false;
|
||||||
|
|
||||||
|
@ -1543,12 +1543,20 @@ void parse_radial_gradient(svg_parser& parser, rapidxml::xml_node<char> const* n
|
||||||
{
|
{
|
||||||
cx = parse_svg_value(parser, attr->value(), has_percent);
|
cx = parse_svg_value(parser, attr->value(), has_percent);
|
||||||
}
|
}
|
||||||
|
else if (gr.get_units() == USER_SPACE_ON_USE)
|
||||||
|
{
|
||||||
|
cx = 0.5 * (parser.vbox_ ? parser.vbox_->width : parser.path_.width()); // 50%
|
||||||
|
}
|
||||||
|
|
||||||
attr = node->first_attribute("cy");
|
attr = node->first_attribute("cy");
|
||||||
if (attr != nullptr)
|
if (attr != nullptr)
|
||||||
{
|
{
|
||||||
cy = parse_svg_value(parser, attr->value(), has_percent);
|
cy = parse_svg_value(parser, attr->value(), has_percent);
|
||||||
}
|
}
|
||||||
|
else if (gr.get_units() == USER_SPACE_ON_USE)
|
||||||
|
{
|
||||||
|
cy = 0.5 * (parser.vbox_ ? parser.vbox_->height : parser.path_.height()); // 50%
|
||||||
|
}
|
||||||
|
|
||||||
attr = node->first_attribute("fx");
|
attr = node->first_attribute("fx");
|
||||||
if (attr != nullptr)
|
if (attr != nullptr)
|
||||||
|
@ -1573,19 +1581,11 @@ void parse_radial_gradient(svg_parser& parser, rapidxml::xml_node<char> const* n
|
||||||
{
|
{
|
||||||
r = parse_svg_value(parser, attr->value(), has_percent);
|
r = parse_svg_value(parser, attr->value(), has_percent);
|
||||||
}
|
}
|
||||||
// this logic for detecting %'s will not support mixed coordinates.
|
else if (gr.get_units() == USER_SPACE_ON_USE)
|
||||||
if (gr.get_units() == USER_SPACE_ON_USE)
|
|
||||||
{
|
{
|
||||||
if (!has_percent && parser.path_.width() > 0 && parser.path_.height() > 0)
|
r = 0.5 * parser.normalized_diagonal_; // 50%
|
||||||
{
|
|
||||||
fx /= parser.path_.width();
|
|
||||||
fy /= parser.path_.height();
|
|
||||||
cx /= parser.path_.width();
|
|
||||||
cy /= parser.path_.height();
|
|
||||||
r /= parser.path_.width();
|
|
||||||
}
|
|
||||||
gr.set_units(USER_SPACE_ON_USE_BOUNDING_BOX);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
gr.set_gradient_type(RADIAL);
|
gr.set_gradient_type(RADIAL);
|
||||||
gr.set_control_points(fx, fy, cx, cy, r);
|
gr.set_control_points(fx, fy, cx, cy, r);
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit ac363ee887d2a55039fd19390c186663d8f0f206
|
Subproject commit 540561debb38280deb1b9598de1724e0ebd8df49
|
Loading…
Add table
Reference in a new issue