freetype_engine - port singleton changes from v3.0.x

This commit is contained in:
artemp 2017-06-01 12:47:18 +02:00
parent aeefd1cb58
commit dfa8f100b2
3 changed files with 102 additions and 58 deletions

View file

@ -2,7 +2,7 @@
* *
* This file is part of Mapnik (c++ mapping toolkit) * This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2015 Artem Pavlenko
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -25,9 +25,10 @@
// mapnik // mapnik
#include <mapnik/config.hpp> #include <mapnik/config.hpp>
#include <mapnik/util/singleton.hpp>
#include <mapnik/util/noncopyable.hpp>
#include <mapnik/font_set.hpp> #include <mapnik/font_set.hpp>
#include <mapnik/text/font_library.hpp> #include <mapnik/text/font_library.hpp>
#include <mapnik/util/noncopyable.hpp>
// stl // stl
#include <memory> #include <memory>
@ -35,10 +36,6 @@
#include <utility> // pair #include <utility> // pair
#include <vector> #include <vector>
#ifdef MAPNIK_THREADSAFE
#include <mutex>
#endif
namespace boost { template <class T> class optional; } namespace boost { template <class T> class optional; }
namespace mapnik namespace mapnik
@ -51,22 +48,17 @@ using face_set_ptr = std::unique_ptr<font_face_set>;
class font_face; class font_face;
using face_ptr = std::shared_ptr<font_face>; using face_ptr = std::shared_ptr<font_face>;
class MAPNIK_DECL freetype_engine class MAPNIK_DECL freetype_engine : public singleton<freetype_engine, CreateUsingNew>,
private util::noncopyable
{ {
friend class CreateUsingNew<freetype_engine>;
friend class Map;
public: public:
using font_file_mapping_type = std::map<std::string,std::pair<int,std::string>>; using font_file_mapping_type = std::map<std::string,std::pair<int,std::string>>;
using font_memory_cache_type = std::map<std::string, std::pair<std::unique_ptr<char[]>, std::size_t>>; using font_memory_cache_type = std::map<std::string, std::pair<std::unique_ptr<char[]>, std::size_t>>;
static bool is_font_file(std::string const& file_name); static bool is_font_file(std::string const& file_name);
/*! \brief register a font file
* @param file_name path to a font file.
* @return bool - true if at least one face was successfully registered in the file.
*/
static bool register_font(std::string const& file_name); static bool register_font(std::string const& file_name);
/*! \brief register a font files
* @param dir - path to a directory containing fonts or subdirectories.
* @param recurse - default false, whether to search for fonts in sub directories.
* @return bool - true if at least one face was successfully registered.
*/
static bool register_fonts(std::string const& dir, bool recurse = false); static bool register_fonts(std::string const& dir, bool recurse = false);
static std::vector<std::string> face_names(); static std::vector<std::string> face_names();
static font_file_mapping_type const& get_mapping(); static font_file_mapping_type const& get_mapping();
@ -75,29 +67,42 @@ public:
font_library & library, font_library & library,
font_file_mapping_type const& font_file_mapping, font_file_mapping_type const& font_file_mapping,
font_file_mapping_type const& global_font_file_mapping); font_file_mapping_type const& global_font_file_mapping);
static face_ptr create_face(std::string const& face_name, static face_ptr create_face(std::string const& face_name,
font_library & library, font_library & library,
font_file_mapping_type const& font_file_mapping, font_file_mapping_type const& font_file_mapping,
freetype_engine::font_memory_cache_type const& font_cache, freetype_engine::font_memory_cache_type const& font_cache,
font_file_mapping_type const& global_font_file_mapping, font_file_mapping_type const& global_font_file_mapping,
freetype_engine::font_memory_cache_type & global_memory_fonts); freetype_engine::font_memory_cache_type & global_memory_fonts);
static bool register_font_impl(std::string const& file_name,
font_library & libary,
font_file_mapping_type & font_file_mapping);
static bool register_fonts_impl(std::string const& dir,
font_library & libary,
font_file_mapping_type & font_file_mapping,
bool recurse = false);
virtual ~freetype_engine();
freetype_engine();
private: private:
static bool register_font_impl(std::string const& file_name, FT_LibraryRec_ * library); bool is_font_file_impl(std::string const& file_name);
static bool register_fonts_impl(std::string const& dir, FT_LibraryRec_ * library, bool recurse = false); std::vector<std::string> face_names_impl();
#ifdef MAPNIK_THREADSAFE font_file_mapping_type const& get_mapping_impl();
static std::mutex mutex_; font_memory_cache_type& get_cache_impl();
#endif bool can_open_impl(std::string const& face_name,
static font_file_mapping_type global_font_file_mapping_; font_library & library,
static font_memory_cache_type global_memory_fonts_; font_file_mapping_type const& font_file_mapping,
font_file_mapping_type const& global_font_file_mapping);
face_ptr create_face_impl(std::string const& face_name,
font_library & library,
font_file_mapping_type const& font_file_mapping,
freetype_engine::font_memory_cache_type const& font_cache,
font_file_mapping_type const& global_font_file_mapping,
freetype_engine::font_memory_cache_type & global_memory_fonts);
bool register_font_impl(std::string const& file_name);
bool register_fonts_impl(std::string const& dir, bool recurse);
bool register_font_impl(std::string const& file_name, FT_LibraryRec_ * library);
bool register_fonts_impl(std::string const& dir, FT_LibraryRec_ * library, bool recurse = false);
bool register_font_impl(std::string const& file_name,
font_library & libary,
font_file_mapping_type & font_file_mapping);
bool register_fonts_impl(std::string const& dir,
font_library & libary,
font_file_mapping_type & font_file_mapping,
bool recurse = false);
font_file_mapping_type global_font_file_mapping_;
font_memory_cache_type global_memory_fonts_;
}; };
class MAPNIK_DECL face_manager class MAPNIK_DECL face_manager
@ -124,7 +129,7 @@ private:
}; };
using face_manager_freetype = face_manager; using face_manager_freetype = face_manager;
extern template class MAPNIK_DECL singleton<freetype_engine, CreateUsingNew>;
} }
#endif // MAPNIK_FONT_ENGINE_FREETYPE_HPP #endif // MAPNIK_FONT_ENGINE_FREETYPE_HPP

View file

@ -2,7 +2,7 @@
* *
* This file is part of Mapnik (c++ mapping toolkit) * This file is part of Mapnik (c++ mapping toolkit)
* *
* Copyright (C) 2017 Artem Pavlenko * Copyright (C) 2015 Artem Pavlenko
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -48,11 +48,10 @@ extern "C"
#include <algorithm> #include <algorithm>
#include <stdexcept> #include <stdexcept>
namespace mapnik namespace mapnik
{ {
template class MAPNIK_DECL singleton<freetype_engine, CreateUsingNew>;
freetype_engine::freetype_engine() {}
freetype_engine::~freetype_engine() {}
bool freetype_engine::is_font_file(std::string const& file_name) bool freetype_engine::is_font_file(std::string const& file_name)
{ {
@ -78,6 +77,11 @@ unsigned long ft_read_cb(FT_Stream stream, unsigned long offset, unsigned char *
} }
bool freetype_engine::register_font(std::string const& file_name) bool freetype_engine::register_font(std::string const& file_name)
{
return instance().register_font_impl(file_name);
}
bool freetype_engine::register_font_impl(std::string const& file_name)
{ {
#ifdef MAPNIK_THREADSAFE #ifdef MAPNIK_THREADSAFE
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
@ -160,6 +164,11 @@ bool freetype_engine::register_font_impl(std::string const& file_name,
} }
bool freetype_engine::register_fonts(std::string const& dir, bool recurse) bool freetype_engine::register_fonts(std::string const& dir, bool recurse)
{
return instance().register_fonts_impl(dir, recurse);
}
bool freetype_engine::register_fonts_impl(std::string const& dir, bool recurse)
{ {
#ifdef MAPNIK_THREADSAFE #ifdef MAPNIK_THREADSAFE
std::lock_guard<std::mutex> lock(mutex_); std::lock_guard<std::mutex> lock(mutex_);
@ -215,8 +224,12 @@ bool freetype_engine::register_fonts_impl(std::string const& dir,
return success; return success;
} }
std::vector<std::string> freetype_engine::face_names()
{
return instance().face_names_impl();
}
std::vector<std::string> freetype_engine::face_names () std::vector<std::string> freetype_engine::face_names_impl()
{ {
std::vector<std::string> names; std::vector<std::string> names;
for (auto const& kv : global_font_file_mapping_) for (auto const& kv : global_font_file_mapping_)
@ -227,11 +240,21 @@ std::vector<std::string> freetype_engine::face_names ()
} }
freetype_engine::font_file_mapping_type const& freetype_engine::get_mapping() freetype_engine::font_file_mapping_type const& freetype_engine::get_mapping()
{
return instance().get_mapping_impl();
}
freetype_engine::font_file_mapping_type const& freetype_engine::get_mapping_impl()
{ {
return global_font_file_mapping_; return global_font_file_mapping_;
} }
freetype_engine::font_memory_cache_type & freetype_engine::get_cache() freetype_engine::font_memory_cache_type & freetype_engine::get_cache()
{
return instance().get_cache_impl();
}
freetype_engine::font_memory_cache_type & freetype_engine::get_cache_impl()
{ {
return global_memory_fonts_; return global_memory_fonts_;
} }
@ -240,6 +263,14 @@ bool freetype_engine::can_open(std::string const& face_name,
font_library & library, font_library & library,
font_file_mapping_type const& font_file_mapping, font_file_mapping_type const& font_file_mapping,
font_file_mapping_type const& global_font_file_mapping) font_file_mapping_type const& global_font_file_mapping)
{
return instance().can_open_impl(face_name, library, font_file_mapping, global_font_file_mapping);
}
bool freetype_engine::can_open_impl(std::string const& face_name,
font_library & library,
font_file_mapping_type const& font_file_mapping,
font_file_mapping_type const& global_font_file_mapping)
{ {
bool found_font_file = false; bool found_font_file = false;
font_file_mapping_type::const_iterator itr = font_file_mapping.find(face_name); font_file_mapping_type::const_iterator itr = font_file_mapping.find(face_name);
@ -278,12 +309,12 @@ bool freetype_engine::can_open(std::string const& face_name,
return true; return true;
} }
face_ptr freetype_engine::create_face(std::string const& family_name, face_ptr freetype_engine::create_face_impl(std::string const& family_name,
font_library & library, font_library & library,
freetype_engine::font_file_mapping_type const& font_file_mapping, freetype_engine::font_file_mapping_type const& font_file_mapping,
freetype_engine::font_memory_cache_type const& font_cache, freetype_engine::font_memory_cache_type const& font_cache,
freetype_engine::font_file_mapping_type const& global_font_file_mapping, freetype_engine::font_file_mapping_type const& global_font_file_mapping,
freetype_engine::font_memory_cache_type & global_memory_fonts) freetype_engine::font_memory_cache_type & global_memory_fonts)
{ {
bool found_font_file = false; bool found_font_file = false;
font_file_mapping_type::const_iterator itr = font_file_mapping.find(family_name); font_file_mapping_type::const_iterator itr = font_file_mapping.find(family_name);
@ -355,6 +386,20 @@ face_ptr freetype_engine::create_face(std::string const& family_name,
return face_ptr(); return face_ptr();
} }
face_ptr freetype_engine::create_face(std::string const& family_name,
font_library & library,
freetype_engine::font_file_mapping_type const& font_file_mapping,
freetype_engine::font_memory_cache_type const& font_cache,
freetype_engine::font_file_mapping_type const& global_font_file_mapping,
freetype_engine::font_memory_cache_type & global_memory_fonts)
{
return instance().create_face_impl(family_name,
library,
font_file_mapping,
font_cache,
global_font_file_mapping,
global_memory_fonts);
}
face_manager::face_manager(font_library & library, face_manager::face_manager(font_library & library,
freetype_engine::font_file_mapping_type const& font_file_mapping, freetype_engine::font_file_mapping_type const& font_file_mapping,
@ -385,8 +430,8 @@ face_ptr face_manager::get_face(std::string const& name)
library_, library_,
font_file_mapping_, font_file_mapping_,
font_memory_cache_, font_memory_cache_,
freetype_engine::get_mapping(), freetype_engine::instance().get_mapping(),
freetype_engine::get_cache()); freetype_engine::instance().get_cache());
if (face) if (face)
{ {
face_cache_->emplace(name, face); face_cache_->emplace(name, face);
@ -440,10 +485,4 @@ face_set_ptr face_manager::get_face_set(std::string const& name, boost::optional
} }
} }
#ifdef MAPNIK_THREADSAFE
std::mutex freetype_engine::mutex_;
#endif
freetype_engine::font_file_mapping_type freetype_engine::global_font_file_mapping_;
freetype_engine::font_memory_cache_type freetype_engine::global_memory_fonts_;
} }

View file

@ -285,7 +285,7 @@ std::map<std::string,font_set> & Map::fontsets()
bool Map::register_fonts(std::string const& dir, bool recurse) bool Map::register_fonts(std::string const& dir, bool recurse)
{ {
font_library library; font_library library;
return freetype_engine::register_fonts_impl(dir, library, font_file_mapping_, recurse); return freetype_engine::instance().register_fonts_impl(dir, library, font_file_mapping_, recurse);
} }
bool Map::load_fonts() bool Map::load_fonts()