[Complex Text Layouts] Add variable fonts support.

This commit is contained in:
bruvzg
2020-10-22 19:40:18 +03:00
parent bbf7bb3838
commit c1d261fdb0
16 changed files with 279 additions and 4 deletions
+77 -1
View File
@@ -32,6 +32,7 @@
#include FT_STROKER_H
#include FT_ADVANCES_H
#include FT_MULTIPLE_MASTERS_H
DynamicFontDataAdvanced::DataAtSize *DynamicFontDataAdvanced::get_data_for_size(int p_size, int p_outline_size) {
ERR_FAIL_COND_V(!valid, nullptr);
@@ -134,14 +135,89 @@ DynamicFontDataAdvanced::DataAtSize *DynamicFontDataAdvanced::get_data_for_size(
memdelete(fds);
ERR_FAIL_V_MSG(nullptr, "Error loading HB font.");
}
if (p_outline_size != 0) {
size_cache_outline[id] = fds;
} else {
size_cache[id] = fds;
}
// Write variations.
if (fds->face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS) {
FT_MM_Var *amaster;
FT_Get_MM_Var(fds->face, &amaster);
Vector<hb_variation_t> hb_vars;
Vector<FT_Fixed> coords;
coords.resize(amaster->num_axis);
FT_Get_Var_Design_Coordinates(fds->face, coords.size(), coords.ptrw());
for (FT_UInt i = 0; i < amaster->num_axis; i++) {
hb_variation_t var;
// Reset to default.
var.tag = amaster->axis[i].tag;
var.value = (double)amaster->axis[i].def / 65536.f;
coords.write[i] = amaster->axis[i].def;
if (variations.has(var.tag)) {
var.value = variations[var.tag];
coords.write[i] = CLAMP(variations[var.tag] * 65536.f, amaster->axis[i].minimum, amaster->axis[i].maximum);
}
hb_vars.push_back(var);
}
FT_Set_Var_Design_Coordinates(fds->face, coords.size(), coords.ptrw());
hb_font_set_variations(fds->hb_handle, hb_vars.empty() ? nullptr : &hb_vars[0], hb_vars.size());
FT_Done_MM_Var(library, amaster);
}
}
return fds;
}
Dictionary DynamicFontDataAdvanced::get_variation_list() const {
_THREAD_SAFE_METHOD_
DataAtSize *fds = const_cast<DynamicFontDataAdvanced *>(this)->get_data_for_size(base_size);
if (fds == nullptr) {
return Dictionary();
}
return fds;
Dictionary ret;
// Read variations.
if (fds->face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS) {
FT_MM_Var *amaster;
FT_Get_MM_Var(fds->face, &amaster);
for (FT_UInt i = 0; i < amaster->num_axis; i++) {
ret[(int32_t)amaster->axis[i].tag] = Vector3i(amaster->axis[i].minimum / 65536, amaster->axis[i].maximum / 65536, amaster->axis[i].def / 65536);
}
FT_Done_MM_Var(library, amaster);
}
return ret;
}
void DynamicFontDataAdvanced::set_variation(const String &p_name, double p_value) {
_THREAD_SAFE_METHOD_
int32_t tag = TS->name_to_tag(p_name);
if (!variations.has(tag) || (variations[tag] != p_value)) {
variations[tag] = p_value;
clear_cache();
}
}
double DynamicFontDataAdvanced::get_variation(const String &p_name) const {
_THREAD_SAFE_METHOD_
int32_t tag = TS->name_to_tag(p_name);
if (!variations.has(tag)) {
return 0.f;
}
return variations[tag];
}
Dictionary DynamicFontDataAdvanced::get_feature_list() const {