summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn-Mark Bell <jmb@netsurf-browser.org>2021-08-14 00:01:05 +0100
committerJohn-Mark Bell <jmb@netsurf-browser.org>2021-08-14 01:33:23 +0100
commit7455528fedc1d6a03ba693307c441ffddcc3c164 (patch)
tree3c93db9ece9e1d112b0fe5068d799d398ca9c900
parentc69d7fee4ef1820296cb1c0db072e01cf6970ce1 (diff)
downloadlibrufl-7455528fedc1d6a03ba693307c441ffddcc3c164.tar.gz
librufl-7455528fedc1d6a03ba693307c441ffddcc3c164.tar.bz2
Fix initialisation on UCS Font Manager 3.41-3.63
We cannot use Font_ReadEncodingFile to find the path to a font's source encoding because that is not what the API returns (it returns the path to the encoding file corresponding to the target encoding used to open the font handle) and there is no public API for obtaining the path of the source encoding. Additionally, there is no reliable way to replicate the UCS Font Manager's mapping of undefined and duplicate glyph names into the private use space at U+E000-U+EFFF. Therefore, take a different approach to supporting these versions of the Font Manager: abuse Font_EnumerateCharacters by probing every codepoint in the range [0, first_returned) to force the Font Manager to reveal the information we want. Once we have reached the first_returned codepoint, we can happily fall through to the normal flow (which will make use of the sparse nature of the Unicode space).
-rw-r--r--src/rufl_init.c63
1 files changed, 50 insertions, 13 deletions
diff --git a/src/rufl_init.c b/src/rufl_init.c
index 29ef415..cf85980 100644
--- a/src/rufl_init.c
+++ b/src/rufl_init.c
@@ -543,16 +543,56 @@ static rufl_code rufl_init_enumerate_characters(const char *font_name,
uint32_t glyph_idx, uint32_t ucs4),
void *pw)
{
- unsigned int u, next;
- rufl_code result;
+ unsigned int u = 0, next, internal;
+ rufl_code result = rufl_OK;
- if (rufl_broken_font_enumerate_characters)
- return rufl_init_read_encoding(font, callback, pw);
+ if (rufl_broken_font_enumerate_characters) {
+ /* We know that any codepoints in the first chunk will
+ * be missed because Font_EnumerateCharacters is broken
+ * on this version of the Font Manager. Find the first
+ * codepoint it will report. */
+ unsigned int first;
+ rufl_fm_error = xfont_enumerate_characters(font, 0,
+ (int *) &first, (int *) &internal);
+ if (rufl_fm_error) {
+ LOG("xfont_enumerate_characters(\"%s\", "
+ "U+%x, ...): 0x%x: %s",
+ font_name, 0,
+ rufl_fm_error->errnum,
+ rufl_fm_error->errmess);
+ return rufl_FONT_MANAGER_ERROR;
+ }
- /* Scan through mapped characters */
- for (u = 0; u != (unsigned int) -1; u = next) {
- unsigned int internal;
+ /* Search the entire space up to the first codepoint it
+ * reported. */
+ for (u = 0; u != (unsigned int) -1 && u != first; u++) {
+ rufl_fm_error = xfont_enumerate_characters(font, u,
+ (int *) &next, (int *) &internal);
+ if (rufl_fm_error) {
+ LOG("xfont_enumerate_characters(\"%s\", "
+ "U+%x, ...): 0x%x: %s",
+ font_name, u,
+ rufl_fm_error->errnum,
+ rufl_fm_error->errmess);
+ result = rufl_FONT_MANAGER_ERROR;
+ break;
+ }
+
+ /* Skip unmapped characters */
+ if (internal == (unsigned int) -1)
+ continue;
+
+ /* Character is mapped, emit it */
+ result = callback(pw, internal, u);
+ if (result != rufl_OK)
+ break;
+ }
+ /* Now fall through to the normal path */
+ }
+
+ /* Scan through mapped characters */
+ for (; u != (unsigned int) -1; u = next) {
rufl_fm_error = xfont_enumerate_characters(font, u,
(int *) &next, (int *) &internal);
if (rufl_fm_error) {
@@ -561,6 +601,7 @@ static rufl_code rufl_init_enumerate_characters(const char *font_name,
font_name, u,
rufl_fm_error->errnum,
rufl_fm_error->errmess);
+ result = rufl_FONT_MANAGER_ERROR;
break;
}
@@ -1225,13 +1266,9 @@ rufl_code rufl_init_read_encoding(font_f font,
}
fp = fopen(filename, "r");
- if (!fp) {
+ if (!fp && rufl_old_font_manager) {
/* many "symbol" fonts have no encoding file */
- const char *default_path =
- "Resources:$.Fonts.Encodings./Default";
- if (rufl_old_font_manager)
- default_path = "Resources:$.Fonts.Encodings.Latin1";
- fp = fopen(default_path, "r");
+ fp = fopen("Resources:$.Fonts.Encodings.Latin1", "r");
}
if (!fp)
return rufl_IO_ERROR;