Skip to content

Commit

Permalink
Merge pull request #44117 from bruvzg/mem_fonts
Browse files Browse the repository at this point in the history
Load dynamic fonts to memory on all platforms, to avoid locked files.
  • Loading branch information
akien-mga authored Dec 7, 2020
2 parents 02e370b + 29e5b90 commit 73eb8d5
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 112 deletions.
60 changes: 8 additions & 52 deletions modules/text_server_adv/dynamic_font_adv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
#include FT_STROKER_H
#include FT_ADVANCES_H

HashMap<String, Vector<uint8_t>> DynamicFontDataAdvanced::font_mem_cache;

DynamicFontDataAdvanced::DataAtSize *DynamicFontDataAdvanced::get_data_for_size(int p_size, int p_outline_size) {
ERR_FAIL_COND_V(!valid, nullptr);
ERR_FAIL_COND_V(p_size < 0 || p_size > UINT16_MAX, nullptr);
Expand All @@ -55,51 +53,28 @@ DynamicFontDataAdvanced::DataAtSize *DynamicFontDataAdvanced::get_data_for_size(
if (E != nullptr) {
fds = E->get();
} else {
// FT_OPEN_STREAM is extremely slow only on Android.
if (OS::get_singleton()->get_name() == "Android" && font_mem == nullptr && font_path != String()) {
if (font_mem_cache.has(font_path)) {
font_mem = font_mem_cache[font_path].ptr();
font_mem_size = font_mem_cache[font_path].size();
if (font_mem == nullptr && font_path != String()) {
if (!font_mem_cache.empty()) {
font_mem = font_mem_cache.ptr();
font_mem_size = font_mem_cache.size();
} else {
FileAccess *f = FileAccess::open(font_path, FileAccess::READ);
if (!f) {
ERR_FAIL_V_MSG(nullptr, "Cannot open font file '" + font_path + "'.");
}

size_t len = f->get_len();
font_mem_cache[font_path] = Vector<uint8_t>();
Vector<uint8_t> &fontdata = font_mem_cache[font_path];
fontdata.resize(len);
f->get_buffer(fontdata.ptrw(), len);
font_mem = fontdata.ptr();
font_mem_cache.resize(len);
f->get_buffer(font_mem_cache.ptrw(), len);
font_mem = font_mem_cache.ptr();
font_mem_size = len;
f->close();
}
}

int error = 0;
fds = memnew(DataAtSize);
if (font_mem == nullptr && font_path != String()) {
FileAccess *f = FileAccess::open(font_path, FileAccess::READ);
if (!f) {
memdelete(fds);
ERR_FAIL_V_MSG(nullptr, "Cannot open font file '" + font_path + "'.");
}

memset(&fds->stream, 0, sizeof(FT_StreamRec));
fds->stream.base = nullptr;
fds->stream.size = f->get_len();
fds->stream.pos = 0;
fds->stream.descriptor.pointer = f;
fds->stream.read = _ft_stream_io;
fds->stream.close = _ft_stream_close;

FT_Open_Args fargs;
memset(&fargs, 0, sizeof(FT_Open_Args));
fargs.flags = FT_OPEN_STREAM;
fargs.stream = &fds->stream;
error = FT_Open_Face(library, &fargs, 0, &fds->face);
} else if (font_mem) {
if (font_mem) {
memset(&fds->stream, 0, sizeof(FT_StreamRec));
fds->stream.base = (unsigned char *)font_mem;
fds->stream.size = font_mem_size;
Expand Down Expand Up @@ -169,25 +144,6 @@ DynamicFontDataAdvanced::DataAtSize *DynamicFontDataAdvanced::get_data_for_size(
return fds;
}

unsigned long DynamicFontDataAdvanced::_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 DynamicFontDataAdvanced::_ft_stream_close(FT_Stream stream) {
FileAccess *f = (FileAccess *)stream->descriptor.pointer;
f->close();
memdelete(f);
}

Dictionary DynamicFontDataAdvanced::get_feature_list() const {
_THREAD_SAFE_METHOD_
DataAtSize *fds = const_cast<DynamicFontDataAdvanced *>(this)->get_data_for_size(base_size);
Expand Down
5 changes: 1 addition & 4 deletions modules/text_server_adv/dynamic_font_adv.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ struct DynamicFontDataAdvanced : public FontDataAdvanced {
const uint8_t *font_mem = nullptr;
int font_mem_size = 0;
String font_path;
static HashMap<String, Vector<uint8_t>> font_mem_cache;
Vector<uint8_t> font_mem_cache;

float rect_margin = 1.f;
int base_size = 16;
Expand All @@ -128,9 +128,6 @@ struct DynamicFontDataAdvanced : public FontDataAdvanced {
Map<CacheID, DataAtSize *> size_cache;
Map<CacheID, DataAtSize *> size_cache_outline;

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);

DataAtSize *get_data_for_size(int p_size, int p_outline_size = 0);

TexturePosition find_texture_pos_for_glyph(DataAtSize *p_data, int p_color_size, Image::Format p_image_format, int p_width, int p_height);
Expand Down
60 changes: 8 additions & 52 deletions modules/text_server_fb/dynamic_font_fb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@
#include FT_STROKER_H
#include FT_ADVANCES_H

HashMap<String, Vector<uint8_t>> DynamicFontDataFallback::font_mem_cache;

DynamicFontDataFallback::DataAtSize *DynamicFontDataFallback::get_data_for_size(int p_size, int p_outline_size) {
ERR_FAIL_COND_V(!valid, nullptr);
ERR_FAIL_COND_V(p_size < 0 || p_size > UINT16_MAX, nullptr);
Expand All @@ -55,51 +53,28 @@ DynamicFontDataFallback::DataAtSize *DynamicFontDataFallback::get_data_for_size(
if (E != nullptr) {
fds = E->get();
} else {
// FT_OPEN_STREAM is extremely slow only on Android.
if (OS::get_singleton()->get_name() == "Android" && font_mem == nullptr && font_path != String()) {
if (font_mem_cache.has(font_path)) {
font_mem = font_mem_cache[font_path].ptr();
font_mem_size = font_mem_cache[font_path].size();
if (font_mem == nullptr && font_path != String()) {
if (!font_mem_cache.empty()) {
font_mem = font_mem_cache.ptr();
font_mem_size = font_mem_cache.size();
} else {
FileAccess *f = FileAccess::open(font_path, FileAccess::READ);
if (!f) {
ERR_FAIL_V_MSG(nullptr, "Cannot open font file '" + font_path + "'.");
}

size_t len = f->get_len();
font_mem_cache[font_path] = Vector<uint8_t>();
Vector<uint8_t> &fontdata = font_mem_cache[font_path];
fontdata.resize(len);
f->get_buffer(fontdata.ptrw(), len);
font_mem = fontdata.ptr();
font_mem_cache.resize(len);
f->get_buffer(font_mem_cache.ptrw(), len);
font_mem = font_mem_cache.ptr();
font_mem_size = len;
f->close();
}
}

int error = 0;
fds = memnew(DataAtSize);
if (font_mem == nullptr && font_path != String()) {
FileAccess *f = FileAccess::open(font_path, FileAccess::READ);
if (!f) {
memdelete(fds);
ERR_FAIL_V_MSG(nullptr, "Cannot open font file '" + font_path + "'.");
}

memset(&fds->stream, 0, sizeof(FT_StreamRec));
fds->stream.base = nullptr;
fds->stream.size = f->get_len();
fds->stream.pos = 0;
fds->stream.descriptor.pointer = f;
fds->stream.read = _ft_stream_io;
fds->stream.close = _ft_stream_close;

FT_Open_Args fargs;
memset(&fargs, 0, sizeof(FT_Open_Args));
fargs.flags = FT_OPEN_STREAM;
fargs.stream = &fds->stream;
error = FT_Open_Face(library, &fargs, 0, &fds->face);
} else if (font_mem) {
if (font_mem) {
memset(&fds->stream, 0, sizeof(FT_StreamRec));
fds->stream.base = (unsigned char *)font_mem;
fds->stream.size = font_mem_size;
Expand Down Expand Up @@ -161,25 +136,6 @@ DynamicFontDataFallback::DataAtSize *DynamicFontDataFallback::get_data_for_size(
return fds;
}

unsigned long DynamicFontDataFallback::_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 DynamicFontDataFallback::_ft_stream_close(FT_Stream stream) {
FileAccess *f = (FileAccess *)stream->descriptor.pointer;
f->close();
memdelete(f);
}

DynamicFontDataFallback::TexturePosition DynamicFontDataFallback::find_texture_pos_for_glyph(DynamicFontDataFallback::DataAtSize *p_data, int p_color_size, Image::Format p_image_format, int p_width, int p_height) {
TexturePosition ret;
ret.index = -1;
Expand Down
5 changes: 1 addition & 4 deletions modules/text_server_fb/dynamic_font_fb.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ struct DynamicFontDataFallback : public FontDataFallback {
const uint8_t *font_mem = nullptr;
int font_mem_size = 0;
String font_path;
static HashMap<String, Vector<uint8_t>> font_mem_cache;
Vector<uint8_t> font_mem_cache;

float rect_margin = 1.f;
int base_size = 16;
Expand All @@ -119,9 +119,6 @@ struct DynamicFontDataFallback : public FontDataFallback {
Map<CacheID, DataAtSize *> size_cache;
Map<CacheID, DataAtSize *> size_cache_outline;

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);

DataAtSize *get_data_for_size(int p_size, int p_outline_size = 0);

TexturePosition find_texture_pos_for_glyph(DataAtSize *p_data, int p_color_size, Image::Format p_image_format, int p_width, int p_height);
Expand Down

0 comments on commit 73eb8d5

Please sign in to comment.