Merge branch 'master' into skia-renderer
|
@ -25,6 +25,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/util/hsl.hpp>
|
||||
|
||||
// spirit2
|
||||
#include <boost/spirit/include/qi.hpp>
|
||||
|
@ -39,24 +40,6 @@
|
|||
// stl
|
||||
#include <string>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
// http://www.w3.org/TR/css3-color/#hsl-color
|
||||
inline double hue_to_rgb( double m1, double m2, double h)
|
||||
{
|
||||
if (h < 0.0) h = h + 1.0;
|
||||
else if (h > 1) h = h - 1.0;
|
||||
|
||||
if (h * 6 < 1.0)
|
||||
return m1 + (m2 - m1) * h * 6.0;
|
||||
if (h * 2 < 1.0)
|
||||
return m2;
|
||||
if (h * 3 < 2.0)
|
||||
return m1 + (m2 - m1)* (2.0/3.0 - h) * 6.0;
|
||||
return m1;
|
||||
}
|
||||
|
||||
} // namespace mapnik
|
||||
|
||||
// boost
|
||||
#include <boost/version.hpp>
|
||||
|
|
|
@ -507,41 +507,46 @@ void apply_filter(Src & src, scale_hsla const& transform)
|
|||
uint8_t & g = get_color(src_it[x], green_t());
|
||||
uint8_t & b = get_color(src_it[x], blue_t());
|
||||
uint8_t & a = get_color(src_it[x], alpha_t());
|
||||
double r2 = static_cast<double>(r)/255.0;
|
||||
double g2 = static_cast<double>(g)/255.0;
|
||||
double b2 = static_cast<double>(b)/255.0;
|
||||
double a2 = static_cast<double>(a)/255.0;
|
||||
double a1 = a2;
|
||||
bool alpha_modified = false;
|
||||
if (set_alpha && a2 > 0.01)
|
||||
{
|
||||
a2 = transform.a0 + (a2 * (transform.a1 - transform.a0));
|
||||
if (a2 <= 0)
|
||||
{
|
||||
a = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = static_cast<unsigned>(std::floor((a2 * 255.0) +.5));
|
||||
if (a > 255) a = 255;
|
||||
}
|
||||
alpha_modified = true;
|
||||
}
|
||||
if (tinting && a > 1)
|
||||
{
|
||||
double h;
|
||||
double s;
|
||||
double l;
|
||||
// demultiply
|
||||
if (a1 <= 0.0)
|
||||
if (a2 <= 0.0)
|
||||
{
|
||||
r = g = b = 0;
|
||||
continue;
|
||||
}
|
||||
else if (a1 < 1)
|
||||
else
|
||||
{
|
||||
r /= a1;
|
||||
g /= a1;
|
||||
b /= a1;
|
||||
r2 /= a2;
|
||||
g2 /= a2;
|
||||
b2 /= a2;
|
||||
}
|
||||
rgb2hsl(r,g,b,h,s,l);
|
||||
if (set_alpha)
|
||||
{
|
||||
a2 = transform.a0 + (a2 * (transform.a1 - transform.a0));
|
||||
if (a2 <= 0)
|
||||
{
|
||||
r = g = b = a = 0;
|
||||
continue;
|
||||
}
|
||||
else if (a2 > 1)
|
||||
{
|
||||
a2 = 1;
|
||||
a = 255;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = static_cast<uint8_t>(std::floor((a2 * 255.0) +.5));
|
||||
}
|
||||
}
|
||||
if (tinting)
|
||||
{
|
||||
double h;
|
||||
double s;
|
||||
double l;
|
||||
rgb2hsl(r2,g2,b2,h,s,l);
|
||||
double h2 = transform.h0 + (h * (transform.h1 - transform.h0));
|
||||
double s2 = transform.s0 + (s * (transform.s1 - transform.s0));
|
||||
double l2 = transform.l0 + (l * (transform.l1 - transform.l0));
|
||||
|
@ -551,35 +556,19 @@ void apply_filter(Src & src, scale_hsla const& transform)
|
|||
else if (s2 < 0) { s2 = 0; }
|
||||
if (l2 > 1) { l2 = 1; }
|
||||
else if (l2 < 0) { l2 = 0; }
|
||||
hsl2rgb(h2,s2,l2,r,g,b);
|
||||
// premultiply
|
||||
// we only work with premultiplied source,
|
||||
// thus all color values must be <= alpha
|
||||
r *= a2;
|
||||
g *= a2;
|
||||
b *= a2;
|
||||
}
|
||||
else if (alpha_modified)
|
||||
{
|
||||
// demultiply
|
||||
if (a1 <= 0.0)
|
||||
{
|
||||
r = g = b = 0;
|
||||
continue;
|
||||
}
|
||||
else if (a1 < 1)
|
||||
{
|
||||
r /= a1;
|
||||
g /= a1;
|
||||
b /= a1;
|
||||
hsl2rgb(h2,s2,l2,r2,g2,b2);
|
||||
}
|
||||
// premultiply
|
||||
// we only work with premultiplied source,
|
||||
// thus all color values must be <= alpha
|
||||
r *= a2;
|
||||
g *= a2;
|
||||
b *= a2;
|
||||
}
|
||||
r2 *= a2;
|
||||
g2 *= a2;
|
||||
b2 *= a2;
|
||||
r = static_cast<uint8_t>(std::floor((r2*255.0)+.5));
|
||||
g = static_cast<uint8_t>(std::floor((g2*255.0)+.5));
|
||||
b = static_cast<uint8_t>(std::floor((b2*255.0)+.5));
|
||||
// all color values must be <= alpha
|
||||
if (r>a) r=a;
|
||||
if (g>a) g=a;
|
||||
if (b>a) b=a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,13 +26,17 @@
|
|||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/config_error.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/variant.hpp>
|
||||
|
||||
// stl
|
||||
#include <vector>
|
||||
#include <ostream>
|
||||
#include <iterator> // for std::back_insert_iterator
|
||||
|
||||
|
||||
namespace mapnik { namespace filter {
|
||||
|
||||
struct blur {};
|
||||
|
@ -66,7 +70,19 @@ struct scale_hsla
|
|||
l0(_l0),
|
||||
l1(_l1),
|
||||
a0(_a0),
|
||||
a1(_a1) {}
|
||||
a1(_a1) {
|
||||
if (h0 < 0 || h0 > 1 ||
|
||||
h1 < 0 || h1 > 1 ||
|
||||
s0 < 0 || s0 > 1 ||
|
||||
s1 < 0 || s1 > 1 ||
|
||||
l0 < 0 || l0 > 1 ||
|
||||
l1 < 0 || l1 > 1 ||
|
||||
a0 < 0 || a0 > 1 ||
|
||||
a1 < 0 || a1 > 1)
|
||||
{
|
||||
throw config_error("scale-hsla values must be between 0 and 1");
|
||||
}
|
||||
}
|
||||
inline bool is_identity() const {
|
||||
return (h0 == 0 &&
|
||||
h1 == 1 &&
|
||||
|
|
|
@ -27,11 +27,8 @@
|
|||
|
||||
namespace mapnik {
|
||||
|
||||
static inline void rgb2hsl(unsigned char red, unsigned char green, unsigned char blue,
|
||||
inline void rgb2hsl(double r, double g, double b,
|
||||
double & h, double & s, double & l) {
|
||||
double r = red/255.0;
|
||||
double g = green/255.0;
|
||||
double b = blue/255.0;
|
||||
double max = std::max(r,std::max(g,b));
|
||||
double min = std::min(r,std::min(g,b));
|
||||
double delta = max - min;
|
||||
|
@ -46,25 +43,30 @@ static inline void rgb2hsl(unsigned char red, unsigned char green, unsigned char
|
|||
}
|
||||
}
|
||||
|
||||
static inline double hueToRGB(double m1, double m2, double h) {
|
||||
if(h < 0) h += 1;
|
||||
if(h > 1) h -= 1;
|
||||
if (h * 6 < 1) return m1 + (m2 - m1) * h * 6;
|
||||
if (h * 2 < 1) return m2;
|
||||
if (h * 3 < 2) return m1 + (m2 - m1) * (0.66666 - h) * 6;
|
||||
// http://www.w3.org/TR/css3-color/#hsl-color
|
||||
inline double hue_to_rgb(double m1, double m2, double h)
|
||||
{
|
||||
if (h < 0.0) h = h + 1.0;
|
||||
else if (h > 1.0) h = h - 1.0;
|
||||
if (h * 6 < 1.0)
|
||||
return m1 + (m2 - m1) * h * 6.0;
|
||||
if (h * 2 < 1.0)
|
||||
return m2;
|
||||
if (h * 3 < 2.0)
|
||||
return m1 + (m2 - m1)* (2.0/3.0 - h) * 6.0;
|
||||
return m1;
|
||||
}
|
||||
|
||||
static inline void hsl2rgb(double h, double s, double l,
|
||||
unsigned char & r, unsigned char & g, unsigned char & b) {
|
||||
inline void hsl2rgb(double h, double s, double l,
|
||||
double & r, double & g, double & b) {
|
||||
if (!s) {
|
||||
r = g = b = static_cast<unsigned char>(std::floor((l * 255.0)+.5));
|
||||
r = g = b = l;
|
||||
}
|
||||
double m2 = (l <= 0.5) ? l * (s + 1) : l + s - l * s;
|
||||
double m1 = l * 2 - m2;
|
||||
r = static_cast<unsigned char>(std::floor((hueToRGB(m1, m2, h + 0.33333) * 255.0)+.5));
|
||||
g = static_cast<unsigned char>(std::floor((hueToRGB(m1, m2, h) * 255.0)+.5));
|
||||
b = static_cast<unsigned char>(std::floor((hueToRGB(m1, m2, h - 0.33333) * 255.0)+.5));
|
||||
double m2 = (l <= 0.5) ? l * (s + 1.0) : l + s - l * s;
|
||||
double m1 = l * 2.0 - m2;
|
||||
r = hue_to_rgb(m1, m2, h + 1.0/3.0);
|
||||
g = hue_to_rgb(m1, m2, h);
|
||||
b = hue_to_rgb(m1, m2, h - 1.0/3.0);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
4
tests/data/broken_maps/invalid-scale-hsla-filter.xml
Normal file
|
@ -0,0 +1,4 @@
|
|||
<Map>
|
||||
<Style name="style" image-filters="scale-hsla(-1,1.1,0,1,0,1,0,1)">
|
||||
</Style>
|
||||
</Map>
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 8 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 29 KiB |
|
@ -1,7 +1,7 @@
|
|||
<Map srs="+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs" background-image="../../data/images/checker.jpg">
|
||||
|
||||
<Style name="ellipse"
|
||||
direct-image-filters=" scale-hsla(0,1,0,1,0,1,0,.5)"
|
||||
direct-image-filters="scale-hsla(0,1,0,1,0,1,0,.5)"
|
||||
image-filters="scale-hsla(.1,.9,.5,1,.5,1,.2,1)"
|
||||
>
|
||||
<Rule>
|
||||
|
|