+ text rendering work-in-progress
This commit is contained in:
parent
acc14b9cc0
commit
99ab053558
10 changed files with 154 additions and 67 deletions
|
@ -68,7 +68,6 @@ public:
|
||||||
for (; itr != end; ++itr)
|
for (; itr != end; ++itr)
|
||||||
{
|
{
|
||||||
char_properties const& p = itr->p;
|
char_properties const& p = itr->p;
|
||||||
std::cerr << p.face_name << " : " << p.fontset << std::endl;
|
|
||||||
face_set_ptr faces = font_manager.get_face_set(p.face_name, p.fontset);
|
face_set_ptr faces = font_manager.get_face_set(p.face_name, p.fontset);
|
||||||
if (faces->size() > 0)
|
if (faces->size() > 0)
|
||||||
{
|
{
|
||||||
|
@ -90,19 +89,25 @@ public:
|
||||||
char_properties const& p = itr->p;
|
char_properties const& p = itr->p;
|
||||||
if (p.fontset)
|
if (p.fontset)
|
||||||
{
|
{
|
||||||
for (auto const& face_name : p.fontset->get_face_names())
|
for (auto face_name : p.fontset->get_face_names())
|
||||||
{
|
{
|
||||||
|
face_name.erase(remove_if(face_name.begin(), face_name.end(), ::isspace), face_name.end());
|
||||||
|
size_t pos = face_name.rfind("-");
|
||||||
|
if (pos != std::string::npos)
|
||||||
|
{
|
||||||
|
face_name = face_name.substr(0,pos);
|
||||||
|
}
|
||||||
std::cerr << face_name << std::endl;
|
std::cerr << face_name << std::endl;
|
||||||
|
manager.test(face_name, itr->str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StringCharacterIterator iter(itr->str);
|
StringCharacterIterator iter(itr->str);
|
||||||
for (iter.setToStart(); iter.hasNext();)
|
for (iter.setToStart(); iter.hasNext();)
|
||||||
{
|
{
|
||||||
UChar ch = iter.nextPostInc();
|
UChar ch = iter.nextPostInc();
|
||||||
char_info char_dim(ch, 10, 12, 0, 12);
|
char_info char_dim(ch, p.text_size * scale_factor_, p.text_size * scale_factor_, 0, p.text_size * scale_factor_);
|
||||||
char_dim.format = &(itr->p);
|
char_dim.format = &(itr->p);
|
||||||
char_dim.avg_height = 12;//avg_height;
|
char_dim.avg_height = p.text_size * scale_factor_;
|
||||||
info_.add_info(char_dim);
|
info_.add_info(char_dim);
|
||||||
}
|
}
|
||||||
// char sizes ---> p.text_size * scale_factor_
|
// char sizes ---> p.text_size * scale_factor_
|
||||||
|
@ -112,7 +117,7 @@ public:
|
||||||
return info_;
|
return info_;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
//string_info const& get_string_info();
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
expression_list expr_list_;
|
expression_list expr_list_;
|
||||||
|
|
|
@ -27,16 +27,23 @@
|
||||||
#define MAPNIK_SKIA_FONT_MANAGER_HPP
|
#define MAPNIK_SKIA_FONT_MANAGER_HPP
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <mapnik/unicode.hpp>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class skia_typeface_cache;
|
||||||
|
|
||||||
class skia_font_manager
|
class skia_font_manager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
void test() const
|
|
||||||
{
|
skia_font_manager(skia_typeface_cache & cache)
|
||||||
std::cerr << "skia_font_manager" << std::endl;
|
: cache_(cache) {}
|
||||||
}
|
|
||||||
|
void test(std::string const&, UnicodeString & ustr);
|
||||||
|
private:
|
||||||
|
skia_typeface_cache & cache_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,9 @@
|
||||||
#include <mapnik/rule.hpp>
|
#include <mapnik/rule.hpp>
|
||||||
#include <mapnik/feature_style_processor.hpp>
|
#include <mapnik/feature_style_processor.hpp>
|
||||||
#include <mapnik/skia/skia_font_manager.hpp>
|
#include <mapnik/skia/skia_font_manager.hpp>
|
||||||
|
#include <mapnik/skia/skia_typeface_cache.hpp>
|
||||||
#include <mapnik/label_collision_detector.hpp>
|
#include <mapnik/label_collision_detector.hpp>
|
||||||
|
|
||||||
// skia fwd decl
|
// skia fwd decl
|
||||||
class SkCanvas;
|
class SkCanvas;
|
||||||
|
|
||||||
|
@ -91,6 +93,7 @@ private:
|
||||||
double scale_factor_;
|
double scale_factor_;
|
||||||
box2d<double> query_extent_;
|
box2d<double> query_extent_;
|
||||||
skia_font_manager font_manager_;
|
skia_font_manager font_manager_;
|
||||||
|
skia_typeface_cache typeface_cache_;
|
||||||
boost::shared_ptr<label_collision_detector4> detector_;
|
boost::shared_ptr<label_collision_detector4> detector_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,11 @@
|
||||||
#ifndef MAPNIK_SKIA_TYPEFACE_CACHE_HPP
|
#ifndef MAPNIK_SKIA_TYPEFACE_CACHE_HPP
|
||||||
#define MAPNIK_SKIA_TYPEFACE_CACHE_HPP
|
#define MAPNIK_SKIA_TYPEFACE_CACHE_HPP
|
||||||
|
|
||||||
#include <iostream>
|
#ifdef MAPNIK_THREADSAFE
|
||||||
|
#include <boost/thread/mutex.hpp>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
|
||||||
class SkTypeface;
|
class SkTypeface;
|
||||||
|
|
||||||
|
@ -36,16 +40,17 @@ namespace mapnik
|
||||||
class skia_typeface_cache
|
class skia_typeface_cache
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
typedef std::map<std::string, SkTypeface*> cache_type;
|
||||||
skia_typeface_cache();
|
skia_typeface_cache();
|
||||||
~skia_typeface_cache();
|
~skia_typeface_cache();
|
||||||
static bool register_font(std::string const& file_name);
|
static bool register_font(std::string const& file_name);
|
||||||
static bool register_fonts(std::string const& dir, bool recurse = false);
|
static bool register_fonts(std::string const& dir, bool recurse = false);
|
||||||
|
SkTypeface * create(std::string const& family_name);
|
||||||
private:
|
private:
|
||||||
#ifdef MAPNIK_THREADSAFE
|
#ifdef MAPNIK_THREADSAFE
|
||||||
static boost::mutex mutex_;
|
static boost::mutex mutex_;
|
||||||
#endif
|
#endif
|
||||||
static std::map<std::string, SkTypeface*> typefaces_;
|
static cache_type typefaces_;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -263,7 +263,7 @@ if env['HAS_SKIA']:
|
||||||
libmapnik_defines.append('-DHAVE_SKIA')
|
libmapnik_defines.append('-DHAVE_SKIA')
|
||||||
source.insert(0,'skia/skia_renderer.cpp')
|
source.insert(0,'skia/skia_renderer.cpp')
|
||||||
source.insert(0,'skia/skia_typeface_cache.cpp')
|
source.insert(0,'skia/skia_typeface_cache.cpp')
|
||||||
|
source.insert(0,'skia/skia_font_manager.cpp')
|
||||||
|
|
||||||
if env['JPEG']:
|
if env['JPEG']:
|
||||||
source += Split(
|
source += Split(
|
||||||
|
|
|
@ -114,7 +114,7 @@ bool freetype_engine::register_font(std::string const& file_name)
|
||||||
// http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_FaceRec
|
// http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_FaceRec
|
||||||
if (face->family_name && face->style_name)
|
if (face->family_name && face->style_name)
|
||||||
{
|
{
|
||||||
std::string name = std::string(face->family_name) + " " + std::string(face->style_name);
|
std::string name = std::string(face->family_name) + "-" + std::string(face->style_name);
|
||||||
// skip fonts with leading . in the name
|
// skip fonts with leading . in the name
|
||||||
if (!boost::algorithm::starts_with(name,"."))
|
if (!boost::algorithm::starts_with(name,"."))
|
||||||
{
|
{
|
||||||
|
@ -217,8 +217,7 @@ std::map<std::string,std::pair<int,std::string> > const& freetype_engine::get_ma
|
||||||
|
|
||||||
face_ptr freetype_engine::create_face(std::string const& family_name)
|
face_ptr freetype_engine::create_face(std::string const& family_name)
|
||||||
{
|
{
|
||||||
std::map<std::string, std::pair<int,std::string> >::const_iterator itr;
|
std::map<std::string, std::pair<int,std::string> >::const_iterator itr = name2file_.find(family_name);
|
||||||
itr = name2file_.find(family_name);
|
|
||||||
if (itr != name2file_.end())
|
if (itr != name2file_.end())
|
||||||
{
|
{
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
|
|
|
@ -51,51 +51,4 @@ void processed_text::clear()
|
||||||
expr_list_.clear();
|
expr_list_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
string_info const& processed_text::get_string_info()
|
|
||||||
{
|
|
||||||
info_.clear(); //if this function is called twice invalid results are returned, so clear string_info first
|
|
||||||
expression_list::iterator itr = expr_list_.begin();
|
|
||||||
expression_list::iterator end = expr_list_.end();
|
|
||||||
for (; itr != end; ++itr)
|
|
||||||
{
|
|
||||||
char_properties const &p = itr->p;
|
|
||||||
face_set_ptr faces = font_manager_.get_face_set(p.face_name, p.fontset);
|
|
||||||
if (faces->size() == 0)
|
|
||||||
{
|
|
||||||
if (p.fontset && !p.fontset->get_name().empty())
|
|
||||||
{
|
|
||||||
if (p.fontset->size())
|
|
||||||
{
|
|
||||||
if (!p.face_name.empty())
|
|
||||||
{
|
|
||||||
throw config_error("Unable to find specified font face '" + p.face_name
|
|
||||||
+ "' in font set: '" + p.fontset->get_name() + "'");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw config_error("No valid font face could be loaded for font set: '" + p.fontset->get_name() + "'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw config_error("Font set '" + p.fontset->get_name() + "' does not contain any Font face-name entries");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!p.face_name.empty())
|
|
||||||
{
|
|
||||||
throw config_error("Unable to find specified font face '" + p.face_name + "'");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw config_error("Both font set and face name are empty!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
faces->set_character_sizes(p.text_size * scale_factor_);
|
|
||||||
faces->get_string_info(info_, itr->str, &(itr->p));
|
|
||||||
info_.add_text(itr->str);
|
|
||||||
}
|
|
||||||
return info_;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
} //ns mapnik
|
} //ns mapnik
|
||||||
|
|
78
src/skia/skia_font_manager.cpp
Normal file
78
src/skia/skia_font_manager.cpp
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* This file is part of Mapnik (c++ mapping toolkit)
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013 Artem Pavlenko
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library 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
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
#include <mapnik/skia/skia_font_manager.hpp>
|
||||||
|
#include <mapnik/skia/skia_typeface_cache.hpp>
|
||||||
|
#include <mapnik/unicode.hpp>
|
||||||
|
|
||||||
|
#include <SkTypeface.h>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace mapnik {
|
||||||
|
|
||||||
|
void skia_font_manager::test(std::string const& family_name, UnicodeString & ustr)
|
||||||
|
{
|
||||||
|
SkTypeface * typeface = cache_.create(family_name);
|
||||||
|
//SkTypeface * typeface = SkTypeface::CreateFromName(family_name.c_str(),SkTypeface::kNormal);
|
||||||
|
if (typeface)
|
||||||
|
{
|
||||||
|
std::cerr << "ustr.length()=" << ustr.length() << std::endl;
|
||||||
|
std::vector<uint16_t> glyph_ids;
|
||||||
|
glyph_ids.resize(ustr.length());
|
||||||
|
std::cerr << (char*)ustr.getTerminatedBuffer() << std::endl;
|
||||||
|
int num_ids = typeface->charsToGlyphs((void*)ustr.getTerminatedBuffer(), SkTypeface::kUTF16_Encoding,
|
||||||
|
&glyph_ids[0], glyph_ids.size());
|
||||||
|
|
||||||
|
std::cerr << "num_ids = " << num_ids << std::endl;
|
||||||
|
std::vector<uint32_t> glyph_32_ids;
|
||||||
|
for (std::size_t i = 0; i < glyph_ids.size() ;++i)
|
||||||
|
{
|
||||||
|
glyph_32_ids.push_back(glyph_ids[i]);
|
||||||
|
}
|
||||||
|
//const uint32_t glyph_id = 0;
|
||||||
|
// SkAdvancedTypefaceMetrics * metrics =
|
||||||
|
// typeface->getAdvancedTypefaceMetrics(SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo, &glyph_32_ids[0], glyph_32_ids.size());
|
||||||
|
|
||||||
|
|
||||||
|
//auto const& advances = metrics->fGlyphWidths->fAdvance;
|
||||||
|
//std::cerr << "count = " << advances.count();
|
||||||
|
//for ( unsigned j=0; j< num_ids; ++j)
|
||||||
|
//{
|
||||||
|
// std::cerr << advances[j] << ",";
|
||||||
|
//}
|
||||||
|
//std::cerr << std::endl;
|
||||||
|
//for (size_t i = 0; i<metrics.fGlyphWidths.
|
||||||
|
//std::cerr << "SkAdvancedTypefaceMetrics: fFontName=" << metrics->fFontName.c_str() << std::endl;
|
||||||
|
//std::cerr << "SkAdvancedTypefaceMetrics: fAscent=" << metrics->fAscent << std::endl;
|
||||||
|
//std::cerr << "SkAdvancedTypefaceMetrics: fCapHeight=" << metrics->fCapHeight << std::endl;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cerr << "FAIL" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -75,7 +75,8 @@ skia_renderer::skia_renderer(Map const& map, SkCanvas & canvas, double scale_fac
|
||||||
height_(map.height()),
|
height_(map.height()),
|
||||||
t_(map.width(), map.height(), map.get_current_extent()),
|
t_(map.width(), map.height(), map.get_current_extent()),
|
||||||
scale_factor_(scale_factor),
|
scale_factor_(scale_factor),
|
||||||
font_manager_(),
|
typeface_cache_(),
|
||||||
|
font_manager_(typeface_cache_),
|
||||||
detector_(boost::make_shared<label_collision_detector4>(
|
detector_(boost::make_shared<label_collision_detector4>(
|
||||||
box2d<double>(-map.buffer_size(), -map.buffer_size(),
|
box2d<double>(-map.buffer_size(), -map.buffer_size(),
|
||||||
map.width() + map.buffer_size(), map.height() + map.buffer_size()))) {}
|
map.width() + map.buffer_size(), map.height() + map.buffer_size()))) {}
|
||||||
|
@ -261,6 +262,31 @@ void skia_renderer::process(text_symbolizer const& sym,
|
||||||
{
|
{
|
||||||
double sx = placements[i].center.x;
|
double sx = placements[i].center.x;
|
||||||
double sy = placements[i].center.y;
|
double sy = placements[i].center.y;
|
||||||
|
|
||||||
|
placements[i].rewind();
|
||||||
|
// halo
|
||||||
|
for (int j = 0; j < placements[i].num_nodes(); ++j)
|
||||||
|
{
|
||||||
|
char_info_ptr c;
|
||||||
|
double x, y, angle;
|
||||||
|
placements[i].vertex(c, x, y, angle);
|
||||||
|
SkPaint paint;
|
||||||
|
paint.setStyle(SkPaint::kStroke_Style);
|
||||||
|
paint.setAntiAlias(true);
|
||||||
|
double text_size = c->format->text_size * scale_factor_;
|
||||||
|
paint.setTextSize((SkScalar)text_size);
|
||||||
|
paint.setStrokeWidth(2.0 * c->format->halo_radius * scale_factor_);
|
||||||
|
paint.setStrokeJoin(SkPaint::kRound_Join);
|
||||||
|
color const& halo_fill = c->format->halo_fill; // !!
|
||||||
|
paint.setARGB(int(halo_fill.alpha() * c->format->text_opacity), halo_fill.red(), halo_fill.green(), halo_fill.blue());
|
||||||
|
SkPoint pt = SkPoint::Make(0,0);
|
||||||
|
canvas_.save();
|
||||||
|
canvas_.translate((SkScalar)(sx + x), (SkScalar)(sy - y));
|
||||||
|
canvas_.rotate(-(SkScalar)180 * (angle/M_PI));
|
||||||
|
canvas_.drawPosText(&(c->c),1, &pt, paint);
|
||||||
|
canvas_.restore();
|
||||||
|
}
|
||||||
|
// text
|
||||||
placements[i].rewind();
|
placements[i].rewind();
|
||||||
|
|
||||||
for (int j = 0; j < placements[i].num_nodes(); ++j)
|
for (int j = 0; j < placements[i].num_nodes(); ++j)
|
||||||
|
@ -274,7 +300,7 @@ void skia_renderer::process(text_symbolizer const& sym,
|
||||||
double text_size = c->format->text_size * scale_factor_;
|
double text_size = c->format->text_size * scale_factor_;
|
||||||
paint.setTextSize((SkScalar)text_size);
|
paint.setTextSize((SkScalar)text_size);
|
||||||
color const& fill = c->format->fill; // !!
|
color const& fill = c->format->fill; // !!
|
||||||
paint.setARGB(int(fill.alpha() * sym.get_text_opacity()), fill.red(), fill.green(), fill.blue());
|
paint.setARGB(int(fill.alpha() * c->format->text_opacity), fill.red(), fill.green(), fill.blue());
|
||||||
SkPoint pt = SkPoint::Make(0,0);
|
SkPoint pt = SkPoint::Make(0,0);
|
||||||
canvas_.save();
|
canvas_.save();
|
||||||
canvas_.translate((SkScalar)(sx + x), (SkScalar)(sy - y));
|
canvas_.translate((SkScalar)(sx + x), (SkScalar)(sy - y));
|
||||||
|
|
|
@ -45,6 +45,17 @@ skia_typeface_cache::~skia_typeface_cache()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SkTypeface * skia_typeface_cache::create(std::string const& family_name)
|
||||||
|
{
|
||||||
|
cache_type::const_iterator itr = typefaces_.find(family_name);
|
||||||
|
if (itr != typefaces_.end())
|
||||||
|
{
|
||||||
|
return itr->second;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool skia_typeface_cache::register_font(std::string const& file_name)
|
bool skia_typeface_cache::register_font(std::string const& file_name)
|
||||||
{
|
{
|
||||||
#ifdef MAPNIK_THREADSAFE
|
#ifdef MAPNIK_THREADSAFE
|
||||||
|
@ -117,6 +128,6 @@ bool skia_typeface_cache::register_fonts(std::string const& dir, bool recurse)
|
||||||
#ifdef MAPNIK_THREADSAFE
|
#ifdef MAPNIK_THREADSAFE
|
||||||
boost::mutex skia_typeface_cache::mutex_;
|
boost::mutex skia_typeface_cache::mutex_;
|
||||||
#endif
|
#endif
|
||||||
std::map<std::string, SkTypeface* > skia_typeface_cache::typefaces_;
|
skia_typeface_cache::cache_type skia_typeface_cache::typefaces_;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue