From 17efe0601ba8a50aa310b6e6b8133ff47e6fae22 Mon Sep 17 00:00:00 2001 From: Hermann Kraus Date: Sun, 8 Jul 2012 17:19:08 +0200 Subject: [PATCH] Make sure everything compiles again after font engine changes. --- bindings/python/mapnik_font_engine.cpp | 1 + include/mapnik/agg_renderer.hpp | 1 + include/mapnik/cairo_renderer.hpp | 2 +- include/mapnik/grid/grid_renderer.hpp | 1 + include/mapnik/text/placement_finder_ng.hpp | 6 +- include/mapnik/text/renderer.hpp | 42 +++ src/agg/process_shield_symbolizer.cpp | 10 +- src/agg/process_text_symbolizer.cpp | 1 + src/build.py | 1 + src/font_engine_freetype.cpp | 1 - src/grid/process_shield_symbolizer.cpp | 4 + src/grid/process_text_symbolizer.cpp | 4 + src/text/placement_finder_ng.cpp | 9 +- src/text/renderer.cpp | 273 ++++++++++++++++++++ 14 files changed, 341 insertions(+), 15 deletions(-) create mode 100644 include/mapnik/text/renderer.hpp create mode 100644 src/text/renderer.cpp diff --git a/bindings/python/mapnik_font_engine.cpp b/bindings/python/mapnik_font_engine.cpp index 5f4160756..a94bb1835 100644 --- a/bindings/python/mapnik_font_engine.cpp +++ b/bindings/python/mapnik_font_engine.cpp @@ -22,6 +22,7 @@ #include #include +#include void export_font_engine() { diff --git a/include/mapnik/agg_renderer.hpp b/include/mapnik/agg_renderer.hpp index 71401b8de..de32ff8e0 100644 --- a/include/mapnik/agg_renderer.hpp +++ b/include/mapnik/agg_renderer.hpp @@ -29,6 +29,7 @@ #include #include #include +#include // boost #include diff --git a/include/mapnik/cairo_renderer.hpp b/include/mapnik/cairo_renderer.hpp index a5fa5d8a2..e3071a641 100644 --- a/include/mapnik/cairo_renderer.hpp +++ b/include/mapnik/cairo_renderer.hpp @@ -31,7 +31,7 @@ #include #include #include -//#include +#include // cairo #include diff --git a/include/mapnik/grid/grid_renderer.hpp b/include/mapnik/grid/grid_renderer.hpp index fe4c65a15..e4bab58bc 100644 --- a/include/mapnik/grid/grid_renderer.hpp +++ b/include/mapnik/grid/grid_renderer.hpp @@ -31,6 +31,7 @@ #include //#include #include +#include // boost #include diff --git a/include/mapnik/text/placement_finder_ng.hpp b/include/mapnik/text/placement_finder_ng.hpp index f958eaff7..ed16b842e 100644 --- a/include/mapnik/text/placement_finder_ng.hpp +++ b/include/mapnik/text/placement_finder_ng.hpp @@ -24,6 +24,7 @@ //mapnik #include +#include //stl #include @@ -48,10 +49,9 @@ class glyph_positions { public: glyph_positions(text_layout_ptr layout); - void point_placement(double x, double y); + void point_placement(pixel_position base_point); private: - double x_; - double y_; + pixel_position base_point_; bool point_; text_layout_ptr layout_; }; diff --git a/include/mapnik/text/renderer.hpp b/include/mapnik/text/renderer.hpp new file mode 100644 index 000000000..18c1e31bb --- /dev/null +++ b/include/mapnik/text/renderer.hpp @@ -0,0 +1,42 @@ +#ifndef MAPNIK_TEXT_RENDERER_HPP +#define MAPNIK_TEXT_RENDERER_HPP + +//mapnik +#include +#include +#include + +//boost +#include + + +// freetype2 +extern "C" +{ +#include +#include FT_FREETYPE_H +#include FT_GLYPH_H +#include FT_STROKER_H +} + +namespace mapnik +{ +template +struct text_renderer : private boost::noncopyable +{ typedef T pixmap_type; + + text_renderer (pixmap_type & pixmap, face_manager &font_manager_, stroker & s, composite_mode_e comp_op = src_over); + void render(glyph_positions_ptr 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); + void render_bitmap_id(FT_Bitmap *bitmap,int feature_id,int x,int y); + + pixmap_type & pixmap_; + face_manager &font_manager_; + stroker & stroker_; + composite_mode_e comp_op_; +}; +} +#endif // RENDERER_HPP diff --git a/src/agg/process_shield_symbolizer.cpp b/src/agg/process_shield_symbolizer.cpp index e65b5a0ee..cb4cb4a71 100644 --- a/src/agg/process_shield_symbolizer.cpp +++ b/src/agg/process_shield_symbolizer.cpp @@ -22,12 +22,8 @@ // mapnik #include -#include -#include -#include -#include -#include #include +#include // boost #include @@ -39,6 +35,7 @@ void agg_renderer::process(shield_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { +#if 0 shield_symbolizer_helper, label_collision_detector4> helper( sym, feature, prj_trans, @@ -69,6 +66,9 @@ void agg_renderer::process(shield_symbolizer const& sym, ren.render(placements[ii].center); } } +#else +#warning AGG: ShieldSymbolizer disabled! +#endif } diff --git a/src/agg/process_text_symbolizer.cpp b/src/agg/process_text_symbolizer.cpp index c087fb734..867c2ff54 100644 --- a/src/agg/process_text_symbolizer.cpp +++ b/src/agg/process_text_symbolizer.cpp @@ -24,6 +24,7 @@ #include #include #include +#include namespace mapnik { diff --git a/src/build.py b/src/build.py index b9bf0c8fa..1037a1d39 100644 --- a/src/build.py +++ b/src/build.py @@ -186,6 +186,7 @@ source = Split( text/scrptrun.cpp text/face.cpp text/placement_finder_ng.cpp + text/renderer.cpp """ ) diff --git a/src/font_engine_freetype.cpp b/src/font_engine_freetype.cpp index 36298459c..44617f8c1 100644 --- a/src/font_engine_freetype.cpp +++ b/src/font_engine_freetype.cpp @@ -23,7 +23,6 @@ // mapnik #include #include -//#include // boost #include diff --git a/src/grid/process_shield_symbolizer.cpp b/src/grid/process_shield_symbolizer.cpp index e91bb8939..96d166a2a 100644 --- a/src/grid/process_shield_symbolizer.cpp +++ b/src/grid/process_shield_symbolizer.cpp @@ -41,6 +41,7 @@ void grid_renderer::process(shield_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { +#if 0 box2d query_extent; shield_symbolizer_helper, label_collision_detector4> helper( @@ -69,6 +70,9 @@ void grid_renderer::process(shield_symbolizer const& sym, } if (placement_found) pixmap_.add_feature(feature); +#else +#warning GRID: ShieldSymbolizer disabled! +#endif } template void grid_renderer::process(shield_symbolizer const&, diff --git a/src/grid/process_text_symbolizer.cpp b/src/grid/process_text_symbolizer.cpp index 039b41a51..0c67ea089 100644 --- a/src/grid/process_text_symbolizer.cpp +++ b/src/grid/process_text_symbolizer.cpp @@ -31,6 +31,7 @@ void grid_renderer::process(text_symbolizer const& sym, mapnik::feature_impl & feature, proj_transform const& prj_trans) { +#if 0 box2d query_extent; text_symbolizer_helper, label_collision_detector4> helper( @@ -52,6 +53,9 @@ void grid_renderer::process(text_symbolizer const& sym, } } if (placement_found) pixmap_.add_feature(feature); +#else +#warning GRID: TextSymbolizer disabled! +#endif } diff --git a/src/text/placement_finder_ng.cpp b/src/text/placement_finder_ng.cpp index b0afc919a..1c2aaf593 100644 --- a/src/text/placement_finder_ng.cpp +++ b/src/text/placement_finder_ng.cpp @@ -36,22 +36,21 @@ placement_finder_ng::placement_finder_ng( Feature const& feature, DetectorType & glyph_positions_ptr placement_finder_ng::find_point_placement(text_layout_ptr layout, double pos_x, double pos_y, double angle) { glyph_positions_ptr glyphs = boost::make_shared(layout); - glyphs->point_placement(pos_x, pos_y); + glyphs->point_placement(pixel_position(pos_x, pos_y)); //TODO: angle //TODO: Check for placement return glyphs; } glyph_positions::glyph_positions(text_layout_ptr layout) - : x_(0), y_(0), point_(true), layout_(layout) + : base_point_(), point_(true), layout_(layout) { } -void glyph_positions::point_placement(double x, double y) +void glyph_positions::point_placement(pixel_position base_point) { - x_ = x; - y_ = y; + base_point_ = base_point; point_ = true; } diff --git a/src/text/renderer.cpp b/src/text/renderer.cpp new file mode 100644 index 000000000..a3a9e5e63 --- /dev/null +++ b/src/text/renderer.cpp @@ -0,0 +1,273 @@ +#include +#include +#include + +namespace mapnik +{ + +template +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), + comp_op_(comp_op) {} + +#if 0 +template +box2d text_renderer::prepare_glyphs(text_path *path) +{ + //clear glyphs + glyphs_.clear(); + + FT_Matrix matrix; + FT_Vector pen; + FT_Error error; + + FT_BBox bbox; + bbox.xMin = bbox.yMin = 32000; // Initialize these so we can tell if we + bbox.xMax = bbox.yMax = -32000; // properly grew the bbox later + + for (int i = 0; i < path->num_nodes(); i++) + { + char_info_ptr c; + double x, y, angle; + + path->vertex(&c, &x, &y, &angle); + + // TODO Enable when we have support for setting verbosity + // MAPNIK_LOG_DEBUG(font_engine_freetype) << "text_renderer: prepare_glyphs=" + // << c << "," << x << "," << y << "," << angle; + + FT_BBox glyph_bbox; + FT_Glyph image; + + pen.x = int(x * 64); + pen.y = int(y * 64); + + face_set_ptr faces = font_manager_.get_face_set(c->format->face_name, c->format->fontset); + faces->set_character_sizes(c->format->text_size); + + glyph_ptr glyph = faces->get_glyph(unsigned(c->c)); + FT_Face face = glyph->get_face()->get_face(); + + matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L ); + matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L ); + matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L ); + matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L ); + + FT_Set_Transform(face, &matrix, &pen); + + error = FT_Load_Glyph(face, glyph->get_index(), FT_LOAD_NO_HINTING); + if ( error ) + continue; + + error = FT_Get_Glyph(face->glyph, &image); + if ( error ) + continue; + + FT_Glyph_Get_CBox(image,ft_glyph_bbox_pixels, &glyph_bbox); + if (glyph_bbox.xMin < bbox.xMin) + bbox.xMin = glyph_bbox.xMin; + if (glyph_bbox.yMin < bbox.yMin) + bbox.yMin = glyph_bbox.yMin; + if (glyph_bbox.xMax > bbox.xMax) + bbox.xMax = glyph_bbox.xMax; + if (glyph_bbox.yMax > bbox.yMax) + bbox.yMax = glyph_bbox.yMax; + + // Check if we properly grew the bbox + if ( bbox.xMin > bbox.xMax ) + { + bbox.xMin = 0; + bbox.yMin = 0; + bbox.xMax = 0; + bbox.yMax = 0; + } + + // take ownership of the glyph + glyphs_.push_back(new glyph_t(image, c->format)); + } + + return box2d(bbox.xMin, bbox.yMin, bbox.xMax, bbox.yMax); +} +#endif + +template +void composite_bitmap(T & pixmap, FT_Bitmap *bitmap, unsigned rgba, int x, int y, double opacity, composite_mode_e comp_op) +{ +#if 0 + 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); + } + } + } +#endif +} + +template +void text_renderer::render(glyph_positions_ptr pos) +{ +#if 0 + FT_Error error; + FT_Vector start; + unsigned height = pixmap_.height(); + + start.x = static_cast(pos.x * (1 << 6)); + start.y = static_cast((height - pos.y) * (1 << 6)); + + // now render transformed glyphs + typename glyphs_t::iterator itr; + for (itr = glyphs_.begin(); itr != glyphs_.end(); ++itr) + { + double halo_radius = itr->properties->halo_radius; + //make sure we've got reasonable values. + if (halo_radius <= 0.0 || halo_radius > 1024.0) continue; + stroker_.init(halo_radius); + FT_Glyph g; + error = FT_Glyph_Copy(itr->image, &g); + if (!error) + { + FT_Glyph_Transform(g,0,&start); + FT_Glyph_Stroke(&g,stroker_.get(),1); + error = FT_Glyph_To_Bitmap( &g,FT_RENDER_MODE_NORMAL,0,1); + if ( ! error ) + { + + FT_BitmapGlyph bit = (FT_BitmapGlyph)g; + 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); + } + //render actual text + for (itr = glyphs_.begin(); itr != glyphs_.end(); ++itr) + { + + FT_Glyph_Transform(itr->image,0,&start); + + error = FT_Glyph_To_Bitmap( &(itr->image),FT_RENDER_MODE_NORMAL,0,1); + if ( ! error ) + { + + FT_BitmapGlyph bit = (FT_BitmapGlyph)itr->image; + //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_ + ); + } + } +#endif +} + + +template +void text_renderer::render_id(int feature_id, pixel_position pos, double min_radius) +{ +#if 0 + FT_Error error; + FT_Vector start; + unsigned height = pixmap_.height(); + + start.x = static_cast(pos.x * (1 << 6)); + start.y = static_cast((height - pos.y) * (1 << 6)); + + // now render transformed glyphs + typename glyphs_t::iterator itr; + for (itr = glyphs_.begin(); itr != glyphs_.end(); ++itr) + { + stroker_.init(std::max(itr->properties->halo_radius, min_radius)); + FT_Glyph g; + error = FT_Glyph_Copy(itr->image, &g); + if (!error) + { + FT_Glyph_Transform(g,0,&start); + FT_Glyph_Stroke(&g,stroker_.get(),1); + error = FT_Glyph_To_Bitmap( &g,FT_RENDER_MODE_NORMAL,0,1); + //error = FT_Glyph_To_Bitmap( &g,FT_RENDER_MODE_MONO,0,1); + if ( ! error ) + { + + FT_BitmapGlyph bit = (FT_BitmapGlyph)g; + render_bitmap_id(&bit->bitmap, feature_id, + bit->left, + height - bit->top); + } + } + FT_Done_Glyph(g); + } +#endif +} + +template +void text_renderer::render_bitmap_id(FT_Bitmap *bitmap,int feature_id,int x,int y) +{ +#if 0 + 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_.setPixel(i,j,feature_id); + //pixmap_.blendPixel2(i,j,rgba,gray,opacity_); + } + } + } +#endif +} + +template +void text_renderer::render_bitmap(FT_Bitmap *bitmap, unsigned rgba, int x, int y, double opacity) +{ +#if 0 + 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_.blendPixel2(i, j, rgba, gray, opacity); + } + } + } +#endif +} + +template void text_renderer::render(glyph_positions_ptr); +template text_renderer::text_renderer(image_32&, face_manager&, stroker&, composite_mode_e); + +template void text_renderer::render_id(int, pixel_position, double ); +template text_renderer::text_renderer(grid&, face_manager&, stroker&, composite_mode_e); + +}