+ move compositing modes implementation out of Image class

This commit is contained in:
Artem Pavlenko 2009-03-31 10:08:33 +00:00
parent e4f305620f
commit 4a3a9128ec
2 changed files with 100 additions and 99 deletions

View file

@ -42,6 +42,97 @@
namespace mapnik
{
struct Multiply
{
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
unsigned &r1, unsigned &g1, unsigned &b1)
{
r1 = r1*r0/255;
g1 = g1*g0/255;
b1 = b1*b0/255;
}
};
struct Multiply2
{
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
unsigned &r1, unsigned &g1, unsigned &b1)
{
r1 = r1*r0/128;
if (r1>255) r1=255;
g1 = g1*g0/128;
if (g1>255) g1=255;
b1 = b1*b0/128;
if (b1>255) b1=255;
}
};
struct Divide
{
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
unsigned &r1, unsigned &g1, unsigned &b1)
{
r1 = r0*256/(r1+1);
g1 = g0*256/(g1+1);
b1 = b0*256/(b1+1);
}
};
struct Divide2
{
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
unsigned &r1, unsigned &g1, unsigned &b1)
{
r1 = r0*128/(r1+1);
g1 = g0*128/(g1+1);
b1 = b0*128/(b1+1);
}
};
struct Screen
{
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
unsigned &r1, unsigned &g1, unsigned &b1)
{
r1 = 255 - (255-r0)*(255-r1)/255;
g1 = 255 - (255-g0)*(255-g1)/255;
b1 = 255 - (255-b0)*(255-b1)/255;
}
};
struct HardLight
{
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
unsigned &r1, unsigned &g1, unsigned &b1)
{
r1 = (r1>128)?255-(255-r0)*(255-2*(r1-128))/256:r0*r1*2/256;
g1 = (g1>128)?255-(255-g0)*(255-2*(g1-128))/256:g0*g1*2/256;
b1 = (b1>128)?255-(255-b0)*(255-2*(b1-128))/256:b0*b1*2/256;
}
};
struct MergeGrain
{
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
unsigned &r1, unsigned &g1, unsigned &b1)
{
r1 = (r1+r0>128)?r1+r0-128:0;
if (r1>255) r1=255;
g1 = (g1+g0>128)?g1+g0-128:0;
if (g1>255) g1=255;
b1 = (b1+b0>128)?b1+b0-128:0;
if (b1>255) b1=255;
}
};
struct MergeGrain2
{
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
unsigned &r1, unsigned &g1, unsigned &b1)
{
r1 = (2*r1+r0>256)?2*r1+r0-256:0;
if (r1>255) r1=255;
g1 = (2*g1+g0>256)?2*g1+g0-256:0;
if (g1>255) g1=255;
b1 = (2*b1+b0>256)?2*b1+b0-256:0;
if (b1>255) b1=255;
}
};
class MAPNIK_DECL Image32
{
private:
@ -235,96 +326,6 @@ namespace mapnik
}
}
struct Multiply
{
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
unsigned &r1, unsigned &g1, unsigned &b1)
{
r1 = r1*r0/255;
g1 = g1*g0/255;
b1 = b1*b0/255;
}
};
struct Multiply2
{
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
unsigned &r1, unsigned &g1, unsigned &b1)
{
r1 = r1*r0/128;
if (r1>255) r1=255;
g1 = g1*g0/128;
if (g1>255) g1=255;
b1 = b1*b0/128;
if (b1>255) b1=255;
}
};
struct Divide
{
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
unsigned &r1, unsigned &g1, unsigned &b1)
{
r1 = r0*256/(r1+1);
g1 = g0*256/(g1+1);
b1 = b0*256/(b1+1);
}
};
struct Divide2
{
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
unsigned &r1, unsigned &g1, unsigned &b1)
{
r1 = r0*128/(r1+1);
g1 = g0*128/(g1+1);
b1 = b0*128/(b1+1);
}
};
struct Screen
{
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
unsigned &r1, unsigned &g1, unsigned &b1)
{
r1 = 255 - (255-r0)*(255-r1)/255;
g1 = 255 - (255-g0)*(255-g1)/255;
b1 = 255 - (255-b0)*(255-b1)/255;
}
};
struct HardLight
{
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
unsigned &r1, unsigned &g1, unsigned &b1)
{
r1 = (r1>128)?255-(255-r0)*(255-2*(r1-128))/256:r0*r1*2/256;
g1 = (g1>128)?255-(255-g0)*(255-2*(g1-128))/256:g0*g1*2/256;
b1 = (b1>128)?255-(255-b0)*(255-2*(b1-128))/256:b0*b1*2/256;
}
};
struct MergeGrain
{
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
unsigned &r1, unsigned &g1, unsigned &b1)
{
r1 = (r1+r0>128)?r1+r0-128:0;
if (r1>255) r1=255;
g1 = (g1+g0>128)?g1+g0-128:0;
if (g1>255) g1=255;
b1 = (b1+b0>128)?b1+b0-128:0;
if (b1>255) b1=255;
}
};
struct MergeGrain2
{
inline static void mergeRGB(unsigned const &r0, unsigned const &g0, unsigned const &b0,
unsigned &r1, unsigned &g1, unsigned &b1)
{
r1 = (2*r1+r0>256)?2*r1+r0-256:0;
if (r1>255) r1=255;
g1 = (2*g1+g0>256)?2*g1+g0-256:0;
if (g1>255) g1=255;
b1 = (2*b1+b0>256)?2*b1+b0-256:0;
if (b1>255) b1=255;
}
};
template <typename MergeMethod>
inline void merge_rectangle(ImageData32 const& data, unsigned x0, unsigned y0, float opacity)
{

View file

@ -687,21 +687,21 @@ namespace mapnik
pixmap_.set_rectangle_alpha2(target,int(ext.minx()),int(ext.miny()), sym.get_opacity());
}
} else if (sym.get_mode() == "grain_merge"){
pixmap_.template merge_rectangle<Image32::MergeGrain> (target,int(ext.minx()),int(ext.miny()), sym.get_opacity());
pixmap_.template merge_rectangle<MergeGrain> (target,int(ext.minx()),int(ext.miny()), sym.get_opacity());
} else if (sym.get_mode() == "grain_merge2"){
pixmap_.template merge_rectangle<Image32::MergeGrain2> (target,int(ext.minx()),int(ext.miny()), sym.get_opacity());
pixmap_.template merge_rectangle<MergeGrain2> (target,int(ext.minx()),int(ext.miny()), sym.get_opacity());
} else if (sym.get_mode() == "multiply"){
pixmap_.template merge_rectangle<Image32::Multiply> (target,int(ext.minx()),int(ext.miny()), sym.get_opacity());
pixmap_.template merge_rectangle<Multiply> (target,int(ext.minx()),int(ext.miny()), sym.get_opacity());
} else if (sym.get_mode() == "multiply2"){
pixmap_.template merge_rectangle<Image32::Multiply2> (target,int(ext.minx()),int(ext.miny()), sym.get_opacity());
pixmap_.template merge_rectangle<Multiply2> (target,int(ext.minx()),int(ext.miny()), sym.get_opacity());
} else if (sym.get_mode() == "divide"){
pixmap_.template merge_rectangle<Image32::Divide> (target,int(ext.minx()),int(ext.miny()), sym.get_opacity());
pixmap_.template merge_rectangle<Divide> (target,int(ext.minx()),int(ext.miny()), sym.get_opacity());
} else if (sym.get_mode() == "divide2"){
pixmap_.template merge_rectangle<Image32::Divide2> (target,int(ext.minx()),int(ext.miny()), sym.get_opacity());
pixmap_.template merge_rectangle<Divide2> (target,int(ext.minx()),int(ext.miny()), sym.get_opacity());
} else if (sym.get_mode() == "screen"){
pixmap_.template merge_rectangle<Image32::Screen> (target,int(ext.minx()),int(ext.miny()), sym.get_opacity());
pixmap_.template merge_rectangle<Screen> (target,int(ext.minx()),int(ext.miny()), sym.get_opacity());
} else if (sym.get_mode() == "hard_light"){
pixmap_.template merge_rectangle<Image32::HardLight> (target,int(ext.minx()),int(ext.miny()), sym.get_opacity());
pixmap_.template merge_rectangle<HardLight> (target,int(ext.minx()),int(ext.miny()), sym.get_opacity());
} else {
if (sym.get_opacity() == 1.0){
pixmap_.set_rectangle(int(ext.minx()),int(ext.miny()),target);