diff --git a/CHANGELOG.md b/CHANGELOG.md index 50e982d7e..33a7f8803 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,11 +4,13 @@ A simple log of core changes affecting Mapnik usage. Developers: Please commit along with changes. -For a complete change history, see the SVN log. +For a complete change history, see the git log. ## Mapnik 2.1.0 +Not yet released + - PostGIS: Added 'simplify_geometries' option - will trigger ST_Simplify on geometries before returning to Mapnik (#1179) - Improved error feedback for invalid values passed to map.query_point @@ -48,7 +50,9 @@ For a complete change history, see the SVN log. ## Mapnik 2.0.1 -(Packaged from 5cd3cb2efdaf7e9990a57e8e00b652a81aaa39ae) +Released April 10, 2012 + +(Packaged from 57347e9106) - Support for PostGIS 2.0 (#956,#1083) @@ -83,6 +87,10 @@ For a complete change history, see the SVN log. ## Mapnik 2.0.0 +Released September 26, 2011 + +(Packaged from 5b4c20eab3) + - Add minimum-path-length property to text_symbolizer to allow labels to be placed only on lines of a certain length (#865) - Add support for png quantization using fixed palettes (#843) @@ -170,7 +178,11 @@ For a complete change history, see the SVN log. - Implement MarkersSymbolizer in Cairo render and improve the markers placement finder. (#553) -# Mapnik 0.7.2 Release +# Mapnik 0.7.2 + +Released Oct 18, 2011 + +(Packaged from bc5cabeb6a) - Added forward compatibility for Mapnik 2.0 XML syntax (https://trac.mapnik.org/wiki/Mapnik2/Changes) @@ -213,9 +225,53 @@ For a complete change history, see the SVN log. - Fixed reading of label_position_tolerance on text_symbolizer and height for building_symbolizer -# Mapnik 0.7.0 Release +# Mapnik 0.7.1 -(Packaged from r1574) +Released March 23, 2010 + +(Packaged from r1745/db89f1ca75) + +- Rasters: Various fixes and improvements to 8bit png output ([#522](https://github.com/mapnik/mapnik/issues/522),[#475](https://github.com/mapnik/mapnik/issues/475)) + +- XML: Save map buffer_size when serializing map. + +- SCons: Added new build options 'PRIORITIZE_LINKING' and 'LINK_PRIORITY'. The first is a boolean (default True) + of whether to use the new sorting implementation that gives explcit preference to custom or local paths + during compile and linking that will affect builds when duplicate libraries and include directories are on the + system. LINK_PRIORITY defaults to prioritizing internal sources of the mapnik source folder, then local/user + installed libraries over system libraries, but the option can be customized. Sorting not only ensures that + compiling and linking will more likely match the desired libraries but also gives more likelyhood to avoid + the scenario where libraries are linked that don't match the includes libmapnik compiled against. + +- XML: Fixed behavior of PolygonPatternSymbolizer and LinePatternSymbolizer whereby width, height, + and type of images is actually allowed to be optionally ommitted ([#508](https://github.com/mapnik/mapnik/issues/508)). This was added in r1543 but + only worked correctly for PointSymbolizer and ShieldSymbolizer. + +- Fixed reading of PostGIS data on Big Endian systems ([#515](https://github.com/mapnik/mapnik/issues/515)) + +- PostGIS: Added better support for alterative schemas ([#500](https://github.com/mapnik/mapnik/issues/500)) + +- AGG Renderer - Enforced default gamma function on all symbolizers to ensure proper antialiasing + even when gamma is modified on the PolygonSymbolizer. ([#512](https://github.com/mapnik/mapnik/issues/512)) + +- PNG: fixed png256 for large images and some improvements to reduce color corruptions ([#522](https://github.com/mapnik/mapnik/issues/522)) + +- PNG: Added new quantization method for indexed png format using hextree with full support for alpha + channel. Also new method has some optimizations for color gradients common when using elevation based + rasters. By default old method using octree is used. (r1680, r1683, [#477](https://github.com/mapnik/mapnik/issues/477)) + +- PNG: Added initial support for passing options to png writter like number of colors, transparency + support, quantization method and possibly other in future using type parameter. For example + "png8:c=128:t=1:m=h" limits palette to 128 colors, uses only binary transparency (0 - none, + 1 - binary, 2 - full), and new method of quantization using hextree (h - hextree, o - octree). + Existing type "png256" can be also written using "png8:c=256:m=o:t=2" (r1680, r1683, [#477](https://github.com/mapnik/mapnik/issues/477)) + + +# Mapnik 0.7.0 + +Released January, 19 2010 + +(Packaged from r1574/a0da946be9) - Core: Fixed linking to external libagg (r1297,r1299) @@ -353,10 +409,11 @@ For a complete change history, see the SVN log. - Fonts: Added unifont to auto-installed fonts, which is used by the OSM styles as a fallback font (r1328) +# Mapnik 0.6.1 -# Mapnik 0.6.1 Release +Released July 14, 2009 -(Packaged from r1247) +(Packaged from r1247/353ff576c7) - Plugins: expose list of registered plugins as a 'plugin_names()' method of DatasourceCache (r1180) @@ -437,10 +494,11 @@ For a complete change history, see the SVN log. - Plugins: Fixed segfault in OGR Plugin with empty geometries (r1074) (#292) +# Mapnik 0.6.0 -# Mapnik 0.6.0 Release +Released April 1, 2009 -(Packaged from r1066) +(Packaged from r1066/c88e03436f) - Python: Added support for aspect_fix_mode (r1013) @@ -530,3 +588,27 @@ For a complete change history, see the SVN log. - Plugins: Use memory mapped files for reading shape file (r628) - Core: Use streams to write images (i/o refactor) (r628) (#15) + +# Mapnik 0.5.1 + +Released April 15, 2008 + +(Packaged from c29cb7386d) + +# Mapnik 0.5.0 + +Released April 15, 2008 + +(Packaged from 0464a3563c) + +# Mapnik 0.4.0 + +Released February 26, 2007 + +(Packaged from 8d73e3a8dc) + +# Mapnik 0.3.0 + +Released May 22, 2006 + +(Packaged from 3ae046ebe2) diff --git a/boost/gil/extension/toolbox/hsl.hpp b/boost/gil/extension/toolbox/hsl.hpp new file mode 100644 index 000000000..d22afef19 --- /dev/null +++ b/boost/gil/extension/toolbox/hsl.hpp @@ -0,0 +1,263 @@ +// Copyright 2007 Christian Henning. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/*************************************************************************************************/ + +#ifndef GIL_HSL_H +#define GIL_HSL_H + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Support for HSL color space +/// \author Christian Henning \n +//////////////////////////////////////////////////////////////////////////////////////// + +#include + +namespace boost { namespace gil { + +/// \addtogroup ColorNameModel +/// \{ +namespace hsl_color_space +{ +/// \brief Hue +struct hue_t {}; +/// \brief Saturation +struct saturation_t {}; +/// \brief Lightness +struct lightness_t {}; +} +/// \} + +/// \ingroup ColorSpaceModel +typedef mpl::vector3< hsl_color_space::hue_t + , hsl_color_space::saturation_t + , hsl_color_space::lightness_t + > hsl_t; + +/// \ingroup LayoutModel +typedef layout hsl_layout_t; + + +GIL_DEFINE_ALL_TYPEDEFS( 32f, hsl ); + +/// \ingroup ColorConvert +/// \brief RGB to HSL +template <> +struct default_color_converter_impl< rgb_t, hsl_t > +{ + template + void operator()( const P1& src, P2& dst ) const + { + using namespace hsl_color_space; + + // only bits32f for hsl is supported + bits32f temp_red = channel_convert( get_color( src, red_t() )); + bits32f temp_green = channel_convert( get_color( src, green_t() )); + bits32f temp_blue = channel_convert( get_color( src, blue_t() )); + + bits32f hue, saturation, lightness; + + bits32f min_color = std::min( temp_red, std::min( temp_green, temp_blue )); + bits32f max_color = std::max( temp_red, std::max( temp_green, temp_blue )); + + if ( max_color - min_color < 0.001 ) + { + // rgb color is gray + + hue = 0.f; + saturation = 0.f; + + // doesn't matter which rgb channel we use. + lightness = temp_red; + } + else + { + + bits32f diff = max_color - min_color; + + // lightness calculation + + lightness = ( min_color + max_color ) / 2.f; + + // saturation calculation + + if( lightness < 0.5f ) + { + saturation = diff + / ( min_color + max_color ); + } + else + { + saturation = ( max_color - min_color ) + / ( 2.f - diff ); + + } + + // hue calculation + if( std::abs( max_color - temp_red ) < 0.0001f ) + { + // max_color is red + hue = ( temp_green - temp_blue ) + / diff; + + } + else if( std::abs( max_color - temp_green) < 0.0001f ) + { + // max_color is green + // 2.0 + (b - r) / (maxColor - minColor) + hue = 2.f + + ( temp_blue - temp_red ) + / diff; + + } + else + { + // max_color is blue + // 4.0 + (r - g) / (maxColor - minColor) + hue = 4.f + + ( temp_red - temp_green ) + / diff; + } + + hue /= 6.f; + + if( hue < 0.f ) + { + hue += 1.f; + } + } + + get_color( dst,hue_t() ) = hue; + get_color( dst,saturation_t() ) = saturation; + get_color( dst,lightness_t() ) = lightness; + } +}; + +/// \ingroup ColorConvert +/// \brief HSL to RGB +template <> +struct default_color_converter_impl +{ + template + void operator()( const P1& src, P2& dst) const + { + using namespace hsl_color_space; + + bits32f red, green, blue; + + if( std::abs( get_color( src, saturation_t() )) < 0.0001 ) + { + // If saturation is 0, the color is a shade of gray + red = get_color( src, lightness_t() ); + green = get_color( src, lightness_t() ); + blue = get_color( src, lightness_t() ); + } + else + { + float temp1, temp2; + float tempr, tempg, tempb; + + //Set the temporary values + if( get_color( src, lightness_t() ) < 0.5 ) + { + temp2 = get_color( src, lightness_t() ) + * ( 1.f + get_color( src, saturation_t() ) ); + } + else + { + temp2 = ( get_color( src, lightness_t() ) + get_color( src, saturation_t() )) + - ( get_color( src, lightness_t() ) * get_color( src, saturation_t() )); + } + + temp1 = 2.f + * get_color( src, lightness_t() ) + - temp2; + + tempr = get_color( src, hue_t() ) + 1.f / 3.f; + + if( tempr > 1.f ) + { + tempr--; + } + + tempg = get_color( src, hue_t() ); + tempb = get_color( src, hue_t() ) - 1.f / 3.f; + + if( tempb < 0.f ) + { + tempb++; + } + + //Red + if( tempr < 1.f / 6.f ) + { + red = temp1 + ( temp2 - temp1 ) * 6.f * tempr; + } + else if( tempr < 0.5f ) + { + red = temp2; + } + else if( tempr < 2.f / 3.f ) + { + red = temp1 + (temp2 - temp1) + * (( 2.f / 3.f ) - tempr) * 6.f; + } + else + { + red = temp1; + } + + //Green + if( tempg < 1.f / 6.f ) + { + green = temp1 + ( temp2 - temp1 ) * 6.f * tempg; + } + else if( tempg < 0.5f ) + { + green = temp2; + } + else if( tempg < 2.f / 3.f ) + { + green = temp1 + ( temp2 - temp1 ) + * (( 2.f / 3.f ) - tempg) * 6.f; + } + else + { + green = temp1; + } + + //Blue + if( tempb < 1.f / 6.f ) + { + blue = temp1 + (temp2 - temp1) * 6.f * tempb; + } + else if( tempb < 0.5f ) + { + blue = temp2; + } + else if( tempb < 2.f / 3.f ) + { + blue = temp1 + (temp2 - temp1) + * (( 2.f / 3.f ) - tempb) * 6.f; + } + else + { + blue = temp1; + } + } + + get_color(dst,red_t()) = + channel_convert::type>( red ); + get_color(dst,green_t())= + channel_convert::type>( green ); + get_color(dst,blue_t()) = + channel_convert::type>( blue ); + } +}; + +} } // namespace boost::gil + +#endif // GIL_HSL_H diff --git a/boost/gil/extension/toolbox/hsv.hpp b/boost/gil/extension/toolbox/hsv.hpp new file mode 100644 index 000000000..afaf1ff8a --- /dev/null +++ b/boost/gil/extension/toolbox/hsv.hpp @@ -0,0 +1,231 @@ +// Copyright 2004 Christian Henning. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) + +/*************************************************************************************************/ + +#ifndef GIL_HSV_H +#define GIL_HSV_H + +//////////////////////////////////////////////////////////////////////////////////////// +/// \file +/// \brief Support for HSV color space +/// \author Christian Henning \n +//////////////////////////////////////////////////////////////////////////////////////// + +#include +#include + +namespace boost { namespace gil { + +/// \addtogroup ColorNameModel +/// \{ +namespace hsv_color_space +{ +/// \brief Hue +struct hue_t {}; +/// \brief Saturation +struct saturation_t{}; +/// \brief Value +struct value_t {}; +} +/// \} + +/// \ingroup ColorSpaceModel +typedef mpl::vector3< hsv_color_space::hue_t + , hsv_color_space::saturation_t + , hsv_color_space::value_t + > hsv_t; + +/// \ingroup LayoutModel +typedef layout hsv_layout_t; + + +GIL_DEFINE_ALL_TYPEDEFS( 32f, hsv ) + +/// \ingroup ColorConvert +/// \brief RGB to HSV +template <> +struct default_color_converter_impl< rgb_t, hsv_t > +{ + template + void operator()( const P1& src, P2& dst ) const + { + using namespace hsv_color_space; + + // only bits32f for hsv is supported + bits32f temp_red = channel_convert( get_color( src, red_t() )); + bits32f temp_green = channel_convert( get_color( src, green_t() )); + bits32f temp_blue = channel_convert( get_color( src, blue_t() )); + + bits32f hue, saturation, value; + + bits32f min_color = std::min(temp_red,std::min(temp_green, temp_blue)); + bits32f max_color = std::max(temp_red,std::max(temp_green, temp_blue)); + + value = max_color; + + bits32f diff = max_color - min_color; + + if( max_color < 0.0001f ) + { + saturation = 0.f; + } + else + { + saturation = diff / max_color; + } + + + if( saturation < 0.0001f ) + { + //it doesn't matter what value it has + hue = 0.f; + } + else + { + if( std::abs( boost::numeric_cast(temp_red - max_color) ) < 0.0001f ) + { + hue = ( temp_green - temp_blue ) + / diff; + } + else if( temp_green == max_color ) + { + hue = 2.f + ( temp_blue - temp_red ) + / diff; + } + else + { + hue = 4.f + ( temp_red - temp_green ) + / diff; + } + + //to bring it to a number between 0 and 1 + hue /= 6.f; + + if( hue < 0.f ) + { + hue++; + } + } + + get_color( dst, hue_t() ) = hue; + get_color( dst, saturation_t() ) = saturation; + get_color( dst, value_t() ) = value; + } +}; + +/// \ingroup ColorConvert +/// \brief HSV to RGB +template <> +struct default_color_converter_impl +{ + template + void operator()( const P1& src, P2& dst) const + { + using namespace hsv_color_space; + + bits32f red, green, blue; + + //If saturation is 0, the color is a shade of gray + if( std::abs( get_color( src, saturation_t() )) < 0.0001f ) + { + // If saturation is 0, the color is a shade of gray + red = get_color( src, value_t() ); + green = get_color( src, value_t() ); + blue = get_color( src, value_t() ); + } + else + { + bits32f frac, p, q, t, h; + bits32 i; + + //to bring hue to a number between 0 and 6, better for the calculations + h = get_color( src, hue_t() ); + h *= 6.f; + + i = static_cast( floor( h )); + + frac = h - i; + + p = get_color( src, value_t() ) + * ( 1.f - get_color( src, saturation_t() )); + + q = get_color( src, value_t() ) + * ( 1.f - ( get_color( src, saturation_t() ) * frac )); + + t = get_color( src, value_t() ) + * ( 1.f - ( get_color( src, saturation_t() ) * ( 1.f - frac ))); + + switch( i ) + { + case 0: + { + red = get_color( src, value_t() ); + green = t; + blue = p; + + break; + } + + case 1: + { + red = q; + green = get_color( src, value_t() ); + blue = p; + + break; + } + + case 2: + { + red = p; + green = get_color( src, value_t() ); + blue = t; + + break; + } + + case 3: + { + red = p; + green = q; + blue = get_color( src, value_t() ); + + break; + } + + case 4: + { + red = t; + green = p; + blue = get_color( src, value_t() ); + + break; + } + + case 5: + { + red = get_color( src, value_t() ); + green = p; + blue = q; + + break; + } + + } + } + + get_color(dst,red_t()) = + channel_convert::type>( red ); + get_color(dst,green_t())= + channel_convert::type>( green ); + get_color(dst,blue_t()) = + channel_convert::type>( blue ); + } +}; + +} } // namespace boost::gil + +#endif // GIL_HSV_H diff --git a/deps/agg/build.py b/deps/agg/build.py index 9e2db94a3..04c67735a 100644 --- a/deps/agg/build.py +++ b/deps/agg/build.py @@ -28,4 +28,4 @@ if env['SUNCC']: else: cxxflags = env['CUSTOM_CXXFLAGS'] + ' -O%s -fPIC -DNDEBUG' % env['OPTIMIZATION'] -agg_env.StaticLibrary('agg', glob.glob('./src/' + '*.cpp'), LIBS=[], CPPPATH='./include', CXXFLAGS=cxxflags, LINKFLAGS=env['CUSTOM_LDFLAGS']) \ No newline at end of file +agg_env.StaticLibrary('agg', glob.glob('./src/' + '*.cpp'), LIBS=[], CXXFLAGS=cxxflags, LINKFLAGS=env['CUSTOM_LDFLAGS']) \ No newline at end of file diff --git a/deps/agg/include/agg_pixfmt_rgba.h b/deps/agg/include/agg_pixfmt_rgba.h index 7d2ef4f0a..6d27d8f42 100644 --- a/deps/agg/include/agg_pixfmt_rgba.h +++ b/deps/agg/include/agg_pixfmt_rgba.h @@ -31,6 +31,11 @@ #include "agg_color_rgba.h" #include "agg_rendering_buffer.h" +#include +#include + +#include + namespace agg { @@ -1428,6 +1433,54 @@ namespace agg } }; + // color spin + template + struct comp_op_rgba_color_spin + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + static AGG_INLINE void blend_pix(value_type* p, + // source rgb + unsigned sr, unsigned sg, unsigned sb, + // source alpha and opacity + unsigned sa, unsigned cover) { + if (cover < 255) { + sa = (sa * cover + 255) >> 8; + } + p[Order::R] = (value_type)(((0 + base_mask) >> base_shift)); + p[Order::G] = (value_type)(((0 + base_mask) >> base_shift)); + p[Order::B] = (value_type)(((0 + base_mask) >> base_shift)); + p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); + + // http://en.wikipedia.org/wiki/File:HSV-RGB-comparison.svg + if (p[Order::A] < 64) { + p[Order::G] = ((p[Order::A] - 64) * 4); + p[Order::B] = 255; + } + if (p[Order::A] >= 64 && p[Order::A] < 128) { + p[Order::G] = 255; + p[Order::B] = 255 - ((p[Order::A] - 64) * 4); + } + if (p[Order::A] >= 128 && p[Order::A] < 192) { + p[Order::R] = ((p[Order::A] - 128) * 4); + p[Order::G] = 255; + } + if (p[Order::A] >= 192) { + p[Order::R] = 255; + p[Order::G] = 255 - ((p[Order::A] - 192) * 4); + } + } + }; + // grain extract (GIMP) // E = I - M + 128 @@ -1471,6 +1524,191 @@ namespace agg } }; + template + struct comp_op_rgba_hue + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if (cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + + if (sa > 0) + { + using namespace boost; + using namespace gil; + using namespace hsv_color_space; + rgb8_pixel_t rgb_src(sr,sg,sb); + rgb8_pixel_t rgb_dst(p[Order::R],p[Order::G],p[Order::B]); + hsv32f_pixel_t hsv_src,hsv_dst; + color_convert(rgb_src, hsv_src); + color_convert(rgb_dst, hsv_dst); + get_color(hsv_dst,hue_t()) = get_color(hsv_src,hue_t()); + color_convert(hsv_dst, rgb_dst); + p[Order::R] = get_color(rgb_dst,red_t()); + p[Order::G] = get_color(rgb_dst,green_t()); + p[Order::B] = get_color(rgb_dst,blue_t()); + p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); + } + } + }; + + template + struct comp_op_rgba_saturation + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if (cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + + if (sa > 0) + { + using namespace boost; + using namespace gil; + using namespace hsv_color_space; + rgb8_pixel_t rgb_src(sr,sg,sb); + rgb8_pixel_t rgb_dst(p[Order::R],p[Order::G],p[Order::B]); + hsv32f_pixel_t hsv_src,hsv_dst; + color_convert( rgb_src, hsv_src); + color_convert( rgb_dst, hsv_dst); + get_color(hsv_dst,saturation_t()) = get_color(hsv_src,saturation_t()); + color_convert(hsv_dst, rgb_dst); + p[Order::R] = get_color(rgb_dst,red_t()); + p[Order::G] = get_color(rgb_dst,green_t()); + p[Order::B] = get_color(rgb_dst,blue_t()); + p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); + } + } + }; + + template + struct comp_op_rgba_color + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if (cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + + if (sa > 0) + { + using namespace boost; + using namespace gil; + using namespace hsv_color_space; + rgb8_pixel_t rgb_src(sr,sg,sb); + rgb8_pixel_t rgb_dst(p[Order::R],p[Order::G],p[Order::B]); + hsv32f_pixel_t hsv_src,hsv_dst; + color_convert( rgb_src, hsv_src); + color_convert( rgb_dst, hsv_dst); + get_color(hsv_dst,hue_t()) = get_color(hsv_src,hue_t()); + get_color(hsv_dst,saturation_t()) = get_color(hsv_src,saturation_t()); + color_convert(hsv_dst, rgb_dst); + p[Order::R] = get_color(rgb_dst,red_t()); + p[Order::G] = get_color(rgb_dst,green_t()); + p[Order::B] = get_color(rgb_dst,blue_t()); + p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); + } + } + }; + + + template + struct comp_op_rgba_value + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if (cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + + if (sa > 0) + { + using namespace boost; + using namespace gil; + using namespace hsv_color_space; + rgb8_pixel_t rgb_src(sr,sg,sb); + rgb8_pixel_t rgb_dst(p[Order::R],p[Order::G],p[Order::B]); + hsv32f_pixel_t hsv_src,hsv_dst; + color_convert( rgb_src, hsv_src); + color_convert( rgb_dst, hsv_dst); + get_color(hsv_dst,value_t()) = get_color(hsv_src,value_t()); + color_convert(hsv_dst, rgb_dst); + p[Order::R] = get_color(rgb_dst,red_t()); + p[Order::G] = get_color(rgb_dst,green_t()); + p[Order::B] = get_color(rgb_dst,blue_t()); + p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift)); + } + } + }; //======================================================comp_op_table_rgba template struct comp_op_table_rgba @@ -1520,6 +1758,11 @@ namespace agg comp_op_rgba_invert_rgb ::blend_pix, comp_op_rgba_grain_merge::blend_pix, comp_op_rgba_grain_extract::blend_pix, + comp_op_rgba_hue::blend_pix, + comp_op_rgba_saturation::blend_pix, + comp_op_rgba_color::blend_pix, + comp_op_rgba_value::blend_pix, + comp_op_rgba_color_spin::blend_pix, 0 }; @@ -1557,15 +1800,14 @@ namespace agg comp_op_invert_rgb, //----comp_op_invert_rgb comp_op_grain_merge, //----comp_op_grain_merge_rgb comp_op_grain_extract, //----comp_op_grain_extract_rgb + comp_op_hue, //----comp_op_hue + comp_op_saturation, //----comp_op_saturation + comp_op_color, //----comp_op_color + comp_op_value, //----comp_op_value + comp_op_color_spin, //----comp_op_color_spin end_of_comp_op_e }; - - - - - - //====================================================comp_op_adaptor_rgba template struct comp_op_adaptor_rgba { diff --git a/include/mapnik/image_compositing.hpp b/include/mapnik/image_compositing.hpp index 09c9e0db1..72beac1d5 100644 --- a/include/mapnik/image_compositing.hpp +++ b/include/mapnik/image_compositing.hpp @@ -70,7 +70,12 @@ enum composite_mode_e invert, invert_rgb, grain_merge, - grain_extract + grain_extract, + hue, + saturation, + _color, + _value, + color_spin }; MAPNIK_DECL boost::optional comp_op_from_string(std::string const& name); diff --git a/src/cairo_renderer.cpp b/src/cairo_renderer.cpp index 05afd8f7d..48997f766 100644 --- a/src/cairo_renderer.cpp +++ b/src/cairo_renderer.cpp @@ -385,10 +385,15 @@ public: case invert_rgb: case grain_merge: case grain_extract: + case hue: + case saturation: + case _color: + case _value: + case color_spin: break; } } - + void set_line_join(line_join_e join) { if (join == MITER_JOIN) diff --git a/src/image_compositing.cpp b/src/image_compositing.cpp index cee42c85f..d2bcbd56c 100644 --- a/src/image_compositing.cpp +++ b/src/image_compositing.cpp @@ -70,6 +70,11 @@ static const comp_op_lookup_type comp_lookup = boost::assign::list_of comp_op_from_string(std::string const& name) diff --git a/src/parse_transform.cpp b/src/parse_transform.cpp index 325d440c6..6892c2cb9 100644 --- a/src/parse_transform.cpp +++ b/src/parse_transform.cpp @@ -22,6 +22,8 @@ #include #include +#include +#include #include diff --git a/src/svg_parser.cpp b/src/svg_parser.cpp index 0f4412e25..22a2ed766 100644 --- a/src/svg_parser.cpp +++ b/src/svg_parser.cpp @@ -139,10 +139,17 @@ void svg_parser::parse(std::string const& filename) if (reader != 0) { int ret = xmlTextReaderRead(reader); - while (ret == 1) + try { + while (ret == 1) + { + process_node(reader); + ret = xmlTextReaderRead(reader); + } + } + catch (std::exception const& ex) { - process_node(reader); - ret = xmlTextReaderRead(reader); + xmlFreeTextReader(reader); + throw; } xmlFreeTextReader(reader); if (ret != 0) @@ -428,26 +435,34 @@ void svg_parser::parse_path(xmlTextReaderPtr reader) value = xmlTextReaderGetAttribute(reader, BAD_CAST "d"); if (value) { - path_.begin_path(); - - if (!mapnik::svg::parse_path((const char*) value, path_)) + // d="" (empty paths) are valid + if (strlen((const char*)value) < 1) { xmlFree(value); - xmlChar *id_value; - id_value = xmlTextReaderGetAttribute(reader, BAD_CAST "id"); - if (id_value) - { - std::string id_string((const char *) id_value); - xmlFree(id_value); - throw std::runtime_error(std::string("unable to parse invalid svg with id '") + id_string + "'"); - } - else - { - throw std::runtime_error("unable to parse invalid svg "); - } } - path_.end_path(); - xmlFree(value); + else + { + path_.begin_path(); + + if (!mapnik::svg::parse_path((const char*) value, path_)) + { + xmlFree(value); + xmlChar *id_value; + id_value = xmlTextReaderGetAttribute(reader, BAD_CAST "id"); + if (id_value) + { + std::string id_string((const char *) id_value); + xmlFree(id_value); + throw std::runtime_error(std::string("unable to parse invalid svg with id '") + id_string + "'"); + } + else + { + throw std::runtime_error("unable to parse invalid svg "); + } + } + path_.end_path(); + xmlFree(value); + } } }