diff --git a/demo/c++/rundemo.cpp b/demo/c++/rundemo.cpp index eb22729e9..2546bd09e 100644 --- a/demo/c++/rundemo.cpp +++ b/demo/c++/rundemo.cpp @@ -21,6 +21,7 @@ *****************************************************************************/ #include +#include #include #include #include @@ -250,11 +251,11 @@ int main ( int argc , char** argv) agg_renderer ren(m,buf); ren.apply(); - save_to_file(buf.data(),"demo.jpg","jpeg"); - save_to_file(buf.data(),"demo.png","png"); - save_to_file(buf.data(),"demo256.png","png256"); - save_to_file(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" diff --git a/demo/viewer/mapwidget.cpp b/demo/viewer/mapwidget.cpp index 858e9268c..f9b7ae396 100644 --- a/demo/viewer/mapwidget.cpp +++ b/demo/viewer/mapwidget.cpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include diff --git a/include/mapnik/agg_renderer.hpp b/include/mapnik/agg_renderer.hpp index 674f98ff8..d717c252c 100644 --- a/include/mapnik/agg_renderer.hpp +++ b/include/mapnik/agg_renderer.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_; diff --git a/include/mapnik/font_engine_freetype.hpp b/include/mapnik/font_engine_freetype.hpp index 77dc9a4d5..7ca982794 100644 --- a/include/mapnik/font_engine_freetype.hpp +++ b/include/mapnik/font_engine_freetype.hpp @@ -32,6 +32,7 @@ #include #include #include +#include // 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 glyphs_t; typedef T pixmap_type; - text_renderer (pixmap_type & pixmap, face_manager &font_manager_, stroker & s); + text_renderer (pixmap_type & pixmap, face_manager &font_manager_, stroker & s, composite_mode_e comp_op = src_over); box2d 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 &font_manager_; stroker & stroker_; glyphs_t glyphs_; + composite_mode_e comp_op_; }; + typedef face_manager face_manager_freetype; + } #endif // MAPNIK_FONT_ENGINE_FREETYPE_HPP diff --git a/include/mapnik/graphics.hpp b/include/mapnik/graphics.hpp index a9de688c0..0b5ba8ffa 100644 --- a/include/mapnik/graphics.hpp +++ b/include/mapnik/graphics.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_; diff --git a/include/mapnik/image_util.hpp b/include/mapnik/image_util.hpp index 4ff3a08b2..16b0146a5 100644 --- a/include/mapnik/image_util.hpp +++ b/include/mapnik/image_util.hpp @@ -25,7 +25,7 @@ // mapnik #include -#include +//#include #include // boost @@ -215,43 +215,29 @@ template 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(), 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(), 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(), 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(), 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(), type, palette); -} +MAPNIK_DECL std::string save_to_string(image_32 const& image, + std::string const& type, + rgba_palette const& palette); /////////////////////////////////////////////////////////////////////////// diff --git a/include/mapnik/png_io.hpp b/include/mapnik/png_io.hpp index c46f509c2..7bcd3d8f4 100644 --- a/include/mapnik/png_io.hpp +++ b/include/mapnik/png_io.hpp @@ -28,7 +28,7 @@ #include #include #include - +#include // zlib #include diff --git a/include/mapnik/raster.hpp b/include/mapnik/raster.hpp index 4a0757938..d48cf6bd0 100644 --- a/include/mapnik/raster.hpp +++ b/include/mapnik/raster.hpp @@ -24,7 +24,8 @@ #define MAPNIK_RASTER_HPP // mapnik -#include +#include +#include namespace mapnik { struct raster diff --git a/src/agg/agg_renderer.cpp b/src/agg/agg_renderer.cpp index 2c1a19821..460e1adca 100644 --- a/src/agg/agg_renderer.cpp +++ b/src/agg/agg_renderer.cpp @@ -21,6 +21,7 @@ *****************************************************************************/ // mapnik +#include #include #include #include @@ -292,5 +293,11 @@ void agg_renderer::render_marker(pixel_position const& pos, marker const& mar } } +template +void agg_renderer::painted(bool painted) +{ + pixmap_.painted(painted); +} + template class agg_renderer; } diff --git a/src/agg/process_building_symbolizer.cpp b/src/agg/process_building_symbolizer.cpp index 03b23e0eb..05aced20d 100644 --- a/src/agg/process_building_symbolizer.cpp +++ b/src/agg/process_building_symbolizer.cpp @@ -21,6 +21,7 @@ *****************************************************************************/ // mapnik +#include #include #include #include diff --git a/src/agg/process_line_pattern_symbolizer.cpp b/src/agg/process_line_pattern_symbolizer.cpp index 361210686..34348186d 100644 --- a/src/agg/process_line_pattern_symbolizer.cpp +++ b/src/agg/process_line_pattern_symbolizer.cpp @@ -24,6 +24,7 @@ #include // mapnik #include +#include #include #include #include diff --git a/src/agg/process_line_symbolizer.cpp b/src/agg/process_line_symbolizer.cpp index 30a8ff548..d18948a4c 100644 --- a/src/agg/process_line_symbolizer.cpp +++ b/src/agg/process_line_symbolizer.cpp @@ -23,6 +23,7 @@ // boost #include // mapnik +#include #include #include #include diff --git a/src/agg/process_markers_symbolizer.cpp b/src/agg/process_markers_symbolizer.cpp index 581933a2c..cce8ca3b3 100644 --- a/src/agg/process_markers_symbolizer.cpp +++ b/src/agg/process_markers_symbolizer.cpp @@ -22,6 +22,7 @@ // mapnik #include +#include #include #include #include diff --git a/src/agg/process_polygon_pattern_symbolizer.cpp b/src/agg/process_polygon_pattern_symbolizer.cpp index 387939532..11941a239 100644 --- a/src/agg/process_polygon_pattern_symbolizer.cpp +++ b/src/agg/process_polygon_pattern_symbolizer.cpp @@ -24,6 +24,7 @@ #include // mapnik #include +#include #include #include #include diff --git a/src/agg/process_polygon_symbolizer.cpp b/src/agg/process_polygon_symbolizer.cpp index a7d944add..592b2aa3c 100644 --- a/src/agg/process_polygon_symbolizer.cpp +++ b/src/agg/process_polygon_symbolizer.cpp @@ -24,6 +24,7 @@ #include // mapnik #include +#include #include #include #include diff --git a/src/agg/process_raster_symbolizer.cpp b/src/agg/process_raster_symbolizer.cpp index 29c3401bf..8e932a463 100644 --- a/src/agg/process_raster_symbolizer.cpp +++ b/src/agg/process_raster_symbolizer.cpp @@ -22,6 +22,7 @@ // mapnik #include +#include #include #include #include diff --git a/src/agg/process_text_symbolizer.cpp b/src/agg/process_text_symbolizer.cpp index a3c7827e6..72d541003 100644 --- a/src/agg/process_text_symbolizer.cpp +++ b/src/agg/process_text_symbolizer.cpp @@ -38,9 +38,12 @@ void agg_renderer::process(text_symbolizer const& sym, width_, height_, scale_factor_, t_, font_manager_, *detector_, query_extent_); - - text_renderer 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 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) diff --git a/src/font_engine_freetype.cpp b/src/font_engine_freetype.cpp index 403b52b95..4350e8982 100644 --- a/src/font_engine_freetype.cpp +++ b/src/font_engine_freetype.cpp @@ -315,13 +315,11 @@ void font_face_set::get_string_info(string_info & info, UnicodeString const& ust } template -text_renderer::text_renderer (pixmap_type & pixmap, face_manager &font_manager_, stroker & s) +text_renderer::text_renderer (pixmap_type & pixmap, face_manager &font_manager_, stroker & s, composite_mode_e comp_op) : pixmap_(pixmap), font_manager_(font_manager_), - stroker_(s) -{ - -} + stroker_(s), + comp_op_(comp_op) {} template box2d text_renderer::prepare_glyphs(text_path *path) @@ -401,6 +399,26 @@ box2d text_renderer::prepare_glyphs(text_path *path) return box2d(bbox.xMin, bbox.yMin, bbox.xMax, bbox.yMax); } +template +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;ibuffer[q*bitmap->width+p]; + if (gray) + { + pixmap.composite_pixel(comp_op, i, j, rgba, gray, opacity); + } + } + } +} + template void text_renderer::render(pixel_position pos) { @@ -430,9 +448,12 @@ void text_renderer::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::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 > freetype_engine::name2file_; template void text_renderer::render(pixel_position); -template text_renderer::text_renderer(image_32&, face_manager&, stroker&); +template text_renderer::text_renderer(image_32&, face_manager&, stroker&, composite_mode_e); template box2dtext_renderer::prepare_glyphs(text_path*); -template void text_renderer::render_id(int, pixel_position, double); -template text_renderer::text_renderer(grid&, face_manager&, stroker&); +template void text_renderer::render_id(int, pixel_position, double ); +template text_renderer::text_renderer(grid&, face_manager&, stroker&, composite_mode_e); template box2dtext_renderer::prepare_glyphs(text_path*); } diff --git a/src/graphics.cpp b/src/graphics.cpp index 5cb71b8a6..98844ac41 100644 --- a/src/graphics.cpp +++ b/src/graphics.cpp @@ -26,7 +26,8 @@ #include #include #include - +// agg +#include "agg_pixfmt_rgba.h" // cairo #ifdef HAVE_CAIRO #include @@ -190,4 +191,23 @@ boost::optional 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 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; + } +} + } diff --git a/src/image_util.cpp b/src/image_util.cpp index 8a4fd3964..1a0089b7d 100644 --- a/src/image_util.cpp +++ b/src/image_util.cpp @@ -73,6 +73,7 @@ extern "C" namespace mapnik { + template 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(), file); +} + +void save_to_file (image_32 const& image, + std::string const& file, + std::string const& type) +{ + save_to_file(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(), file, type, palette); +} + +std::string save_to_string(image_32 const& image, + std::string const& type) +{ + return save_to_string(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(), type, palette); +} + template void scale_image_agg (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& target,const image_data_32& source, double x_off_f, double y_off_f);