face_ptr freetype_engine::create_face(std::string const& family_name) { 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(); }
face_ptr freetype_engine::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(); }
face_ptr freetype_engine::create_face(std::string const& family_name) { auto itr = name2file_.find(family_name); if (itr != name2file_.end()) { FT_Face face; auto mem_font_itr = memory_fonts_.find(itr->second.second); if (mem_font_itr != memory_fonts_.end()) // memory font { FT_Error error = FT_New_Memory_Face(library_, reinterpret_cast<FT_Byte const*>(mem_font_itr->second.first.get()), // data static_cast<FT_Long>(mem_font_itr->second.second), // size itr->second.first, // face index &face); if (!error) return std::make_shared<font_face>(face); } else { // load font into memory #ifdef MAPNIK_THREADSAFE mapnik::scoped_lock lock(mutex_); #endif #ifdef _WINDOWS std::unique_ptr<std::FILE, int (*)(std::FILE *)> file(_wfopen(mapnik::utf8_to_utf16(itr->second.second).c_str(), L"rb"), fclose); #else std::unique_ptr<std::FILE, int (*)(std::FILE *)> file(std::fopen(itr->second.second.c_str(),"rb"), std::fclose); #endif if (file != nullptr) { std::fseek(file.get(), 0, SEEK_END); std::size_t file_size = std::ftell(file.get()); std::fseek(file.get(), 0, SEEK_SET); std::unique_ptr<char[]> buffer(new char[file_size]); std::fread(buffer.get(), file_size, 1, file.get()); auto result = memory_fonts_.insert(std::make_pair(itr->second.second, std::make_pair(std::move(buffer),file_size))); FT_Error error = FT_New_Memory_Face (library_, reinterpret_cast<FT_Byte const*>(result.first->second.first.get()), static_cast<FT_Long>(result.first->second.second), itr->second.first, &face); if (!error) return std::make_shared<font_face>(face); else { // we can't load font, erase it. memory_fonts_.erase(result.first); } } } } return face_ptr(); }
face_ptr freetype_engine::create_face(std::string const& family_name) { std::map<std::string, std::pair<int,std::string> >::const_iterator itr; itr = name2file_.find(family_name); if (itr != name2file_.end()) { FT_Face face; std::map<std::string,std::string>::const_iterator mem_font_itr = memory_fonts_.find(itr->second.second); if (mem_font_itr != memory_fonts_.end()) // memory font { FT_Error error = FT_New_Memory_Face(library_, reinterpret_cast<FT_Byte const*>(mem_font_itr->second.c_str()), static_cast<FT_Long>(mem_font_itr->second.size()), // size itr->second.first, // face index &face); if (!error) return std::make_shared<font_face>(face); } else { // load font into memory #ifdef MAPNIK_THREADSAFE mapnik::scoped_lock lock(mutex_); #endif std::ifstream is(itr->second.second.c_str() , std::ios::binary); std::string buffer((std::istreambuf_iterator<char>(is)), std::istreambuf_iterator<char>()); std::pair<std::map<std::string,std::string>::iterator,bool> result = memory_fonts_.insert(std::make_pair(itr->second.second, buffer)); FT_Error error = FT_New_Memory_Face (library_, reinterpret_cast<FT_Byte const*>(result.first->second.c_str()), static_cast<FT_Long>(buffer.size()), itr->second.first, &face); if (!error) return std::make_shared<font_face>(face); else { // we can't load font, erase it. memory_fonts_.erase(result.first); } } } return face_ptr(); }
face_ptr freetype_engine::create_face(std::string const& family_name) { std::map<std::string, std::pair<int,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.second.c_str(), itr->second.first, &face); if (!error) { return boost::make_shared<font_face>(face); } } 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) { bool found_font_file = false; font_file_mapping_type::const_iterator itr = font_file_mapping.find(family_name); // look for font registered on specific map if (itr != font_file_mapping.end()) { auto mem_font_itr = font_cache.find(itr->second.second); // if map has font already in memory, use it if (mem_font_itr != font_cache.end()) { FT_Face face; FT_Error error = FT_New_Memory_Face(library.get(), reinterpret_cast<FT_Byte const*>(mem_font_itr->second.first.get()), // data static_cast<FT_Long>(mem_font_itr->second.second), // size itr->second.first, // face index &face); if (!error) return std::make_shared<font_face>(face); } // we don't add to cache here because the map and its font_cache // must be immutable during rendering for predictable thread safety found_font_file = true; } else { // otherwise search global registry itr = global_font_file_mapping.find(family_name); if (itr != global_font_file_mapping.end()) { auto mem_font_itr = global_memory_fonts.find(itr->second.second); // if font already in memory, use it if (mem_font_itr != global_memory_fonts.end()) { FT_Face face; FT_Error error = FT_New_Memory_Face(library.get(), reinterpret_cast<FT_Byte const*>(mem_font_itr->second.first.get()), // data static_cast<FT_Long>(mem_font_itr->second.second), // size itr->second.first, // face index &face); if (!error) return std::make_shared<font_face>(face); } found_font_file = true; } } // if we found file file but it is not yet in memory if (found_font_file) { mapnik::util::file file(itr->second.second); if (file) { #ifdef MAPNIK_THREADSAFE std::lock_guard<std::mutex> lock(mutex_); #endif auto result = global_memory_fonts.emplace(itr->second.second, std::make_pair(file.data(),file.size())); FT_Face face; FT_Error error = FT_New_Memory_Face(library.get(), reinterpret_cast<FT_Byte const*>(result.first->second.first.get()), // data static_cast<FT_Long>(result.first->second.second), // size itr->second.first, // face index &face); if (error) { // we can't load font, erase it. global_memory_fonts.erase(result.first); return face_ptr(); } return std::make_shared<font_face>(face); } } return face_ptr(); }