mirror of
https://github.com/mapnik/mapnik.git
synced 2026-02-01 17:36:36 +00:00
+ implement compositing for text
+ refactor image_32
This commit is contained in:
parent
36c5e348d0
commit
aad7c5e384
@ -21,6 +21,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
#include <mapnik/map.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/datasource_cache.hpp>
|
||||
#include <mapnik/font_engine_freetype.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
@ -250,11 +251,11 @@ int main ( int argc , char** argv)
|
||||
agg_renderer<image_32> ren(m,buf);
|
||||
ren.apply();
|
||||
|
||||
save_to_file<image_data_32>(buf.data(),"demo.jpg","jpeg");
|
||||
save_to_file<image_data_32>(buf.data(),"demo.png","png");
|
||||
save_to_file<image_data_32>(buf.data(),"demo256.png","png256");
|
||||
save_to_file<image_data_32>(buf.data(),"demo.tif","tiff");
|
||||
|
||||
save_to_file(buf,"demo.jpg","jpeg");
|
||||
save_to_file(buf,"demo.png","png");
|
||||
save_to_file(buf,"demo256.png","png256");
|
||||
save_to_file(buf,"demo.tif","tiff");
|
||||
|
||||
std::cout << "Three maps have been rendered using AGG in the current directory:\n"
|
||||
"- demo.jpg\n"
|
||||
"- demo.png\n"
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/grid/grid_renderer.hpp>
|
||||
#include <mapnik/layer.hpp>
|
||||
#include <mapnik/projection.hpp>
|
||||
|
||||
@ -111,11 +111,8 @@ public:
|
||||
// agg renderer doesn't support processing of multiple symbolizers.
|
||||
return false;
|
||||
};
|
||||
void painted(bool painted)
|
||||
{
|
||||
pixmap_.painted(painted);
|
||||
}
|
||||
|
||||
|
||||
void painted(bool painted);
|
||||
|
||||
private:
|
||||
buffer_type & pixmap_;
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
#include <mapnik/font_set.hpp>
|
||||
#include <mapnik/char_info.hpp>
|
||||
#include <mapnik/pixel_position.hpp>
|
||||
#include <mapnik/image_compositing.hpp>
|
||||
|
||||
// freetype2
|
||||
extern "C"
|
||||
@ -337,7 +338,7 @@ public:
|
||||
{
|
||||
return stroker_;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
font_engine_type & engine_;
|
||||
stroker_ptr stroker_;
|
||||
@ -351,20 +352,21 @@ struct text_renderer : private boost::noncopyable
|
||||
{
|
||||
FT_Glyph image;
|
||||
char_properties *properties;
|
||||
glyph_t(FT_Glyph image_, char_properties *properties_)
|
||||
glyph_t(FT_Glyph image_, char_properties *properties_)
|
||||
: image(image_), properties(properties_) {}
|
||||
~glyph_t () { FT_Done_Glyph(image);}
|
||||
};
|
||||
|
||||
|
||||
typedef boost::ptr_vector<glyph_t> glyphs_t;
|
||||
typedef T pixmap_type;
|
||||
|
||||
text_renderer (pixmap_type & pixmap, face_manager<freetype_engine> &font_manager_, stroker & s);
|
||||
text_renderer (pixmap_type & pixmap, face_manager<freetype_engine> &font_manager_, stroker & s, composite_mode_e comp_op = src_over);
|
||||
box2d<double> prepare_glyphs(text_path *path);
|
||||
void render(pixel_position pos);
|
||||
void render_id(int feature_id, pixel_position pos, double min_radius=1.0);
|
||||
|
||||
private:
|
||||
|
||||
void render_bitmap(FT_Bitmap *bitmap, unsigned rgba, int x, int y, double opacity)
|
||||
{
|
||||
int x_max=x+bitmap->width;
|
||||
@ -408,8 +410,11 @@ private:
|
||||
face_manager<freetype_engine> &font_manager_;
|
||||
stroker & stroker_;
|
||||
glyphs_t glyphs_;
|
||||
composite_mode_e comp_op_;
|
||||
};
|
||||
|
||||
typedef face_manager<freetype_engine> face_manager_freetype;
|
||||
|
||||
}
|
||||
|
||||
#endif // MAPNIK_FONT_ENGINE_FREETYPE_HPP
|
||||
|
||||
@ -223,7 +223,7 @@ public:
|
||||
{
|
||||
unsigned rgba0 = data_(x,y);
|
||||
#ifdef MAPNIK_BIG_ENDIAN
|
||||
unsigned a1 = (int)((rgba1 & 0xff) * opacity) & 0xff; // adjust for desired opacity
|
||||
unsigned a1 = (unsigned)((rgba1 & 0xff) * opacity) & 0xff; // adjust for desired opacity
|
||||
a1 = (t*a1) / 255;
|
||||
if (a1 == 0) return;
|
||||
unsigned r1 = (rgba1 >> 24) & 0xff;
|
||||
@ -243,7 +243,7 @@ public:
|
||||
a0 = a0 >> 8;
|
||||
data_(x,y)= (a0)| (b0 << 8) | (g0 << 16) | (r0 << 24) ;
|
||||
#else
|
||||
unsigned a1 = (int)(((rgba1 >> 24) & 0xff) * opacity) & 0xff; // adjust for desired opacity
|
||||
unsigned a1 = (unsigned)(((rgba1 >> 24) & 0xff) * opacity) & 0xff; // adjust for desired opacity
|
||||
a1 = (t*a1) / 255;
|
||||
if (a1 == 0) return;
|
||||
unsigned r1 = rgba1 & 0xff;
|
||||
@ -265,7 +265,9 @@ public:
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void composite_pixel(unsigned op, int x,int y,unsigned c, unsigned cover, double opacity);
|
||||
|
||||
inline unsigned width() const
|
||||
{
|
||||
return width_;
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
//#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/palette.hpp>
|
||||
|
||||
// boost
|
||||
@ -215,43 +215,29 @@ template <typename Image>
|
||||
void scale_image_bilinear8 (Image& target,const Image& source, double x_off_f=0, double y_off_f=0);
|
||||
|
||||
/////////// save_to_file ////////////////////////////////////////////////
|
||||
class image_32;
|
||||
|
||||
inline MAPNIK_DECL void save_to_file(image_32 const& image,
|
||||
std::string const& file)
|
||||
{
|
||||
save_to_file<image_data_32>(image.data(), file);
|
||||
}
|
||||
MAPNIK_DECL void save_to_file(image_32 const& image,
|
||||
std::string const& file);
|
||||
|
||||
inline MAPNIK_DECL void save_to_file (image_32 const& image,
|
||||
std::string const& file,
|
||||
std::string const& type)
|
||||
{
|
||||
save_to_file<image_data_32>(image.data(), file, type);
|
||||
}
|
||||
MAPNIK_DECL void save_to_file (image_32 const& image,
|
||||
std::string const& file,
|
||||
std::string const& type);
|
||||
|
||||
inline MAPNIK_DECL void save_to_file (image_32 const& image,
|
||||
std::string const& file,
|
||||
std::string const& type,
|
||||
rgba_palette const& palette)
|
||||
{
|
||||
save_to_file<image_data_32>(image.data(), file, type, palette);
|
||||
}
|
||||
MAPNIK_DECL void save_to_file (image_32 const& image,
|
||||
std::string const& file,
|
||||
std::string const& type,
|
||||
rgba_palette const& palette);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
inline MAPNIK_DECL std::string save_to_string(image_32 const& image,
|
||||
std::string const& type)
|
||||
{
|
||||
return save_to_string<image_data_32>(image.data(), type);
|
||||
}
|
||||
MAPNIK_DECL std::string save_to_string(image_32 const& image,
|
||||
std::string const& type);
|
||||
|
||||
inline MAPNIK_DECL std::string save_to_string(image_32 const& image,
|
||||
std::string const& type,
|
||||
rgba_palette const& palette)
|
||||
{
|
||||
return save_to_string<image_data_32>(image.data(), type, palette);
|
||||
}
|
||||
MAPNIK_DECL std::string save_to_string(image_32 const& image,
|
||||
std::string const& type,
|
||||
rgba_palette const& palette);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
#include <mapnik/palette.hpp>
|
||||
#include <mapnik/octree.hpp>
|
||||
#include <mapnik/hextree.hpp>
|
||||
|
||||
#include <mapnik/image_data.hpp>
|
||||
// zlib
|
||||
#include <zlib.h>
|
||||
|
||||
|
||||
@ -24,7 +24,8 @@
|
||||
#define MAPNIK_RASTER_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
struct raster
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
#include <mapnik/agg_helpers.hpp>
|
||||
@ -292,5 +293,11 @@ void agg_renderer<T>::render_marker(pixel_position const& pos, marker const& mar
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void agg_renderer<T>::painted(bool painted)
|
||||
{
|
||||
pixmap_.painted(painted);
|
||||
}
|
||||
|
||||
template class agg_renderer<image_32>;
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
*****************************************************************************/
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
#include <mapnik/segment.hpp>
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include <boost/foreach.hpp>
|
||||
// mapnik
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
#include <mapnik/agg_pattern_source.hpp>
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
// boost
|
||||
#include <boost/foreach.hpp>
|
||||
// mapnik
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/agg_helpers.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
#include <mapnik/expression_evaluator.hpp>
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include <boost/foreach.hpp>
|
||||
// mapnik
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/agg_helpers.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
|
||||
@ -24,6 +24,7 @@
|
||||
#include <boost/foreach.hpp>
|
||||
// mapnik
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/agg_helpers.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
#include <mapnik/polygon_symbolizer.hpp>
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
|
||||
@ -38,9 +38,12 @@ void agg_renderer<T>::process(text_symbolizer const& sym,
|
||||
width_, height_,
|
||||
scale_factor_,
|
||||
t_, font_manager_, *detector_, query_extent_);
|
||||
|
||||
text_renderer<T> ren(*current_buffer_, font_manager_, *(font_manager_.get_stroker()));
|
||||
|
||||
|
||||
composite_mode_e comp_op = src_over;
|
||||
if ( sym.comp_op() ) comp_op = *sym.comp_op();
|
||||
|
||||
text_renderer<T> ren(*current_buffer_, font_manager_, *(font_manager_.get_stroker()), comp_op);
|
||||
|
||||
while (helper.next()) {
|
||||
placements_type &placements = helper.placements();
|
||||
for (unsigned int ii = 0; ii < placements.size(); ++ii)
|
||||
|
||||
@ -315,13 +315,11 @@ void font_face_set::get_string_info(string_info & info, UnicodeString const& ust
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
text_renderer<T>::text_renderer (pixmap_type & pixmap, face_manager<freetype_engine> &font_manager_, stroker & s)
|
||||
text_renderer<T>::text_renderer (pixmap_type & pixmap, face_manager<freetype_engine> &font_manager_, stroker & s, composite_mode_e comp_op)
|
||||
: pixmap_(pixmap),
|
||||
font_manager_(font_manager_),
|
||||
stroker_(s)
|
||||
{
|
||||
|
||||
}
|
||||
stroker_(s),
|
||||
comp_op_(comp_op) {}
|
||||
|
||||
template <typename T>
|
||||
box2d<double> text_renderer<T>::prepare_glyphs(text_path *path)
|
||||
@ -401,6 +399,26 @@ box2d<double> text_renderer<T>::prepare_glyphs(text_path *path)
|
||||
return box2d<double>(bbox.xMin, bbox.yMin, bbox.xMax, bbox.yMax);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void composite_bitmap(T & pixmap, FT_Bitmap *bitmap, unsigned rgba, int x, int y, double opacity, composite_mode_e comp_op)
|
||||
{
|
||||
int x_max=x+bitmap->width;
|
||||
int y_max=y+bitmap->rows;
|
||||
int i,p,j,q;
|
||||
|
||||
for (i=x,p=0;i<x_max;++i,++p)
|
||||
{
|
||||
for (j=y,q=0;j<y_max;++j,++q)
|
||||
{
|
||||
unsigned gray=bitmap->buffer[q*bitmap->width+p];
|
||||
if (gray)
|
||||
{
|
||||
pixmap.composite_pixel(comp_op, i, j, rgba, gray, opacity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void text_renderer<T>::render(pixel_position pos)
|
||||
{
|
||||
@ -430,9 +448,12 @@ void text_renderer<T>::render(pixel_position pos)
|
||||
{
|
||||
|
||||
FT_BitmapGlyph bit = (FT_BitmapGlyph)g;
|
||||
render_bitmap(&bit->bitmap, itr->properties->halo_fill.rgba(),
|
||||
bit->left,
|
||||
height - bit->top, itr->properties->text_opacity);
|
||||
composite_bitmap(pixmap_, &bit->bitmap, itr->properties->halo_fill.rgba(),
|
||||
bit->left,
|
||||
height - bit->top,
|
||||
itr->properties->text_opacity,
|
||||
comp_op_
|
||||
);
|
||||
}
|
||||
}
|
||||
FT_Done_Glyph(g);
|
||||
@ -448,9 +469,16 @@ void text_renderer<T>::render(pixel_position pos)
|
||||
{
|
||||
|
||||
FT_BitmapGlyph bit = (FT_BitmapGlyph)itr->image;
|
||||
render_bitmap(&bit->bitmap, itr->properties->fill.rgba(),
|
||||
bit->left,
|
||||
height - bit->top, itr->properties->text_opacity);
|
||||
//render_bitmap(&bit->bitmap, itr->properties->fill.rgba(),
|
||||
// bit->left,
|
||||
// height - bit->top, itr->properties->text_opacity);
|
||||
|
||||
composite_bitmap(pixmap_, &bit->bitmap, itr->properties->fill.rgba(),
|
||||
bit->left,
|
||||
height - bit->top,
|
||||
itr->properties->text_opacity,
|
||||
comp_op_
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -497,10 +525,10 @@ boost::mutex freetype_engine::mutex_;
|
||||
#endif
|
||||
std::map<std::string,std::pair<int,std::string> > freetype_engine::name2file_;
|
||||
template void text_renderer<image_32>::render(pixel_position);
|
||||
template text_renderer<image_32>::text_renderer(image_32&, face_manager<freetype_engine>&, stroker&);
|
||||
template text_renderer<image_32>::text_renderer(image_32&, face_manager<freetype_engine>&, stroker&, composite_mode_e);
|
||||
template box2d<double>text_renderer<image_32>::prepare_glyphs(text_path*);
|
||||
|
||||
template void text_renderer<grid>::render_id(int, pixel_position, double);
|
||||
template text_renderer<grid>::text_renderer(grid&, face_manager<freetype_engine>&, stroker&);
|
||||
template void text_renderer<grid>::render_id(int, pixel_position, double );
|
||||
template text_renderer<grid>::text_renderer(grid&, face_manager<freetype_engine>&, stroker&, composite_mode_e);
|
||||
template box2d<double>text_renderer<grid>::prepare_glyphs(text_path*);
|
||||
}
|
||||
|
||||
@ -26,7 +26,8 @@
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/color.hpp>
|
||||
|
||||
// agg
|
||||
#include "agg_pixfmt_rgba.h"
|
||||
// cairo
|
||||
#ifdef HAVE_CAIRO
|
||||
#include <cairomm/surface.h>
|
||||
@ -190,4 +191,23 @@ boost::optional<color> const& image_32::get_background() const
|
||||
return background_;
|
||||
}
|
||||
|
||||
void image_32::composite_pixel(unsigned op, int x,int y, unsigned c, unsigned cover, double opacity)
|
||||
{
|
||||
typedef agg::rgba8 color_type;
|
||||
typedef color_type::value_type value_type;
|
||||
typedef agg::order_rgba order_type;
|
||||
typedef agg::comp_op_adaptor_rgba<color_type,order_type> blender_type;
|
||||
|
||||
if (checkBounds(x,y))
|
||||
{
|
||||
unsigned rgba = data_(x,y);
|
||||
unsigned ca = (unsigned)(((c >> 24) & 0xff) * opacity);
|
||||
unsigned cb = (c >> 16 ) & 0xff;
|
||||
unsigned cg = (c >> 8) & 0xff;
|
||||
unsigned cr = (c & 0xff);
|
||||
blender_type::blend_pix(op, (value_type*)&rgba, cr, cg, cb, ca, cover);
|
||||
data_(x,y) = rgba;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -73,6 +73,7 @@ extern "C"
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
|
||||
template <typename T>
|
||||
std::string save_to_string(T const& image,
|
||||
std::string const& type,
|
||||
@ -774,6 +775,40 @@ void scale_image_agg (Image& target,const Image& source, scaling_method_e scalin
|
||||
agg::render_scanlines_aa(ras, sl, rb_dst, sa, sg);
|
||||
}
|
||||
|
||||
|
||||
void save_to_file(image_32 const& image,std::string const& file)
|
||||
{
|
||||
save_to_file<image_data_32>(image.data(), file);
|
||||
}
|
||||
|
||||
void save_to_file (image_32 const& image,
|
||||
std::string const& file,
|
||||
std::string const& type)
|
||||
{
|
||||
save_to_file<image_data_32>(image.data(), file, type);
|
||||
}
|
||||
|
||||
void save_to_file (image_32 const& image,
|
||||
std::string const& file,
|
||||
std::string const& type,
|
||||
rgba_palette const& palette)
|
||||
{
|
||||
save_to_file<image_data_32>(image.data(), file, type, palette);
|
||||
}
|
||||
|
||||
std::string save_to_string(image_32 const& image,
|
||||
std::string const& type)
|
||||
{
|
||||
return save_to_string<image_data_32>(image.data(), type);
|
||||
}
|
||||
|
||||
std::string save_to_string(image_32 const& image,
|
||||
std::string const& type,
|
||||
rgba_palette const& palette)
|
||||
{
|
||||
return save_to_string<image_data_32>(image.data(), type, palette);
|
||||
}
|
||||
|
||||
template void scale_image_agg<image_data_32> (image_data_32& target,const image_data_32& source, scaling_method_e scaling_method, double scale_factor, double x_off_f, double y_off_f, double filter_radius, double ratio);
|
||||
|
||||
template void scale_image_bilinear_old<image_data_32> (image_data_32& target,const image_data_32& source, double x_off_f, double y_off_f);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user