use FT_Open_Face instead of FT_New_Face - refs #1897

This commit is contained in:
Dane Springmeyer 2014-06-18 15:42:32 -07:00
parent 90396b4359
commit 4007104bf1
2 changed files with 66 additions and 1 deletions

View file

@ -0,0 +1,26 @@
#include "bench_framework.hpp"
#include <mapnik/font_engine_freetype.hpp>
#include <boost/format.hpp>
#include <boost/foreach.hpp>
class test : public benchmark::test_case
{
public:
test(mapnik::parameters const& params)
: test_case(params) {}
bool validate() const
{
return mapnik::freetype_engine::register_fonts("./fonts", true);
}
void operator()() const
{
unsigned long count = 0;
for (unsigned i=0;i<iterations_;++i)
{
mapnik::freetype_engine::register_fonts("./fonts", true);
count++;
}
}
};
BENCHMARK(test,"font registration")

View file

@ -88,11 +88,32 @@ bool freetype_engine::is_font_file(std::string const& file_name)
boost::algorithm::ends_with(fn,std::string(".dfont"));
}
unsigned long ft_read_cb(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count) {
if (count <= 0) return count;
std::ifstream * file = static_cast<std::ifstream *>(stream->descriptor.pointer);
file->seekg(offset, std::ios::beg);
file->read((char*)buffer, count);
return file->gcount();
}
void ft_close_cb(FT_Stream stream) {
std::ifstream * file = static_cast<std::ifstream *>(stream->descriptor.pointer);
file->close();
}
bool freetype_engine::register_font(std::string const& file_name)
{
#ifdef MAPNIK_THREADSAFE
mutex::scoped_lock lock(mutex_);
#endif
std::ifstream file(file_name.c_str() , std::ios::binary);
if (!file.good()) {
std::ostringstream s;
s << "Unable to open font file '" << file_name << "' ";
throw std::runtime_error(s.str().c_str());
}
FT_Library library = 0;
FT_Error error = FT_Init_FreeType(&library);
if (error)
@ -101,6 +122,24 @@ bool freetype_engine::register_font(std::string const& file_name)
}
FT_Face face = 0;
FT_Open_Args args;
FT_StreamRec streamRec;
memset(&args, 0, sizeof(args));
memset(&streamRec, 0, sizeof(streamRec));
std::streampos beg = file.tellg();
file.seekg (0, std::ios::end);
std::streampos end = file.tellg();
std::size_t file_size = end - beg;
file.seekg (0, std::ios::beg);
streamRec.base = 0;
streamRec.pos = 0;
streamRec.size = file_size;
streamRec.descriptor.pointer = &file;
streamRec.read = ft_read_cb;
streamRec.close = ft_close_cb;
args.flags = FT_OPEN_STREAM;
args.stream = &streamRec;
int num_faces = 0;
bool success = false;
// some font files have multiple fonts in a file
@ -108,7 +147,7 @@ bool freetype_engine::register_font(std::string const& file_name)
// see the FT_FaceRec in freetype.h
for ( int i = 0; face == 0 || i < num_faces; i++ ) {
// if face is null then this is the first face
error = FT_New_Face (library,file_name.c_str(),i,&face);
error = FT_Open_Face(library, &args, i, &face);
if (error)
{
break;