diff options
author | John-Mark Bell <jmb@netsurf-browser.org> | 2021-08-08 19:21:09 +0100 |
---|---|---|
committer | John-Mark Bell <jmb@netsurf-browser.org> | 2021-08-09 23:59:34 +0100 |
commit | 6f212ee62e6cc19cb686208dd5b510d01217d0af (patch) | |
tree | 5db27677519e85c78c19365cf13e23d0d78e57cd /src/rufl_init.c | |
parent | a0bad0bd03988b9b77969f8b00cc9a512856f7f0 (diff) | |
download | librufl-6f212ee62e6cc19cb686208dd5b510d01217d0af.tar.gz librufl-6f212ee62e6cc19cb686208dd5b510d01217d0af.tar.bz2 |
Merge UCS font scan implementations
The only meaningful difference is how we enumerate the codepoints
represented by a font. Factor this out so that we can share almost
all of the implementation.
Diffstat (limited to 'src/rufl_init.c')
-rw-r--r-- | src/rufl_init.c | 159 |
1 files changed, 27 insertions, 132 deletions
diff --git a/src/rufl_init.c b/src/rufl_init.c index 523158d..7f6a2ac 100644 --- a/src/rufl_init.c +++ b/src/rufl_init.c @@ -35,6 +35,7 @@ unsigned short *rufl_substitution_table = 0; struct rufl_cache_entry rufl_cache[rufl_CACHE_SIZE]; int rufl_cache_time = 0; bool rufl_old_font_manager = false; +static bool rufl_broken_font_enumerate_characters = false; wimp_w rufl_status_w = 0; char rufl_status_buffer[80]; @@ -73,7 +74,6 @@ static rufl_code rufl_init_add_font(const char *identifier, const char *local_name); static int rufl_weight_table_cmp(const void *keyval, const void *datum); static rufl_code rufl_init_scan_font(unsigned int font); -static rufl_code rufl_init_scan_font_no_enumerate(unsigned int font); static bool rufl_is_space(unsigned int u); static rufl_code rufl_init_scan_font_old(unsigned int font_index); static rufl_code rufl_init_scan_font_in_encoding(const char *font_name, @@ -105,7 +105,6 @@ static void rufl_init_status_close(void); rufl_code rufl_init(void) { - bool rufl_broken_font_enumerate_characters = false; unsigned int changes = 0; unsigned int i; int fm_version; @@ -202,8 +201,6 @@ rufl_code rufl_init(void) (float) i / rufl_font_list_entries); if (rufl_old_font_manager) code = rufl_init_scan_font_old(i); - else if (rufl_broken_font_enumerate_characters) - code = rufl_init_scan_font_no_enumerate(i); else code = rufl_init_scan_font(i); if (code != rufl_OK) { @@ -548,37 +545,17 @@ static struct rufl_character_set *rufl_init_shrinkwrap_planes( return charset; } -/** - * Scan a font for available characters. - */ - -rufl_code rufl_init_scan_font(unsigned int font_index) +static rufl_code rufl_init_enumerate_characters(const char *font_name, + font_f font, + rufl_code (*callback)(void *pw, + uint32_t glyph_idx, uint32_t ucs4), + void *pw) { - char font_name[80]; - int x_out, y_out; - unsigned int byte, bit; - unsigned int string[2] = { 0, 0 }; unsigned int u, next; - struct rufl_character_set *planes[17]; - struct rufl_character_set *charset; - font_f font; - font_scan_block block = { { 0, 0 }, { 0, 0 }, -1, { 0, 0, 0, 0 } }; - - /*LOG("font %u \"%s\"", font_index, - rufl_font_list[font_index].identifier);*/ - - for (u = 0; u < 17; u++) - planes[u] = NULL; - - snprintf(font_name, sizeof font_name, "%s\\EUTF8", - rufl_font_list[font_index].identifier); + rufl_code result; - rufl_fm_error = xfont_find_font(font_name, 160, 160, 0, 0, &font, 0, 0); - if (rufl_fm_error) { - LOG("xfont_find_font(\"%s\"): 0x%x: %s", font_name, - rufl_fm_error->errnum, rufl_fm_error->errmess); - return rufl_OK; - } + if (rufl_broken_font_enumerate_characters) + return rufl_init_read_encoding(font, callback, pw); /* Scan through mapped characters */ for (u = 0; u != (unsigned int) -1; u = next) { @@ -592,110 +569,20 @@ rufl_code rufl_init_scan_font(unsigned int font_index) font_name, u, rufl_fm_error->errnum, rufl_fm_error->errmess); - xfont_lose_font(font); - for (u = 0; u < 17; u++) - free(planes[u]); - return rufl_OK; + break; } - /* Skip DELETE and C0/C1 controls */ - if (u < 0x0020 || (0x007f <= u && u <= 0x009f)) - continue; - /* Skip unmapped characters */ if (internal == (unsigned int) -1) continue; - if (u % 0x200 == 0) - rufl_init_status(0, 0); - - /* Character is mapped, let's see if it's really there */ - string[0] = u; - rufl_fm_error = xfont_scan_string(font, (char *) string, - font_RETURN_BBOX | font_GIVEN32_BIT | - font_GIVEN_FONT | font_GIVEN_LENGTH | - font_GIVEN_BLOCK, - 0x7fffffff, 0x7fffffff, - &block, 0, 4, - 0, &x_out, &y_out, 0); - if (rufl_fm_error) + /* Character is mapped, emit it */ + result = callback(pw, internal, u); + if (result != rufl_OK) break; - - if (block.bbox.x0 == 0x20000000) { - /* absent (no definition) */ - } else if (x_out == 0 && y_out == 0 && - block.bbox.x0 == 0 && block.bbox.y0 == 0 && - block.bbox.x1 == 0 && block.bbox.y1 == 0) { - /* absent (empty) */ - } else if (block.bbox.x0 == 0 && block.bbox.y0 == 0 && - block.bbox.x1 == 0 && block.bbox.y1 == 0 && - !rufl_is_space(u)) { - /* absent (space but not a space character - some - * fonts do this) */ - } else { - /* present */ - const unsigned int plane = (u >> 16) & 0x1f; - const unsigned int block = (u >> 8) & 0xff; - - /* Ensure plane exists */ - if (!planes[plane]) { - planes[plane] = rufl_init_alloc_plane(plane); - if (!planes[plane]) { - for (u = 0; u < 17; u++) - free(planes[u]); - xfont_lose_font(font); - return rufl_OUT_OF_MEMORY; - } - } - - /* Allocate block, if it's currently empty */ - if (planes[plane]->index[block] == BLOCK_EMPTY) { - unsigned int last_used = - PLANE_SIZE(planes[plane]->metadata); - if (last_used < BLOCK_EMPTY) { - planes[plane]->index[block] = last_used; - planes[plane]->metadata = - (planes[plane]->metadata & - 0xffff0000) | - (last_used + 1); - } - } - - /* Set bit for codepoint in bitmap, if bitmap exists */ - if (planes[plane]->index[block] < BLOCK_EMPTY) { - byte = (u >> 3) & 31; - bit = u & 7; - planes[plane]->block[ - planes[plane]->index[block] - ][byte] |= 1 << bit; - } - } - } - - xfont_lose_font(font); - - if (rufl_fm_error) { - LOG("xfont_scan_string(\"%s\", U+%x, ...): 0x%x: %s", - font_name, u, - rufl_fm_error->errnum, rufl_fm_error->errmess); - for (u = 0; u < 17; u++) - free(planes[u]); - return rufl_FONT_MANAGER_ERROR; - } - - charset = rufl_init_shrinkwrap_planes(planes); - if (!charset) { - for (u = 0; u < 17; u++) - free(planes[u]); - return rufl_OUT_OF_MEMORY; } - for (u = 0; u < 17; u++) - free(planes[u]); - - rufl_font_list[font_index].charset = charset; - - return rufl_OK; + return result; } static rufl_code find_plane_cb(void *pw, uint32_t glyph_idx, uint32_t ucs4) @@ -704,7 +591,9 @@ static rufl_code find_plane_cb(void *pw, uint32_t glyph_idx, uint32_t ucs4) (void) glyph_idx; - planes[(ucs4 >> 16) & 0x1f] = (struct rufl_character_set *) 1; + /* Skip DELETE and C0/C1 controls */ + if (ucs4 > 0x0020 && (ucs4 < 0x007f || 0x009f < ucs4)) + planes[(ucs4 >> 16) & 0x1f] = (struct rufl_character_set *) 1; return rufl_OK; } @@ -724,6 +613,10 @@ static rufl_code find_glyph_cb(void *pw, uint32_t glyph_idx, uint32_t ucs4) (void) glyph_idx; + /* Skip DELETE and C0/C1 controls */ + if (ucs4 < 0x0020 || (0x007f <= ucs4 && ucs4 <= 0x009f)) + return rufl_OK; + if (ucs4 % 0x200 == 0) rufl_init_status(0, 0); @@ -785,10 +678,10 @@ static rufl_code find_glyph_cb(void *pw, uint32_t glyph_idx, uint32_t ucs4) } /** - * Scan a font for available characters (version without character enumeration) + * Scan a font for available characters */ -rufl_code rufl_init_scan_font_no_enumerate(unsigned int font_index) +rufl_code rufl_init_scan_font(unsigned int font_index) { char font_name[80]; struct rufl_character_set *planes[17]; @@ -815,7 +708,8 @@ rufl_code rufl_init_scan_font_no_enumerate(unsigned int font_index) } /* First pass: find the planes we need */ - rc = rufl_init_read_encoding(font, find_plane_cb, planes); + rc = rufl_init_enumerate_characters(font_name, font, + find_plane_cb, planes); if (rc != rufl_OK) return rc; @@ -838,7 +732,8 @@ rufl_code rufl_init_scan_font_no_enumerate(unsigned int font_index) ctx.font = font; ctx.planes = planes; - rc = rufl_init_read_encoding(font, find_glyph_cb, &ctx); + rc = rufl_init_enumerate_characters(font_name, font, + find_glyph_cb, &ctx); if (rc != rufl_OK) { for (plane = 0; plane < 17; plane++) free(planes[plane]); |