fast, non-caching check if a font can be opened and read
This commit is contained in:
commit
687a33575c
3 changed files with 60 additions and 8 deletions
|
@ -71,7 +71,11 @@ public:
|
|||
static std::vector<std::string> face_names();
|
||||
static font_file_mapping_type const& get_mapping();
|
||||
static font_memory_cache_type & get_cache();
|
||||
static face_ptr create_face(std::string const& family_name,
|
||||
static bool can_open(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);
|
||||
static face_ptr create_face(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,
|
||||
|
|
|
@ -259,6 +259,48 @@ freetype_engine::font_memory_cache_type & freetype_engine::get_cache()
|
|||
return global_memory_fonts_;
|
||||
}
|
||||
|
||||
bool freetype_engine::can_open(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;
|
||||
font_file_mapping_type::const_iterator itr = font_file_mapping.find(face_name);
|
||||
if (itr != font_file_mapping.end())
|
||||
{
|
||||
found_font_file = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
itr = global_font_file_mapping.find(face_name);
|
||||
if (itr != global_font_file_mapping.end())
|
||||
{
|
||||
found_font_file = true;
|
||||
}
|
||||
}
|
||||
if (!found_font_file) return false;
|
||||
mapnik::util::file file(itr->second.second);
|
||||
if (!file.open()) return false;
|
||||
FT_Face face = 0;
|
||||
FT_Open_Args args;
|
||||
FT_StreamRec streamRec;
|
||||
memset(&args, 0, sizeof(args));
|
||||
memset(&streamRec, 0, sizeof(streamRec));
|
||||
streamRec.base = 0;
|
||||
streamRec.pos = 0;
|
||||
streamRec.size = file.size();
|
||||
streamRec.descriptor.pointer = file.get();
|
||||
streamRec.read = ft_read_cb;
|
||||
streamRec.close = NULL;
|
||||
args.flags = FT_OPEN_STREAM;
|
||||
args.stream = &streamRec;
|
||||
// -1 is used to quickly check if the font file appears valid without iterating each face
|
||||
FT_Error error = FT_Open_Face(library.get(), &args, -1, &face);
|
||||
if (face) FT_Done_Face(face);
|
||||
if (error) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
face_ptr freetype_engine::create_face(std::string const& family_name,
|
||||
font_library & library,
|
||||
freetype_engine::font_file_mapping_type const& font_file_mapping,
|
||||
|
|
|
@ -88,9 +88,8 @@ public:
|
|||
strict_(strict),
|
||||
filename_(filename),
|
||||
font_library_(),
|
||||
font_manager_(font_library_,map.get_font_file_mapping(),map.get_font_memory_cache()),
|
||||
xml_base_path_()
|
||||
{}
|
||||
font_file_mapping_(map.get_font_file_mapping()),
|
||||
xml_base_path_() {}
|
||||
|
||||
void parse_map(Map & map, xml_node const& node, std::string const& base_path);
|
||||
private:
|
||||
|
@ -131,7 +130,7 @@ private:
|
|||
std::string filename_;
|
||||
std::map<std::string,parameters> datasource_templates_;
|
||||
font_library font_library_;
|
||||
face_manager_freetype font_manager_;
|
||||
freetype_engine::font_file_mapping_type & font_file_mapping_;
|
||||
std::map<std::string,std::string> file_sources_;
|
||||
std::map<std::string,font_set> fontsets_;
|
||||
std::string xml_base_path_;
|
||||
|
@ -518,8 +517,11 @@ bool map_parser::parse_font(font_set &fset, xml_node const& f)
|
|||
optional<std::string> face_name = f.get_opt_attr<std::string>("face-name");
|
||||
if (face_name)
|
||||
{
|
||||
face_ptr face = font_manager_.get_face(*face_name);
|
||||
if (face)
|
||||
// TODO - cache results to avoid repeated opens
|
||||
if (freetype_engine::can_open(*face_name,
|
||||
font_library_,
|
||||
font_file_mapping_,
|
||||
freetype_engine::get_mapping()))
|
||||
{
|
||||
fset.add_face_name(*face_name);
|
||||
return true;
|
||||
|
@ -1521,7 +1523,11 @@ void map_parser::parse_pair_layout(group_symbolizer_properties & prop, xml_node
|
|||
|
||||
void map_parser::ensure_font_face(std::string const& face_name)
|
||||
{
|
||||
if (! font_manager_.get_face(face_name))
|
||||
// TODO - cache results to avoid repeated opens
|
||||
if (!freetype_engine::can_open(face_name,
|
||||
font_library_,
|
||||
font_file_mapping_,
|
||||
freetype_engine::get_mapping()))
|
||||
{
|
||||
throw config_error("Failed to find font face '" +
|
||||
face_name + "'");
|
||||
|
|
Loading…
Add table
Reference in a new issue