Faster font i/o backported to 2.3.x - refs #2282
This commit is contained in:
parent
a1cab08d77
commit
bdd800b6fc
1 changed files with 39 additions and 36 deletions
|
@ -90,16 +90,14 @@ bool freetype_engine::is_font_file(std::string const& file_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long ft_read_cb(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count) {
|
unsigned long ft_read_cb(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count) {
|
||||||
if (count <= 0) return count;
|
if (count <= 0) return 0;
|
||||||
std::ifstream * file = static_cast<std::ifstream *>(stream->descriptor.pointer);
|
FILE * file = static_cast<FILE *>(stream->descriptor.pointer);
|
||||||
file->seekg(offset, std::ios::beg);
|
std::fseek (file , offset , SEEK_SET);
|
||||||
file->read((char*)buffer, count);
|
return std::fread ((char*)buffer, 1, count, file);
|
||||||
return file->gcount();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ft_close_cb(FT_Stream stream) {
|
void ft_close_cb(FT_Stream stream) {
|
||||||
std::ifstream * file = static_cast<std::ifstream *>(stream->descriptor.pointer);
|
std::fclose (static_cast<std::FILE *>(stream->descriptor.pointer));
|
||||||
file->close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool freetype_engine::register_font(std::string const& file_name)
|
bool freetype_engine::register_font(std::string const& file_name)
|
||||||
|
@ -109,13 +107,11 @@ bool freetype_engine::register_font(std::string const& file_name)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WINDOWS
|
#ifdef _WINDOWS
|
||||||
std::ifstream file(mapnik::utf8_to_utf16(file_name) , std::ios::binary);
|
FILE * file = _wfopen(mapnik::utf8_to_utf16(file_name).c_str(), L"rb");
|
||||||
#else
|
#else
|
||||||
std::ifstream file(file_name.c_str() , std::ios::binary);
|
FILE * file = std::fopen(file_name.c_str(),"rb");
|
||||||
#endif
|
#endif
|
||||||
if (!file.good()) {
|
if (file == NULL) return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FT_Library library = 0;
|
FT_Library library = 0;
|
||||||
FT_Error error = FT_Init_FreeType(&library);
|
FT_Error error = FT_Init_FreeType(&library);
|
||||||
|
@ -129,16 +125,13 @@ bool freetype_engine::register_font(std::string const& file_name)
|
||||||
FT_StreamRec streamRec;
|
FT_StreamRec streamRec;
|
||||||
memset(&args, 0, sizeof(args));
|
memset(&args, 0, sizeof(args));
|
||||||
memset(&streamRec, 0, sizeof(streamRec));
|
memset(&streamRec, 0, sizeof(streamRec));
|
||||||
std::streampos beg = file.tellg();
|
fseek(file, 0, SEEK_END);
|
||||||
file.seekg (0, std::ios::end);
|
std::size_t file_size = std::ftell(file);
|
||||||
std::streampos end = file.tellg();
|
fseek(file, 0, SEEK_SET);
|
||||||
std::size_t file_size = end - beg;
|
|
||||||
file.seekg (0, std::ios::beg);
|
|
||||||
|
|
||||||
streamRec.base = 0;
|
streamRec.base = 0;
|
||||||
streamRec.pos = 0;
|
streamRec.pos = 0;
|
||||||
streamRec.size = file_size;
|
streamRec.size = file_size;
|
||||||
streamRec.descriptor.pointer = &file;
|
streamRec.descriptor.pointer = file;
|
||||||
streamRec.read = ft_read_cb;
|
streamRec.read = ft_read_cb;
|
||||||
streamRec.close = ft_close_cb;
|
streamRec.close = ft_close_cb;
|
||||||
args.flags = FT_OPEN_STREAM;
|
args.flags = FT_OPEN_STREAM;
|
||||||
|
@ -183,9 +176,8 @@ bool freetype_engine::register_font(std::string const& file_name)
|
||||||
|
|
||||||
MAPNIK_LOG_ERROR(font_engine_freetype) << "register_font: " << s.str();
|
MAPNIK_LOG_ERROR(font_engine_freetype) << "register_font: " << s.str();
|
||||||
}
|
}
|
||||||
|
if (face) FT_Done_Face(face);
|
||||||
}
|
}
|
||||||
if (face)
|
|
||||||
FT_Done_Face(face);
|
|
||||||
if (library)
|
if (library)
|
||||||
FT_Done_FreeType(library);
|
FT_Done_FreeType(library);
|
||||||
return success;
|
return success;
|
||||||
|
@ -300,22 +292,33 @@ face_ptr freetype_engine::create_face(std::string const& family_name)
|
||||||
#ifdef MAPNIK_THREADSAFE
|
#ifdef MAPNIK_THREADSAFE
|
||||||
mutex::scoped_lock lock(mutex_);
|
mutex::scoped_lock lock(mutex_);
|
||||||
#endif
|
#endif
|
||||||
std::ifstream is(itr->second.second.c_str() , std::ios::binary);
|
#ifdef _WINDOWS
|
||||||
std::string buffer((std::istreambuf_iterator<char>(is)),
|
FILE * file = _wfopen(mapnik::utf8_to_utf16(itr->second.second).c_str(), L"rb");
|
||||||
std::istreambuf_iterator<char>());
|
#else
|
||||||
std::pair<std::map<std::string,std::string>::iterator,bool> result
|
FILE * file = std::fopen(itr->second.second.c_str(),"rb");
|
||||||
= memory_fonts_.insert(std::make_pair(itr->second.second, buffer));
|
#endif
|
||||||
|
if (file != NULL)
|
||||||
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 boost::make_shared<font_face>(face);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// we can't load font, erase it.
|
std::fseek(file, 0, SEEK_END);
|
||||||
memory_fonts_.erase(result.first);
|
std::size_t file_size = std::ftell(file);
|
||||||
|
std::fseek(file, 0, SEEK_SET);
|
||||||
|
std::string buffer;
|
||||||
|
buffer.resize(file_size);
|
||||||
|
std::fread(&buffer[0], file_size, 1, file);
|
||||||
|
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);
|
||||||
|
std::fclose(file);
|
||||||
|
if (!error) return boost::make_shared<font_face>(face);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// we can't load font, erase it.
|
||||||
|
memory_fonts_.erase(result.first);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue