parse and setup ability to known original, declared svg width/height - refs #1122

This commit is contained in:
Dane Springmeyer 2013-03-08 17:40:19 -08:00
parent 2fcd531345
commit 76042a1700
10 changed files with 85 additions and 13 deletions

View file

@ -102,7 +102,7 @@ public:
if (is_bitmap()) if (is_bitmap())
return (*bitmap_data_)->width(); return (*bitmap_data_)->width();
else if (is_vector()) else if (is_vector())
return (*vector_data_)->bounding_box().width(); return (*vector_data_)->width();
return 0; return 0;
} }
inline double height() const inline double height() const
@ -110,7 +110,7 @@ public:
if (is_bitmap()) if (is_bitmap())
return (*bitmap_data_)->height(); return (*bitmap_data_)->height();
else if (is_vector()) else if (is_vector())
return (*vector_data_)->bounding_box().height(); return (*vector_data_)->height();
return 0; return 0;
} }

View file

@ -365,6 +365,8 @@ void build_ellipse(T const& sym, mapnik::feature_impl const& feature, svg_storag
styled_svg.pop_attr(); styled_svg.pop_attr();
double lox,loy,hix,hiy; double lox,loy,hix,hiy;
styled_svg.bounding_rect(&lox, &loy, &hix, &hiy); styled_svg.bounding_rect(&lox, &loy, &hix, &hiy);
styled_svg.set_dimensions(width,height);
marker_ellipse.set_dimensions(width,height);
marker_ellipse.set_bounding_box(lox,loy,hix,hiy); marker_ellipse.set_bounding_box(lox,loy,hix,hiy);
} }
@ -419,7 +421,11 @@ bool push_explicit_style(Attr const& src, Attr & dst, markers_symbolizer const&
} }
template <typename T> template <typename T>
void setup_transform_scaling(agg::trans_affine & tr, box2d<double> const& bbox, mapnik::feature_impl const& feature, T const& sym) void setup_transform_scaling(agg::trans_affine & tr,
double svg_width,
double svg_height,
mapnik::feature_impl const& feature,
T const& sym)
{ {
double width = 0; double width = 0;
double height = 0; double height = 0;
@ -434,18 +440,18 @@ void setup_transform_scaling(agg::trans_affine & tr, box2d<double> const& bbox,
if (width > 0 && height > 0) if (width > 0 && height > 0)
{ {
double sx = width/bbox.width(); double sx = width/svg_width;
double sy = height/bbox.height(); double sy = height/svg_height;
tr *= agg::trans_affine_scaling(sx,sy); tr *= agg::trans_affine_scaling(sx,sy);
} }
else if (width > 0) else if (width > 0)
{ {
double sx = width/bbox.width(); double sx = width/svg_width;
tr *= agg::trans_affine_scaling(sx); tr *= agg::trans_affine_scaling(sx);
} }
else if (height > 0) else if (height > 0)
{ {
double sy = height/bbox.height(); double sy = height/svg_height;
tr *= agg::trans_affine_scaling(sy); tr *= agg::trans_affine_scaling(sy);
} }
} }

View file

@ -308,6 +308,22 @@ public:
agg::bounding_rect(trans, *this, 0, attributes_.size(), x1, y1, x2, y2); agg::bounding_rect(trans, *this, 0, attributes_.size(), x1, y1, x2, y2);
} }
void set_dimensions(double w, double h)
{
svg_width_ = w;
svg_height_ = h;
}
double width()
{
return svg_width_;
}
double height()
{
return svg_height_;
}
VertexSource & storage() VertexSource & storage()
{ {
return source_; return source_;
@ -333,6 +349,8 @@ private:
AttributeSource & attributes_; AttributeSource & attributes_;
AttributeSource attr_stack_; AttributeSource attr_stack_;
agg::trans_affine transform_; agg::trans_affine transform_;
double svg_width_;
double svg_height_;
}; };

View file

@ -51,6 +51,7 @@ namespace mapnik { namespace svg {
void start_element(xmlTextReaderPtr reader); void start_element(xmlTextReaderPtr reader);
void end_element(xmlTextReaderPtr reader); void end_element(xmlTextReaderPtr reader);
void parse_path(xmlTextReaderPtr reader); void parse_path(xmlTextReaderPtr reader);
void parse_dimensions(xmlTextReaderPtr reader);
void parse_polygon(xmlTextReaderPtr reader); void parse_polygon(xmlTextReaderPtr reader);
void parse_polyline(xmlTextReaderPtr reader); void parse_polyline(xmlTextReaderPtr reader);
void parse_line(xmlTextReaderPtr reader); void parse_line(xmlTextReaderPtr reader);

View file

@ -34,7 +34,9 @@ template <typename VertexSource ,typename AttributeSource>
class svg_storage : mapnik::noncopyable class svg_storage : mapnik::noncopyable
{ {
public: public:
svg_storage() {} svg_storage() :
svg_width_(0),
svg_height_(0) {}
VertexSource & source() // FIXME!! make const VertexSource & source() // FIXME!! make const
{ {
@ -61,11 +63,29 @@ public:
return bounding_box_; return bounding_box_;
} }
double width() const
{
return svg_width_;
}
double height() const
{
return svg_height_;
}
void set_dimensions(double w, double h)
{
svg_width_ = w;
svg_height_ = h;
}
private: private:
VertexSource source_; VertexSource source_;
AttributeSource attributes_; AttributeSource attributes_;
box2d<double> bounding_box_; box2d<double> bounding_box_;
double svg_width_;
double svg_height_;
}; };

View file

@ -152,7 +152,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
else else
{ {
box2d<double> const& bbox = (*mark)->bounding_box(); box2d<double> const& bbox = (*mark)->bounding_box();
setup_transform_scaling(tr, bbox, feature, sym); setup_transform_scaling(tr, bbox.width(), bbox.height(), feature, sym);
evaluate_transform(tr, feature, sym.get_image_transform()); evaluate_transform(tr, feature, sym.get_image_transform());
coord2d center = bbox.center(); coord2d center = bbox.center();
agg::trans_affine_translation recenter(-center.x, -center.y); agg::trans_affine_translation recenter(-center.x, -center.y);
@ -193,7 +193,7 @@ void agg_renderer<T>::process(markers_symbolizer const& sym,
else // raster markers else // raster markers
{ {
box2d<double> const& bbox = (*mark)->bounding_box(); box2d<double> const& bbox = (*mark)->bounding_box();
setup_transform_scaling(tr, bbox, feature, sym); setup_transform_scaling(tr, bbox.width(), bbox.height(), feature, sym);
evaluate_transform(tr, feature, sym.get_image_transform()); evaluate_transform(tr, feature, sym.get_image_transform());
coord2d center = bbox.center(); coord2d center = bbox.center();
agg::trans_affine_translation recenter(-center.x, -center.y); agg::trans_affine_translation recenter(-center.x, -center.y);

View file

@ -1162,7 +1162,7 @@ void cairo_renderer_base::process(markers_symbolizer const& sym,
agg::trans_affine geom_tr; agg::trans_affine geom_tr;
evaluate_transform(geom_tr, feature, sym.get_transform()); evaluate_transform(geom_tr, feature, sym.get_transform());
box2d<double> const& bbox = (*mark)->bounding_box(); box2d<double> const& bbox = (*mark)->bounding_box();
setup_transform_scaling(tr, bbox, feature, sym); setup_transform_scaling(tr, bbox.width(), bbox.height(), feature, sym);
evaluate_transform(tr, feature, sym.get_image_transform()); evaluate_transform(tr, feature, sym.get_image_transform());
if ((*mark)->is_vector()) if ((*mark)->is_vector())

View file

@ -167,7 +167,7 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
else else
{ {
box2d<double> const& bbox = (*mark)->bounding_box(); box2d<double> const& bbox = (*mark)->bounding_box();
setup_transform_scaling(tr, bbox, feature, sym); setup_transform_scaling(tr, bbox.width(), bbox.height(), feature, sym);
evaluate_transform(tr, feature, sym.get_image_transform()); evaluate_transform(tr, feature, sym.get_image_transform());
// TODO - clamping to >= 4 pixels // TODO - clamping to >= 4 pixels
coord2d center = bbox.center(); coord2d center = bbox.center();
@ -210,7 +210,7 @@ void grid_renderer<T>::process(markers_symbolizer const& sym,
else // raster markers else // raster markers
{ {
box2d<double> const& bbox = (*mark)->bounding_box(); box2d<double> const& bbox = (*mark)->bounding_box();
setup_transform_scaling(tr, bbox, feature, sym); setup_transform_scaling(tr, bbox.width(), bbox.height(), feature, sym);
evaluate_transform(tr, feature, sym.get_image_transform()); evaluate_transform(tr, feature, sym.get_image_transform());
// - clamp sizes to > 4 pixels of interactivity // - clamp sizes to > 4 pixels of interactivity
coord2d center = bbox.center(); coord2d center = bbox.center();

View file

@ -151,6 +151,7 @@ boost::optional<marker_ptr> marker_cache::find(std::string const& uri,
double lox,loy,hix,hiy; double lox,loy,hix,hiy;
svg.bounding_rect(&lox, &loy, &hix, &hiy); svg.bounding_rect(&lox, &loy, &hix, &hiy);
marker_path->set_bounding_box(lox,loy,hix,hiy); marker_path->set_bounding_box(lox,loy,hix,hiy);
marker_path->set_dimensions(svg.width(),svg.height());
marker_ptr mark(boost::make_shared<marker>(marker_path)); marker_ptr mark(boost::make_shared<marker>(marker_path));
result.reset(mark); result.reset(mark);
if (update_cache) if (update_cache)

View file

@ -265,6 +265,10 @@ void svg_parser::start_element(xmlTextReaderPtr reader)
{ {
parse_ellipse(reader); parse_ellipse(reader);
} }
else if (xmlStrEqual(name, BAD_CAST "svg"))
{
parse_dimensions(reader);
}
#ifdef MAPNIK_LOG #ifdef MAPNIK_LOG
else if (!xmlStrEqual(name, BAD_CAST "svg")) else if (!xmlStrEqual(name, BAD_CAST "svg"))
{ {
@ -451,6 +455,28 @@ void svg_parser::parse_attr(xmlTextReaderPtr reader)
} }
xmlTextReaderMoveToElement(reader); xmlTextReaderMoveToElement(reader);
} }
void svg_parser::parse_dimensions(xmlTextReaderPtr reader)
{
xmlChar *value;
double width = 0;
double height = 0;
value = xmlTextReaderGetAttribute(reader, BAD_CAST "width");
if (value)
{
width = parse_double((const char*)value);
xmlFree(value);
}
xmlChar *value2;
value2 = xmlTextReaderGetAttribute(reader, BAD_CAST "width");
if (value2)
{
height = parse_double((const char*)value2);
xmlFree(value2);
}
path_.set_dimensions(width,height);
}
void svg_parser::parse_path(xmlTextReaderPtr reader) void svg_parser::parse_path(xmlTextReaderPtr reader)
{ {
xmlChar *value; xmlChar *value;