added font_engine impl - work in progress:)
This commit is contained in:
parent
897341e042
commit
bd173527a0
11 changed files with 579 additions and 28 deletions
|
@ -24,8 +24,8 @@ opts = Options()
|
||||||
opts.Add('PREFIX', 'The install path "prefix"', '/usr/local')
|
opts.Add('PREFIX', 'The install path "prefix"', '/usr/local')
|
||||||
opts.Add(PathOption('BOOST_INCLUDES', 'Search path for boost include files', '/usr/include'))
|
opts.Add(PathOption('BOOST_INCLUDES', 'Search path for boost include files', '/usr/include'))
|
||||||
opts.Add(PathOption('BOOST_LIBS', 'Search path for boost library files', '/usr/lib'))
|
opts.Add(PathOption('BOOST_LIBS', 'Search path for boost library files', '/usr/lib'))
|
||||||
opts.Add(PathOption('FREETYPE_INCLUDES', 'Search path for FreeType include files', '/usr/include'))
|
opts.Add(PathOption('FREETYPE_INCLUDES', 'Search path for FreeType include files', '/opt/freetype/include/freetype2'))
|
||||||
opts.Add(PathOption('FREETYPE_LIBS', 'Search path for FreeType library files', '/usr/lib'))
|
opts.Add(PathOption('FREETYPE_LIBS', 'Search path for FreeType library files', '/opt/freetype/lib'))
|
||||||
opts.Add(PathOption('PNG_INCLUDES', 'Search path for libpng include files', '/usr/include'))
|
opts.Add(PathOption('PNG_INCLUDES', 'Search path for libpng include files', '/usr/include'))
|
||||||
opts.Add(PathOption('PNG_LIBS', 'Search path for libpng include files', '/usr/lib'))
|
opts.Add(PathOption('PNG_LIBS', 'Search path for libpng include files', '/usr/lib'))
|
||||||
opts.Add(PathOption('JPEG_INCLUDES', 'Search path for libjpeg include files', '/usr/include'))
|
opts.Add(PathOption('JPEG_INCLUDES', 'Search path for libjpeg include files', '/usr/include'))
|
||||||
|
@ -63,6 +63,7 @@ C_LIBSHEADERS = [
|
||||||
['tiff', 'tiff.h', True],
|
['tiff', 'tiff.h', True],
|
||||||
['z', 'zlib.h', True],
|
['z', 'zlib.h', True],
|
||||||
['jpeg', ['stdio.h','jpeglib.h'], True],
|
['jpeg', ['stdio.h','jpeglib.h'], True],
|
||||||
|
#['freetype', 'ft2build.h', True],
|
||||||
['pq', 'libpq-fe.h', False]
|
['pq', 'libpq-fe.h', False]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
|
|
||||||
#include "feature_style_processor.hpp"
|
#include "feature_style_processor.hpp"
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
|
//#include "agg_font_freetype.h"
|
||||||
|
#include "font_engine_freetype.hpp"
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
@ -31,6 +33,10 @@ namespace mapnik
|
||||||
private boost::noncopyable
|
private boost::noncopyable
|
||||||
{
|
{
|
||||||
agg_renderer(Map const& m, T & pixmap);
|
agg_renderer(Map const& m, T & pixmap);
|
||||||
|
void start_map_processing();
|
||||||
|
void end_map_processing();
|
||||||
|
void start_layer_processing();
|
||||||
|
void end_layer_processing();
|
||||||
void process(point_symbolizer const& sym,Feature const& feature);
|
void process(point_symbolizer const& sym,Feature const& feature);
|
||||||
void process(line_symbolizer const& sym,Feature const& feature);
|
void process(line_symbolizer const& sym,Feature const& feature);
|
||||||
void process(line_pattern_symbolizer const& sym,Feature const& feature);
|
void process(line_pattern_symbolizer const& sym,Feature const& feature);
|
||||||
|
@ -41,6 +47,7 @@ namespace mapnik
|
||||||
private:
|
private:
|
||||||
T & pixmap_;
|
T & pixmap_;
|
||||||
CoordTransform t_;
|
CoordTransform t_;
|
||||||
|
face_manager<freetype_engine> font_manager_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ namespace mapnik
|
||||||
}
|
}
|
||||||
std::string to_string() const
|
std::string to_string() const
|
||||||
{
|
{
|
||||||
return value_.to_string();
|
return value_.to_expression_string();
|
||||||
}
|
}
|
||||||
~literal() {}
|
~literal() {}
|
||||||
private:
|
private:
|
||||||
|
@ -88,8 +88,6 @@ namespace mapnik
|
||||||
property(property const& other)
|
property(property const& other)
|
||||||
: expression<FeatureT>(),
|
: expression<FeatureT>(),
|
||||||
name_(other.name_)
|
name_(other.name_)
|
||||||
//index_(other.index_),
|
|
||||||
//valid_(other.valid_)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
value get_value(FeatureT const& feature) const
|
value get_value(FeatureT const& feature) const
|
||||||
|
@ -108,11 +106,7 @@ namespace mapnik
|
||||||
{
|
{
|
||||||
return name_;
|
return name_;
|
||||||
}
|
}
|
||||||
void set_index(size_t index)
|
|
||||||
{
|
|
||||||
//index_=index;
|
|
||||||
//valid_=true;
|
|
||||||
}
|
|
||||||
std::string to_string() const
|
std::string to_string() const
|
||||||
{
|
{
|
||||||
return "["+name_+"]";
|
return "["+name_+"]";
|
||||||
|
@ -120,8 +114,7 @@ namespace mapnik
|
||||||
~property() {}
|
~property() {}
|
||||||
private:
|
private:
|
||||||
std::string name_;
|
std::string name_;
|
||||||
//size_t index_;
|
|
||||||
//bool valid_;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
395
include/font_engine_freetype.hpp
Normal file
395
include/font_engine_freetype.hpp
Normal file
|
@ -0,0 +1,395 @@
|
||||||
|
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
* Copyright (C) 2005 Artem Pavlenko
|
||||||
|
*
|
||||||
|
* Mapnik is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//$Id$
|
||||||
|
|
||||||
|
#if !defined FONT_ENGINE_FREETYPE_HPP
|
||||||
|
#define FONT_ENGINE_FREETYPE_HPP
|
||||||
|
|
||||||
|
#include <ft2build.h>
|
||||||
|
#include FT_FREETYPE_H
|
||||||
|
#include FT_GLYPH_H
|
||||||
|
|
||||||
|
#include <boost/shared_ptr.hpp>
|
||||||
|
#include <boost/utility.hpp>
|
||||||
|
#include <boost/thread/mutex.hpp>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <color.hpp>
|
||||||
|
#include <utils.hpp>
|
||||||
|
|
||||||
|
namespace mapnik
|
||||||
|
{
|
||||||
|
|
||||||
|
class font_face : boost::noncopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
font_face(FT_Face face)
|
||||||
|
: face_(face) {}
|
||||||
|
|
||||||
|
std::string family_name() const
|
||||||
|
{
|
||||||
|
return std::string(face_->family_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string style_name() const
|
||||||
|
{
|
||||||
|
return std::string(face_->style_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned num_glyphs() const
|
||||||
|
{
|
||||||
|
return face_->num_glyphs;
|
||||||
|
}
|
||||||
|
|
||||||
|
FT_GlyphSlot glyph() const
|
||||||
|
{
|
||||||
|
return face_->glyph;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
unsigned glyph_index(unsigned charcode) const
|
||||||
|
{
|
||||||
|
return FT_Get_Char_Index(face_, charcode );
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_transform (FT_Matrix * m,FT_Vector *v)
|
||||||
|
{
|
||||||
|
FT_Set_Transform(face_,m,v);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool render_glyph (unsigned charcode) const
|
||||||
|
{
|
||||||
|
unsigned glyph_index = FT_Get_Char_Index(face_, charcode );
|
||||||
|
FT_Error error;
|
||||||
|
error = FT_Load_Glyph(face_,glyph_index,FT_LOAD_DEFAULT);
|
||||||
|
if (error == 0 )
|
||||||
|
{
|
||||||
|
error = FT_Render_Glyph(face_->glyph, FT_RENDER_MODE_NORMAL );
|
||||||
|
if (error == 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
FT_Face get_face() const
|
||||||
|
{
|
||||||
|
return face_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool set_pixel_sizes(unsigned size)
|
||||||
|
{
|
||||||
|
if (! FT_Set_Pixel_Sizes( face_, 0, size ))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
~font_face()
|
||||||
|
{
|
||||||
|
std::cout << "clean up face:" << family_name()<<":" << style_name() << std::endl;
|
||||||
|
FT_Done_Face(face_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
FT_Face face_;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef boost::shared_ptr<font_face> face_ptr;
|
||||||
|
|
||||||
|
class freetype_engine : public mapnik::singleton<freetype_engine,mapnik::CreateStatic>,
|
||||||
|
private boost::noncopyable
|
||||||
|
{
|
||||||
|
friend class mapnik::CreateStatic<freetype_engine>;
|
||||||
|
public:
|
||||||
|
|
||||||
|
static bool register_font(std::string const& file_name)
|
||||||
|
{
|
||||||
|
mutex::scoped_lock lock(mapnik::singleton<freetype_engine,
|
||||||
|
mapnik::CreateStatic>::mutex_);
|
||||||
|
FT_Face face;
|
||||||
|
FT_Error error = FT_New_Face (library_,file_name.c_str(),0,&face);
|
||||||
|
if ( !error )
|
||||||
|
{
|
||||||
|
std::string name = std::string(face->family_name) + " " + std::string(face->style_name);
|
||||||
|
name2file_.insert(std::make_pair(name,file_name));
|
||||||
|
FT_Done_Face(face );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::vector<std::string> face_names ()
|
||||||
|
{
|
||||||
|
std::vector<std::string> names;
|
||||||
|
std::map<std::string,std::string>::const_iterator itr;
|
||||||
|
for (itr = name2file_.begin();itr!=name2file_.end();++itr)
|
||||||
|
{
|
||||||
|
names.push_back(itr->first);
|
||||||
|
}
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
static face_ptr create_face(std::string const& family_name)
|
||||||
|
{
|
||||||
|
mutex::scoped_lock lock(mapnik::singleton<freetype_engine,
|
||||||
|
mapnik::CreateStatic>::mutex_);
|
||||||
|
|
||||||
|
std::map<std::string,std::string>::iterator itr;
|
||||||
|
itr = name2file_.find(family_name);
|
||||||
|
if (itr != name2file_.end())
|
||||||
|
{
|
||||||
|
FT_Face face;
|
||||||
|
FT_Error error = FT_New_Face (library_,itr->second.c_str(),0,&face);
|
||||||
|
|
||||||
|
if (!error)
|
||||||
|
{
|
||||||
|
return face_ptr (new font_face(face));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return face_ptr();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
freetype_engine()
|
||||||
|
{
|
||||||
|
FT_Error error = FT_Init_FreeType( &library_ );
|
||||||
|
if (error)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("can not load FreeType2 library");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
virtual ~freetype_engine()
|
||||||
|
{
|
||||||
|
FT_Done_FreeType(library_);
|
||||||
|
}
|
||||||
|
|
||||||
|
static FT_Library library_;
|
||||||
|
static std::map<std::string,std::string> name2file_;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class face_manager : private boost::noncopyable
|
||||||
|
{
|
||||||
|
typedef T font_engine_type;
|
||||||
|
typedef std::map<std::string,face_ptr> faces;
|
||||||
|
|
||||||
|
public:
|
||||||
|
face_ptr get_face(std::string const& name)
|
||||||
|
{
|
||||||
|
typename faces::iterator itr;
|
||||||
|
itr = faces_.find(name);
|
||||||
|
if (itr != faces_.end())
|
||||||
|
{
|
||||||
|
return itr->second;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
face_ptr face = font_engine_type::instance()->create_face(name);
|
||||||
|
if (face)
|
||||||
|
{
|
||||||
|
faces_.insert(make_pair(name,face));
|
||||||
|
}
|
||||||
|
return face;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
faces faces_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct text_renderer : private boost::noncopyable
|
||||||
|
{
|
||||||
|
typedef T pixmap_type;
|
||||||
|
|
||||||
|
text_renderer (pixmap_type & pixmap, face_ptr face)
|
||||||
|
: pixmap_(pixmap),
|
||||||
|
face_(face),
|
||||||
|
fill_(0,0,0),
|
||||||
|
halo_fill_(255,255,255),
|
||||||
|
halo_radius_(0),
|
||||||
|
angle_(0.0) {}
|
||||||
|
|
||||||
|
void set_pixel_size(unsigned size)
|
||||||
|
{
|
||||||
|
face_->set_pixel_sizes(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_angle(float angle)
|
||||||
|
{
|
||||||
|
angle_=angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_fill(mapnik::Color const& fill)
|
||||||
|
{
|
||||||
|
fill_=fill;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_halo_fill(mapnik::Color const& halo)
|
||||||
|
{
|
||||||
|
halo_fill_=halo;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_halo_radius( int radius=1)
|
||||||
|
{
|
||||||
|
halo_radius_=radius;
|
||||||
|
}
|
||||||
|
|
||||||
|
void render(std::string const& text, double x0, double y0)
|
||||||
|
{
|
||||||
|
FT_Matrix matrix;
|
||||||
|
FT_Vector origin;
|
||||||
|
FT_Vector pen;
|
||||||
|
FT_Error error;
|
||||||
|
FT_Glyph glyph;
|
||||||
|
|
||||||
|
FT_Face face = face_->get_face();
|
||||||
|
FT_GlyphSlot slot = face->glyph;
|
||||||
|
FT_UInt glyph_index;
|
||||||
|
FT_Bool use_kerning;
|
||||||
|
FT_UInt previous;
|
||||||
|
|
||||||
|
unsigned height = pixmap_.height();
|
||||||
|
|
||||||
|
origin.x = 0;
|
||||||
|
origin.y = 0;
|
||||||
|
pen.x = unsigned(x0 * 64);
|
||||||
|
pen.y = unsigned((height - y0) * 64);
|
||||||
|
|
||||||
|
use_kerning = FT_HAS_KERNING(face);
|
||||||
|
|
||||||
|
//unsigned count=1;
|
||||||
|
|
||||||
|
for (std::string::const_iterator i=text.begin();i!=text.end();++i)
|
||||||
|
{
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
glyph_index = FT_Get_Char_Index( face, *i );
|
||||||
|
if ( use_kerning && previous && glyph_index)
|
||||||
|
{
|
||||||
|
FT_Vector delta;
|
||||||
|
FT_Get_Kerning(face,previous,glyph_index,
|
||||||
|
FT_KERNING_DEFAULT,&delta);
|
||||||
|
pen.x += delta.x;
|
||||||
|
pen.y += delta.y;
|
||||||
|
std::cout<< "use kerning "<< std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
error = FT_Load_Glyph (face,glyph_index,FT_LOAD_DEFAULT);
|
||||||
|
if ( error )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
error = FT_Get_Glyph( face->glyph, &glyph );
|
||||||
|
if ( error )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
//FT_Glyph_Transform(glyph,&matrix,&pen);
|
||||||
|
|
||||||
|
error = FT_Glyph_To_Bitmap( &glyph,FT_RENDER_MODE_NORMAL,0,1);
|
||||||
|
if ( error )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
FT_BitmapGlyph bit = (FT_BitmapGlyph)glyph;
|
||||||
|
if (halo_radius_)
|
||||||
|
{
|
||||||
|
render_halo(&bit->bitmap, halo_fill_.rgba(),
|
||||||
|
bit->left,
|
||||||
|
height - bit->top,halo_radius_);
|
||||||
|
}
|
||||||
|
|
||||||
|
render_bitmap(&bit->bitmap, fill_.rgba(),
|
||||||
|
bit->left,
|
||||||
|
height - bit->top);
|
||||||
|
|
||||||
|
FT_Done_Glyph(glyph);
|
||||||
|
pen.x += slot->advance.x;
|
||||||
|
pen.y += slot->advance.y;
|
||||||
|
|
||||||
|
previous = glyph_index;
|
||||||
|
|
||||||
|
//angle_ = sin ( 0.1 * count++);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
|
||||||
|
void render_halo(FT_Bitmap *bitmap,unsigned rgba,int x,int y,int radius)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
int gray = bitmap->buffer[q*bitmap->width+p];
|
||||||
|
if (gray)
|
||||||
|
{
|
||||||
|
for (int n=-halo_radius_; n <=halo_radius_; ++n)
|
||||||
|
for (int m=-halo_radius_;m <= halo_radius_; ++m)
|
||||||
|
pixmap_.blendPixel(i+m,j+n,rgba,gray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void render_bitmap(FT_Bitmap *bitmap,unsigned rgba,int x,int y)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
int gray=bitmap->buffer[q*bitmap->width+p];
|
||||||
|
if (gray)
|
||||||
|
{
|
||||||
|
pixmap_.blendPixel(i,j,rgba,gray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pixmap_type & pixmap_;
|
||||||
|
face_ptr face_;
|
||||||
|
mapnik::Color fill_;
|
||||||
|
mapnik::Color halo_fill_;
|
||||||
|
int halo_radius_;
|
||||||
|
float angle_;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // FONT_ENGINE_FREETYPE_HPP
|
|
@ -95,13 +95,30 @@ namespace mapnik
|
||||||
return 0xff << 24 | r << 16 | g << 8 | b;
|
return 0xff << 24 | r << 16 | g << 8 | b;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void blendPixel(int x,int y,unsigned int rgba,int t)
|
inline void blendPixel(int x,int y,unsigned int rgba1,int t)
|
||||||
{
|
{
|
||||||
if (checkBounds(x,y))
|
if (checkBounds(x,y))
|
||||||
{
|
{
|
||||||
int bg=data_(x,y);
|
unsigned rgba0 = data_(x,y);
|
||||||
int nc=blendColor(rgba,bg,t);
|
unsigned a1 = t;//(rgba1 >> 24) & 0xff;
|
||||||
data_(x,y)=nc;
|
if (a1 == 0) return;
|
||||||
|
unsigned r1 = rgba1 & 0xff;
|
||||||
|
unsigned g1 = (rgba1 >> 8 ) & 0xff;
|
||||||
|
unsigned b1 = (rgba1 >> 16) & 0xff;
|
||||||
|
|
||||||
|
unsigned a0 = (rgba0 >> 24) & 0xff;
|
||||||
|
unsigned r0 = (rgba0 & 0xff) * a0;
|
||||||
|
unsigned g0 = ((rgba0 >> 8 ) & 0xff) * a0;
|
||||||
|
unsigned b0 = ((rgba0 >> 16) & 0xff) * a0;
|
||||||
|
|
||||||
|
|
||||||
|
a0 = ((a1 + a0) << 8) - a0*a1;
|
||||||
|
|
||||||
|
r0 = ((((r1 << 8) - r0) * a1 + (r0 << 8)) / a0);
|
||||||
|
g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
|
||||||
|
b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
|
||||||
|
a0 = a0 >> 8;
|
||||||
|
data_(x,y)= (a0 << 24)| (b0 << 16) | (g0 << 8) | (r0) ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,15 +27,22 @@
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
enum label_placement_e {
|
||||||
|
point_placement=1,
|
||||||
|
line_placement=2
|
||||||
|
};
|
||||||
|
|
||||||
struct text_symbolizer
|
struct text_symbolizer
|
||||||
{
|
{
|
||||||
text_symbolizer(std::string const& name,Color const& fill)
|
text_symbolizer(std::string const& name,Color const& fill)
|
||||||
: name_(name),
|
: name_(name),
|
||||||
fill_(fill) {}
|
fill_(fill),
|
||||||
|
label_p_(point_placement){}
|
||||||
|
|
||||||
text_symbolizer(text_symbolizer const& rhs)
|
text_symbolizer(text_symbolizer const& rhs)
|
||||||
: name_(rhs.name_),
|
: name_(rhs.name_),
|
||||||
fill_(rhs.fill_) {}
|
fill_(rhs.fill_),
|
||||||
|
label_p_(rhs.label_p_) {}
|
||||||
|
|
||||||
~text_symbolizer()
|
~text_symbolizer()
|
||||||
{
|
{
|
||||||
|
@ -45,9 +52,25 @@ namespace mapnik
|
||||||
{
|
{
|
||||||
return name_;
|
return name_;
|
||||||
}
|
}
|
||||||
|
Color const& get_fill() const
|
||||||
|
{
|
||||||
|
return fill_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void set_label_placement(label_placement_e label_p)
|
||||||
|
{
|
||||||
|
label_p_ = label_p;
|
||||||
|
}
|
||||||
|
|
||||||
|
label_placement_e get_label_placement() const
|
||||||
|
{
|
||||||
|
return label_p_;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string name_;
|
std::string name_;
|
||||||
Color fill_;
|
Color fill_;
|
||||||
|
label_placement_e label_p_;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -313,6 +313,21 @@ namespace mapnik {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct to_string : public boost::static_visitor<std::string>
|
struct to_string : public boost::static_visitor<std::string>
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
std::string operator() (T val) const
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << val;
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
std::string const& operator() (std::string const& val) const
|
||||||
|
{
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct to_expression_string : public boost::static_visitor<std::string>
|
||||||
{
|
{
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::string operator() (T val) const
|
std::string operator() (T val) const
|
||||||
|
@ -391,6 +406,11 @@ namespace mapnik {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string to_expression_string() const
|
||||||
|
{
|
||||||
|
return boost::apply_visitor(impl::to_expression_string(),*this);
|
||||||
|
}
|
||||||
|
|
||||||
std::string to_string() const
|
std::string to_string() const
|
||||||
{
|
{
|
||||||
return boost::apply_visitor(impl::to_string(),*this);
|
return boost::apply_visitor(impl::to_string(),*this);
|
||||||
|
|
|
@ -24,6 +24,8 @@ Import('env')
|
||||||
prefix = env['PREFIX']
|
prefix = env['PREFIX']
|
||||||
|
|
||||||
libraries = ['agg'] + env['LIBS']
|
libraries = ['agg'] + env['LIBS']
|
||||||
|
libraries += ['freetype']
|
||||||
|
|
||||||
linkflags = '-Wl,-rpath-link,. -Wl,-soname,libmapnik.so'
|
linkflags = '-Wl,-rpath-link,. -Wl,-soname,libmapnik.so'
|
||||||
|
|
||||||
source = Split(
|
source = Split(
|
||||||
|
@ -47,6 +49,7 @@ source = Split(
|
||||||
point_symbolizer.cpp
|
point_symbolizer.cpp
|
||||||
polygon_pattern_symbolizer.cpp
|
polygon_pattern_symbolizer.cpp
|
||||||
line_pattern_symbolizer.cpp
|
line_pattern_symbolizer.cpp
|
||||||
|
font_engine_freetype.cpp
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
#render.cpp
|
#render.cpp
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
#include "agg_renderer_outline_image.h"
|
#include "agg_renderer_outline_image.h"
|
||||||
|
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
|
@ -89,6 +88,31 @@ namespace mapnik
|
||||||
pixmap_.setBackground(bg);
|
pixmap_.setBackground(bg);
|
||||||
std::cout << "scale="<<m.scale()<<std::endl;
|
std::cout << "scale="<<m.scale()<<std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void agg_renderer<T>::start_map_processing()
|
||||||
|
{
|
||||||
|
std::cout << "start map processing" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void agg_renderer<T>::end_map_processing()
|
||||||
|
{
|
||||||
|
std::cout << "end map processing" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void agg_renderer<T>::start_layer_processing()
|
||||||
|
{
|
||||||
|
std::cout << "start layer processing" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void agg_renderer<T>::end_layer_processing()
|
||||||
|
{
|
||||||
|
std::cout << "end layer processing" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void agg_renderer<T>::process(polygon_symbolizer const& sym,Feature const& feature)
|
void agg_renderer<T>::process(polygon_symbolizer const& sym,Feature const& feature)
|
||||||
{
|
{
|
||||||
|
@ -356,9 +380,50 @@ namespace mapnik
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void agg_renderer<T>::process(text_symbolizer const& sym ,Feature const& feature)
|
void agg_renderer<T>::process(text_symbolizer const& sym ,Feature const& feature)
|
||||||
{
|
{
|
||||||
//TODO - implement text
|
typedef coord_transform<CoordTransform,geometry_type> path_type;
|
||||||
//std::cout << feature << std::endl;
|
geometry_ptr const& geom=feature.get_geometry();
|
||||||
std::cout << sym.get_name() <<":" << feature[sym.get_name()] << std::endl;
|
if (geom)
|
||||||
|
{
|
||||||
|
double angle = 0.0;
|
||||||
|
if (sym.get_label_placement() == line_placement &&
|
||||||
|
geom->num_points() > 1)
|
||||||
|
{
|
||||||
|
|
||||||
|
path_type path(t_,*geom);
|
||||||
|
double x0,y0,x1,y1;
|
||||||
|
path.vertex(&x0,&y0);
|
||||||
|
path.vertex(&x1,&y1);
|
||||||
|
double dx = x1 - x0;
|
||||||
|
double dy = y1 - y0;
|
||||||
|
angle = atan( dx/ dy ) - 0.5 * 3.1459;
|
||||||
|
|
||||||
|
//TODO!!!!!!!!!!!!!!!!!!!!
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string text = feature[sym.get_name()].to_string();
|
||||||
|
if (text.length() > 0)
|
||||||
|
{
|
||||||
|
Color const& fill = sym.get_fill();
|
||||||
|
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
geom->label_position(&x,&y);
|
||||||
|
t_.forward_x(&x);
|
||||||
|
t_.forward_y(&y);
|
||||||
|
|
||||||
|
face_ptr face = font_manager_.get_face("Bitstream Vera Sans Roman");//TODO
|
||||||
|
|
||||||
|
if (face)
|
||||||
|
{
|
||||||
|
text_renderer<mapnik::Image32> ren(pixmap_,face);
|
||||||
|
ren.set_pixel_size(12);
|
||||||
|
ren.set_fill(fill);
|
||||||
|
ren.set_halo_radius(1);
|
||||||
|
ren.set_angle(angle);
|
||||||
|
ren.render(text,x,y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template class agg_renderer<Image32>;
|
template class agg_renderer<Image32>;
|
||||||
|
|
27
src/font_engine_freetype.cpp
Normal file
27
src/font_engine_freetype.cpp
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
* Copyright (C) 2006 Artem Pavlenko
|
||||||
|
*
|
||||||
|
* Mapnik is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//$Id$
|
||||||
|
|
||||||
|
#include "font_engine_freetype.hpp"
|
||||||
|
|
||||||
|
namespace mapnik
|
||||||
|
{
|
||||||
|
FT_Library freetype_engine::library_;
|
||||||
|
std::map<std::string,std::string> freetype_engine::name2file_;
|
||||||
|
}
|
Loading…
Reference in a new issue