I have set of libraries: fontconfig, freetype, harfbuzz. Is it possible to get scripts list supported by the font?
The task is to create a map of fonts for different unicode scripts.
HarfBuzz, for example, has enum that contains scripts. But I don't understand, is it possible to extract this info from hb_font_t
or hb_face_t
.
Or maybe it's possible to get this info from fontconfig or freetype?
I have set of libraries: fontconfig, freetype, harfbuzz. Is it possible to get scripts list supported by the font?
The task is to create a map of fonts for different unicode scripts.
HarfBuzz, for example, has enum that contains scripts. But I don't understand, is it possible to extract this info from hb_font_t
or hb_face_t
.
Or maybe it's possible to get this info from fontconfig or freetype?
Share Improve this question edited Jan 29 at 14:23 John Kugelman 363k69 gold badges553 silver badges597 bronze badges asked Jan 29 at 14:22 andre487andre487 1,4092 gold badges19 silver badges30 bronze badges 5- 1 With FreeType2 you can enumerate the valid character codes yourself as per "How to get a list of code points supported by a true type font with Freetype2 in C++". Haven't proposed that as a dupe though as I'm not sure if it's exactly what you're looking for. – G.M. Commented Jan 29 at 18:06
- G.M. — Right, that makes sense, but I don't think that “to get Unicode scripts supported by font” makes a whole lot of sense. Script is just one of the properties of a character. There is no one-to-one correspondence between scripts and code blocks. A block can contain a script, but a script can be covered by more than one block. A script is more of a cultural characteristic, a common property of a set of characters. A font family can implement only a subset of a script. So, I'm not sure the inquirer needs to know font family scripts. – Sergey A Kryukov Commented Jan 29 at 20:48
- Is it correct that font file doesn't contain information about scripts? So, it's possible to investigate this property by analyzing separate codes only? Or maybe it contains some info at least about code ranges? – andre487 Commented Jan 30 at 4:47
- A few possible approaches depending on the type of font: 1) determine codepoint coverage of font glyphs and compare to characters required by each script.2) look at the ScriptRecord in the GPOS and GSUB tables. 3) Info you need may be in the font's language system table – Andj Commented Jan 31 at 1:35
- @Andj It looks perspective. Is it possible to access these data from HarfBuzz, fontconfig or freetype? – andre487 Commented Feb 4 at 11:48
1 Answer
Reset to default 0It's possible, but is't very comfortable. I have found this solution:
#include <hb.h>
#include <magic-deps.h>
struct TInstalledFont {
std::string FilePath{};
int FaceIndex{};
std::shared_ptr<hb_face_t> HbFontFace{nullptr};
std::unordered_set<char32_t> Unicodes{};
std::unordered_set<int> HbScripts{};
};
const auto hbUniFuncs = hb_unicode_funcs_get_default();
for (TInstalledFont& font : Fonts) {
auto blob = hb_blob_create_from_file(font.FilePath.c_str());
if (!blob) {
throw std::runtime_error("Failed to load font");
}
DEFER(&blob) {
hb_blob_destroy(blob);
};
const auto face = hb_face_create(blob, font.FaceIndex);
if (!face) {
throw std::runtime_error("Failed to load face");
}
hb_face_make_immutable(face);
font.HbFontFace = std::shared_ptr<hb_face_t>(face, hb_face_destroy);
auto unicodes = hb_set_create();
DEFER(&unicodes) {
hb_set_destroy(unicodes);
};
hb_face_collect_unicodes(face, unicodes);
hb_codepoint_t val{};
while (hb_set_next(unicodes, &val)) {
font.Unicodes.insert(val);
const hb_script_t tagScript = hb_unicode_script(hbUniFuncs, val);
// int because hb_script_t doesn't support hashing
font.HbScripts.insert(static_cast<int>(tagScript));
}
}
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745292386a4620939.html
评论列表(0条)