halo-transform initial impl

This commit is contained in:
artemp 2014-01-17 11:47:18 +00:00
parent 833cfb9827
commit 3628b5f237
6 changed files with 64 additions and 7 deletions

View file

@ -77,6 +77,7 @@ enum class keys : std::uint8_t
markers_multipolicy,
point_placement_type,
colorizer,
halo_transform,
MAX_SYMBOLIZER_KEY
};

View file

@ -28,6 +28,8 @@
#include <mapnik/image_compositing.hpp>
#include <mapnik/symbolizer.hpp>
#include <mapnik/noncopyable.hpp>
// agg
#include <agg_trans_affine.h>
// freetype2
extern "C"
@ -49,8 +51,8 @@ struct glyph_t
: image(image_), properties(properties_) {}
glyph_t( glyph_t && other) noexcept
: image(other.image),
properties(std::move(other.properties))
: image(other.image),
properties(std::move(other.properties))
{
other.image = nullptr;
}
@ -69,6 +71,8 @@ public:
composite_mode_e comp_op = src_over,
double scale_factor=1.0,
stroker_ptr stroker=stroker_ptr());
void set_transform(agg::trans_affine const& transform);
void set_halo_transform(agg::trans_affine const& halo_transform);
protected:
typedef std::vector<glyph_t> glyph_vector;
void prepare_glyphs(glyph_positions const& positions);
@ -77,6 +81,8 @@ protected:
double scale_factor_;
glyph_vector glyphs_;
stroker_ptr stroker_;
agg::trans_affine transform_;
agg::trans_affine halo_transform_;
};
template <typename T>

View file

@ -52,6 +52,13 @@ void agg_renderer<T0,T1>::process(text_symbolizer const& sym,
common_.scale_factor_,
common_.font_manager_.get_stroker());
agg::trans_affine halo_transform;
auto transform = get_optional<transform_type>(sym, keys::halo_transform);
if (transform)
{
evaluate_transform(halo_transform, feature, *transform);
ren.set_halo_transform(halo_transform);
}
placements_list const& placements = helper.get();
for (glyph_positions_ptr glyphs : placements)
{

View file

@ -1210,6 +1210,18 @@ void map_parser::parse_text_symbolizer(rule & rule, xml_node const& sym)
put<text_placements_ptr>(text_symbol, keys::text_placements_, placement_finder);
optional<halo_rasterizer_e> halo_rasterizer_ = sym.get_opt_attr<halo_rasterizer_e>("halo-rasterizer");
if (halo_rasterizer_) put(text_symbol, keys::halo_rasterizer, halo_rasterizer_enum(*halo_rasterizer_));
optional<std::string> halo_transform_wkt = sym.get_opt_attr<std::string>("halo-transform");
if (halo_transform_wkt)
{
mapnik::transform_list_ptr tl = std::make_shared<mapnik::transform_list>();
if (!mapnik::parse_transform(*tl, *halo_transform_wkt, sym.get_tree().transform_expr_grammar))
{
throw mapnik::config_error("Failed to parse halo-transform: '" + *halo_transform_wkt + "'");
}
put(text_symbol, keys::halo_transform, tl);
}
rule.append(std::move(text_symbol));
}
catch (config_error const& ex)

View file

@ -89,7 +89,8 @@ static const property_meta_type key_meta[to_integral(keys::MAX_SYMBOLIZER_KEY)]
[](enumeration_wrapper e) { return enumeration<marker_multi_policy_enum,marker_multi_policy_enum_MAX>(marker_multi_policy_enum(e.value)).as_string();}, property_types::target_double }, // FIXME - better naming ^^
property_meta_type{ "placement", enumeration_wrapper(CENTROID_POINT_PLACEMENT),
[](enumeration_wrapper e) { return enumeration<point_placement_enum,point_placement_enum_MAX>(point_placement_enum(e.value)).as_string();}, property_types::target_double },
property_meta_type{ "raster-colorizer", nullptr, nullptr, property_types::target_colorizer}
property_meta_type{ "raster-colorizer", nullptr, nullptr, property_types::target_colorizer},
property_meta_type{ "halo-transform", false, nullptr, property_types::target_transform },
};
property_meta_type const& get_meta(mapnik::keys key)

View file

@ -36,9 +36,21 @@ text_renderer::text_renderer (halo_rasterizer_e rasterizer, composite_mode_e com
comp_op_(comp_op),
scale_factor_(scale_factor),
glyphs_(),
stroker_(stroker)
stroker_(stroker),
transform_(),
halo_transform_()
{}
void text_renderer::set_transform(agg::trans_affine const& transform)
{
transform_ = transform;
}
void text_renderer::set_halo_transform(agg::trans_affine const& halo_transform)
{
halo_transform_ = halo_transform;
}
void text_renderer::prepare_glyphs(glyph_positions const& positions)
{
FT_Matrix matrix;
@ -109,15 +121,33 @@ void agg_text_renderer<T>::render(glyph_positions const& pos)
prepare_glyphs(pos);
FT_Error error;
FT_Vector start;
FT_Vector start_halo;
int height = pixmap_.height();
pixel_position const& base_point = pos.get_base_point();
start.x = static_cast<FT_Pos>(base_point.x * (1 << 6));
start.y = static_cast<FT_Pos>((height - base_point.y) * (1 << 6));
start_halo = start;
start.x += transform_.tx * 64;
start.y += transform_.ty * 64;
start_halo.x += halo_transform_.tx * 64;
start_halo.y += halo_transform_.ty * 64;
//render halo
double halo_radius = 0;
char_properties_ptr format;
FT_Matrix halo_matrix;
halo_matrix.xx = halo_transform_.sx * 0x10000L;
halo_matrix.xy = halo_transform_.shx * 0x10000L;
halo_matrix.yy = halo_transform_.sy * 0x10000L;
halo_matrix.yx = halo_transform_.shy * 0x10000L;
FT_Matrix matrix;
matrix.xx = transform_.sx * 0x10000L;
matrix.xy = transform_.shx * 0x10000L;
matrix.yy = transform_.sy * 0x10000L;
matrix.yx = transform_.shy * 0x10000L;
for (auto const& glyph : glyphs_)
{
if (glyph.properties)
@ -132,7 +162,7 @@ void agg_text_renderer<T>::render(glyph_positions const& pos)
error = FT_Glyph_Copy(glyph.image, &g);
if (!error)
{
FT_Glyph_Transform(g,0,&start);
FT_Glyph_Transform(g, &halo_matrix, &start_halo);
if (rasterizer_ == HALO_RASTERIZER_FULL)
{
stroker_->init(halo_radius);
@ -176,7 +206,7 @@ void agg_text_renderer<T>::render(glyph_positions const& pos)
{
format = glyph.properties;
}
FT_Glyph_Transform(glyph.image, 0, &start);
FT_Glyph_Transform(glyph.image, &matrix, &start);
error = FT_Glyph_To_Bitmap(&glyph.image ,FT_RENDER_MODE_NORMAL,0,1);
if (!error)
{