mirror of
https://github.com/godotengine/godot.git
synced 2024-12-16 08:03:42 +00:00
Merge pull request #44160 from bruvzg/mem_font_32
[3.2] Load dynamic fonts to memory on all platforms, to avoid locked files.
This commit is contained in:
commit
efc373bc33
@ -112,7 +112,6 @@ DynamicFontData::~DynamicFontData() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////
|
////////////////////
|
||||||
HashMap<String, Vector<uint8_t> > DynamicFontAtSize::_fontdata;
|
|
||||||
|
|
||||||
Error DynamicFontAtSize::_load() {
|
Error DynamicFontAtSize::_load() {
|
||||||
|
|
||||||
@ -120,54 +119,22 @@ Error DynamicFontAtSize::_load() {
|
|||||||
|
|
||||||
ERR_FAIL_COND_V_MSG(error != 0, ERR_CANT_CREATE, "Error initializing FreeType.");
|
ERR_FAIL_COND_V_MSG(error != 0, ERR_CANT_CREATE, "Error initializing FreeType.");
|
||||||
|
|
||||||
// FT_OPEN_STREAM is extremely slow only on Android.
|
|
||||||
if (OS::get_singleton()->get_name() == "Android" && font->font_mem == NULL && font->font_path != String()) {
|
|
||||||
// cache font only once for each font->font_path
|
|
||||||
if (_fontdata.has(font->font_path)) {
|
|
||||||
|
|
||||||
font->set_font_ptr(_fontdata[font->font_path].ptr(), _fontdata[font->font_path].size());
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
FileAccess *f = FileAccess::open(font->font_path, FileAccess::READ);
|
|
||||||
if (!f) {
|
|
||||||
FT_Done_FreeType(library);
|
|
||||||
ERR_FAIL_V_MSG(ERR_CANT_OPEN, "Cannot open font file '" + font->font_path + "'.");
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t len = f->get_len();
|
|
||||||
_fontdata[font->font_path] = Vector<uint8_t>();
|
|
||||||
Vector<uint8_t> &fontdata = _fontdata[font->font_path];
|
|
||||||
fontdata.resize(len);
|
|
||||||
f->get_buffer(fontdata.ptrw(), len);
|
|
||||||
font->set_font_ptr(fontdata.ptr(), len);
|
|
||||||
f->close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (font->font_mem == NULL && font->font_path != String()) {
|
if (font->font_mem == NULL && font->font_path != String()) {
|
||||||
|
|
||||||
FileAccess *f = FileAccess::open(font->font_path, FileAccess::READ);
|
FileAccess *f = FileAccess::open(font->font_path, FileAccess::READ);
|
||||||
if (!f) {
|
if (!f) {
|
||||||
FT_Done_FreeType(library);
|
FT_Done_FreeType(library);
|
||||||
ERR_FAIL_V_MSG(ERR_CANT_OPEN, "Cannot open font file '" + font->font_path + "'.");
|
ERR_FAIL_V_MSG(ERR_CANT_OPEN, "Cannot open font file '" + font->font_path + "'.");
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(&stream, 0, sizeof(FT_StreamRec));
|
size_t len = f->get_len();
|
||||||
stream.base = NULL;
|
font->_fontdata = Vector<uint8_t>();
|
||||||
stream.size = f->get_len();
|
font->_fontdata.resize(len);
|
||||||
stream.pos = 0;
|
f->get_buffer(font->_fontdata.ptrw(), len);
|
||||||
stream.descriptor.pointer = f;
|
font->set_font_ptr(font->_fontdata.ptr(), len);
|
||||||
stream.read = _ft_stream_io;
|
f->close();
|
||||||
stream.close = _ft_stream_close;
|
}
|
||||||
|
|
||||||
FT_Open_Args fargs;
|
|
||||||
memset(&fargs, 0, sizeof(FT_Open_Args));
|
|
||||||
fargs.flags = FT_OPEN_STREAM;
|
|
||||||
fargs.stream = &stream;
|
|
||||||
error = FT_Open_Face(library, &fargs, 0, &face);
|
|
||||||
} else if (font->font_mem) {
|
|
||||||
|
|
||||||
|
if (font->font_mem) {
|
||||||
memset(&stream, 0, sizeof(FT_StreamRec));
|
memset(&stream, 0, sizeof(FT_StreamRec));
|
||||||
stream.base = (unsigned char *)font->font_mem;
|
stream.base = (unsigned char *)font->font_mem;
|
||||||
stream.size = font->font_mem_size;
|
stream.size = font->font_mem_size;
|
||||||
@ -372,26 +339,6 @@ float DynamicFontAtSize::draw_char(RID p_canvas_item, const Point2 &p_pos, CharT
|
|||||||
return advance;
|
return advance;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long DynamicFontAtSize::_ft_stream_io(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count) {
|
|
||||||
|
|
||||||
FileAccess *f = (FileAccess *)stream->descriptor.pointer;
|
|
||||||
|
|
||||||
if (f->get_position() != offset) {
|
|
||||||
f->seek(offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return f->get_buffer(buffer, count);
|
|
||||||
}
|
|
||||||
void DynamicFontAtSize::_ft_stream_close(FT_Stream stream) {
|
|
||||||
|
|
||||||
FileAccess *f = (FileAccess *)stream->descriptor.pointer;
|
|
||||||
f->close();
|
|
||||||
memdelete(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicFontAtSize::Character DynamicFontAtSize::Character::not_found() {
|
DynamicFontAtSize::Character DynamicFontAtSize::Character::not_found() {
|
||||||
Character ch;
|
Character ch;
|
||||||
ch.texture_idx = -1;
|
ch.texture_idx = -1;
|
||||||
|
@ -83,6 +83,7 @@ private:
|
|||||||
bool antialiased;
|
bool antialiased;
|
||||||
bool force_autohinter;
|
bool force_autohinter;
|
||||||
Hinting hinting;
|
Hinting hinting;
|
||||||
|
Vector<uint8_t> _fontdata;
|
||||||
|
|
||||||
String font_path;
|
String font_path;
|
||||||
Map<CacheID, DynamicFontAtSize *> size_cache;
|
Map<CacheID, DynamicFontAtSize *> size_cache;
|
||||||
@ -168,9 +169,6 @@ class DynamicFontAtSize : public Reference {
|
|||||||
TexturePosition _find_texture_pos_for_glyph(int p_color_size, Image::Format p_image_format, int p_width, int p_height);
|
TexturePosition _find_texture_pos_for_glyph(int p_color_size, Image::Format p_image_format, int p_width, int p_height);
|
||||||
Character _bitmap_to_character(FT_Bitmap bitmap, int yofs, int xofs, float advance);
|
Character _bitmap_to_character(FT_Bitmap bitmap, int yofs, int xofs, float advance);
|
||||||
|
|
||||||
static unsigned long _ft_stream_io(FT_Stream stream, unsigned long offset, unsigned char *buffer, unsigned long count);
|
|
||||||
static void _ft_stream_close(FT_Stream stream);
|
|
||||||
|
|
||||||
HashMap<CharType, Character> char_map;
|
HashMap<CharType, Character> char_map;
|
||||||
|
|
||||||
_FORCE_INLINE_ void _update_char(CharType p_char);
|
_FORCE_INLINE_ void _update_char(CharType p_char);
|
||||||
@ -179,7 +177,6 @@ class DynamicFontAtSize : public Reference {
|
|||||||
Ref<DynamicFontData> font;
|
Ref<DynamicFontData> font;
|
||||||
DynamicFontData::CacheID id;
|
DynamicFontData::CacheID id;
|
||||||
|
|
||||||
static HashMap<String, Vector<uint8_t> > _fontdata;
|
|
||||||
Error _load();
|
Error _load();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
Loading…
Reference in New Issue
Block a user