diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh index e66461529..9ebd8e417 100644 --- a/src/hb-ot-cmap-table.hh +++ b/src/hb-ot-cmap-table.hh @@ -342,14 +342,22 @@ struct CmapSubtableFormat4 count--; /* Skip sentinel segment. */ for (unsigned int i = 0; i < count; i++) { + hb_codepoint_t start = this->startCount[i]; + hb_codepoint_t end = this->endCount[i]; unsigned int rangeOffset = this->idRangeOffset[i]; if (rangeOffset == 0) - out->add_range (this->startCount[i], this->endCount[i]); + { + for (hb_codepoint_t codepoint = start; codepoint <= end; codepoint++) + { + hb_codepoint_t gid = (codepoint + this->idDelta[i]) & 0xFFFFu; + if (unlikely (!gid)) + continue; + out->add (codepoint); + } + } else { - for (hb_codepoint_t codepoint = this->startCount[i]; - codepoint <= this->endCount[i]; - codepoint++) + for (hb_codepoint_t codepoint = start; codepoint <= end; codepoint++) { unsigned int index = rangeOffset / 2 + (codepoint - this->startCount[i]) + i - this->segCount; if (unlikely (index >= this->glyphIdArrayLength)) @@ -522,10 +530,18 @@ struct CmapSubtableLongSegmented void collect_unicodes (hb_set_t *out) const { - for (unsigned int i = 0; i < this->groups.len; i++) { - out->add_range (this->groups[i].startCharCode, - hb_min ((hb_codepoint_t) this->groups[i].endCharCode, - (hb_codepoint_t) HB_UNICODE_MAX)); + for (unsigned int i = 0; i < this->groups.len; i++) + { + hb_codepoint_t start = this->groups[i].startCharCode; + hb_codepoint_t end = hb_min ((hb_codepoint_t) this->groups[i].endCharCode, + (hb_codepoint_t) HB_UNICODE_MAX); + for (hb_codepoint_t codepoint = start; codepoint <= end; codepoint++) + { + hb_codepoint_t gid = T::group_get_glyph (this->groups[i], codepoint); + if (unlikely (!gid)) + continue; + out->add (codepoint); + } } } diff --git a/test/api/fonts/cmunrm.otf b/test/api/fonts/cmunrm.otf new file mode 100644 index 000000000..b449df04c Binary files /dev/null and b/test/api/fonts/cmunrm.otf differ diff --git a/test/api/test-collect-unicodes.c b/test/api/test-collect-unicodes.c index 50965a902..8a857e1c0 100644 --- a/test/api/test-collect-unicodes.c +++ b/test/api/test-collect-unicodes.c @@ -49,6 +49,27 @@ test_collect_unicodes_format4 (void) hb_face_destroy (face); } +static void +test_collect_unicodes_format12_notdef (void) +{ + hb_face_t *face = hb_test_open_font_file ("fonts/cmunrm.otf"); + hb_set_t *codepoints = hb_set_create(); + hb_codepoint_t cp; + + hb_face_collect_unicodes (face, codepoints); + + cp = HB_SET_VALUE_INVALID; + g_assert (hb_set_next (codepoints, &cp)); + g_assert_cmpuint (0x20, ==, cp); + g_assert (hb_set_next (codepoints, &cp)); + g_assert_cmpuint (0x21, ==, cp); + g_assert (hb_set_next (codepoints, &cp)); + g_assert_cmpuint (0x22, ==, cp); + + hb_set_destroy (codepoints); + hb_face_destroy (face); +} + static void test_collect_unicodes_format12 (void) { @@ -101,6 +122,7 @@ main (int argc, char **argv) hb_test_add (test_collect_unicodes); hb_test_add (test_collect_unicodes_format4); hb_test_add (test_collect_unicodes_format12); + hb_test_add (test_collect_unicodes_format12_notdef); return hb_test_run(); }