Merge branch 'master' of github.com:mapnik/mapnik
This commit is contained in:
commit
4f5d12defc
2 changed files with 49 additions and 48 deletions
|
@ -87,7 +87,7 @@ private:
|
||||||
static std::mutex mutex_;
|
static std::mutex mutex_;
|
||||||
#endif
|
#endif
|
||||||
static std::map<std::string, std::pair<int,std::string> > name2file_;
|
static std::map<std::string, std::pair<int,std::string> > name2file_;
|
||||||
static std::map<std::string, std::string> memory_fonts_;
|
static std::map<std::string, std::pair<std::unique_ptr<char[]>, std::size_t> > memory_fonts_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
|
@ -102,17 +102,17 @@ bool freetype_engine::is_font_file(std::string const& file_name)
|
||||||
boost::algorithm::ends_with(fn,std::string(".dfont"));
|
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) {
|
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);
|
if (count <= 0) return 0;
|
||||||
file->seekg(offset, std::ios::beg);
|
FILE * file = static_cast<FILE *>(stream->descriptor.pointer);
|
||||||
file->read((char*)buffer, count);
|
std::fseek (file , offset , SEEK_SET);
|
||||||
return file->gcount();
|
return std::fread ((char*)buffer, 1, count, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ft_close_cb(FT_Stream stream) {
|
void ft_close_cb(FT_Stream stream)
|
||||||
std::ifstream * file = static_cast<std::ifstream *>(stream->descriptor.pointer);
|
{
|
||||||
file->close();
|
std::fclose (static_cast<std::FILE *>(stream->descriptor.pointer));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool freetype_engine::register_font(std::string const& file_name)
|
bool freetype_engine::register_font(std::string const& file_name)
|
||||||
|
@ -131,31 +131,26 @@ bool freetype_engine::register_font(std::string const& file_name)
|
||||||
|
|
||||||
bool freetype_engine::register_font_impl(std::string const& file_name, FT_LibraryRec_ * library)
|
bool freetype_engine::register_font_impl(std::string const& file_name, FT_LibraryRec_ * library)
|
||||||
{
|
{
|
||||||
char buffer[512];
|
|
||||||
#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()) return false;
|
|
||||||
file.rdbuf()->pubsetbuf(buffer, 512);
|
if (file == nullptr) return false;
|
||||||
|
|
||||||
FT_Face face = 0;
|
FT_Face face = 0;
|
||||||
FT_Open_Args args;
|
FT_Open_Args args;
|
||||||
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));
|
||||||
|
fseek(file, 0, SEEK_END);
|
||||||
std::streampos beg = file.tellg();
|
std::size_t file_size = std::ftell(file);
|
||||||
file.seekg (0, std::ios::end);
|
fseek(file, 0, SEEK_SET);
|
||||||
std::streampos end = file.tellg();
|
|
||||||
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;
|
||||||
|
@ -165,15 +160,13 @@ bool freetype_engine::register_font_impl(std::string const& file_name, FT_Librar
|
||||||
// some font files have multiple fonts in a file
|
// some font files have multiple fonts in a file
|
||||||
// the count is in the 'root' face library[0]
|
// the count is in the 'root' face library[0]
|
||||||
// see the FT_FaceRec in freetype.h
|
// see the FT_FaceRec in freetype.h
|
||||||
for ( int i = 0; face == 0 || i < num_faces; i++ ) {
|
for ( int i = 0; face == 0 || i < num_faces; ++i )
|
||||||
|
{
|
||||||
// if face is null then this is the first face
|
// if face is null then this is the first face
|
||||||
FT_Error error = FT_Open_Face(library, &args, i, &face);
|
FT_Error error = FT_Open_Face(library, &args, i, &face);
|
||||||
if (error)
|
if (error) break;
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// store num_faces locally, after FT_Done_Face it can not be accessed any more
|
// store num_faces locally, after FT_Done_Face it can not be accessed any more
|
||||||
if (!num_faces)
|
if (num_faces == 0)
|
||||||
num_faces = face->num_faces;
|
num_faces = face->num_faces;
|
||||||
// some fonts can lack names, skip them
|
// some fonts can lack names, skip them
|
||||||
// http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_FaceRec
|
// http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT_FaceRec
|
||||||
|
@ -200,10 +193,8 @@ bool freetype_engine::register_font_impl(std::string const& file_name, FT_Librar
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,8 +305,8 @@ face_ptr freetype_engine::create_face(std::string const& family_name)
|
||||||
if (mem_font_itr != memory_fonts_.end()) // memory font
|
if (mem_font_itr != memory_fonts_.end()) // memory font
|
||||||
{
|
{
|
||||||
FT_Error error = FT_New_Memory_Face(library_,
|
FT_Error error = FT_New_Memory_Face(library_,
|
||||||
reinterpret_cast<FT_Byte const*>(mem_font_itr->second.c_str()),
|
reinterpret_cast<FT_Byte const*>(mem_font_itr->second.first.get()), // data
|
||||||
static_cast<FT_Long>(mem_font_itr->second.size()), // size
|
static_cast<FT_Long>(mem_font_itr->second.second), // size
|
||||||
itr->second.first, // face index
|
itr->second.first, // face index
|
||||||
&face);
|
&face);
|
||||||
|
|
||||||
|
@ -327,21 +318,31 @@ face_ptr freetype_engine::create_face(std::string const& family_name)
|
||||||
#ifdef MAPNIK_THREADSAFE
|
#ifdef MAPNIK_THREADSAFE
|
||||||
mapnik::scoped_lock lock(mutex_);
|
mapnik::scoped_lock lock(mutex_);
|
||||||
#endif
|
#endif
|
||||||
std::ifstream is(itr->second.second.c_str() , std::ios::binary);
|
|
||||||
std::string buffer((std::istreambuf_iterator<char>(is)),
|
|
||||||
std::istreambuf_iterator<char>());
|
|
||||||
auto result = memory_fonts_.insert(std::make_pair(itr->second.second, buffer));
|
|
||||||
|
|
||||||
FT_Error error = FT_New_Memory_Face (library_,
|
#ifdef _WINDOWS
|
||||||
reinterpret_cast<FT_Byte const*>(result.first->second.c_str()),
|
std::unique_ptr<std::FILE, int (*)(std::FILE *)> file(_wfopen(mapnik::utf8_to_utf16(itr->second.second).c_str(), L"rb"), fclose);
|
||||||
static_cast<FT_Long>(buffer.size()),
|
#else
|
||||||
itr->second.first,
|
std::unique_ptr<std::FILE, int (*)(std::FILE *)> file(std::fopen(itr->second.second.c_str(),"rb"), std::fclose);
|
||||||
&face);
|
#endif
|
||||||
if (!error) return std::make_shared<font_face>(face);
|
if (file != nullptr)
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// we can't load font, erase it.
|
std::fseek(file.get(), 0, SEEK_END);
|
||||||
memory_fonts_.erase(result.first);
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -433,7 +434,7 @@ face_set_ptr face_manager<T>::get_face_set(const std::string &name, boost::optio
|
||||||
std::mutex freetype_engine::mutex_;
|
std::mutex freetype_engine::mutex_;
|
||||||
#endif
|
#endif
|
||||||
std::map<std::string,std::pair<int,std::string> > freetype_engine::name2file_;
|
std::map<std::string,std::pair<int,std::string> > freetype_engine::name2file_;
|
||||||
std::map<std::string,std::string> freetype_engine::memory_fonts_;
|
std::map<std::string,std::pair<std::unique_ptr<char[]>,std::size_t> > freetype_engine::memory_fonts_;
|
||||||
template class face_manager<freetype_engine>;
|
template class face_manager<freetype_engine>;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue