From efbba7ad26dda5930f5d1bd5292304835432f504 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 17 Apr 2019 11:00:08 -0400 Subject: [PATCH 01/69] [serializer] Add copy() Calls obj.copy() or obj.operator=() in that order. --- src/hb-serialize.hh | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 0d908bd13..a8fd8d32e 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -358,6 +358,24 @@ struct hb_serialize_context_t memcpy (ret, &obj, size); return ret; } + + template auto + _copy (const Type &obj, hb_priority<1>) const HB_RETURN (Type *, obj.copy (this)) + + template auto + _copy (const Type &obj, hb_priority<0>) const -> decltype (&(obj = obj)) + { + Type *ret = this->allocate_size (sizeof (Type)); + if (unlikely (!ret)) return nullptr; + *ret = obj; + return ret; + } + + /* Like embed, but active: calls obj.operator=() or obj.copy() to transfer data + * instead of memcpy(). */ + template + Type *copy (const Type &obj) { return _copy (obj, hb_prioritize); } + template hb_serialize_context_t &operator << (const Type &obj) { embed (obj); return *this; } From db0c9a1485ae6ca7ca9af38a43504f1ae4ea09c8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 17 Apr 2019 17:58:13 -0400 Subject: [PATCH 02/69] [subset] Assert offsets are zero during relocation If they're not, it's a bug in our subsetting logic somewhere. So check. --- src/hb-serialize.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index a8fd8d32e..971359f40 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -294,12 +294,14 @@ struct hb_serialize_context_t if (link.is_wide) { auto &off = * ((BEInt *) (parent.head + link.position)); + assert (0 == off); off = offset; propagate_error (off == offset); } else { auto &off = * ((BEInt *) (parent.head + link.position)); + assert (0 == off); off = offset; propagate_error (off == offset); } From 693d91cd49fda3e728b59e6885bea8d7b01958ef Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 17 Apr 2019 17:59:39 -0400 Subject: [PATCH 03/69] [serialize] Fix offset calculation --- src/hb-serialize.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 971359f40..311eacfe4 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -272,7 +272,7 @@ struct hb_serialize_context_t auto& link = *current->links.push (); link.is_wide = sizeof (T) == 4; - link.position = (const char *) &ofs - (const char *) base; + link.position = (const char *) &ofs - current->head; link.bias = (const char *) base - current->head; link.objidx = objidx; } From 91d958acc08cb99ddd3b656922e13497b9d1595d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 18 Apr 2019 10:04:10 -0400 Subject: [PATCH 04/69] [array] Simplify copy assignment/constructor To fix bogus MSVC warnings: c:\projects\harfbuzz\src\hb-array.hh(189): warning C4521: 'hb_array_t': multiple copy constructors specified [C:\projects\harfbuzz\build\harfbuzz.vcxproj] c:\projects\harfbuzz\src\hb-array.hh(189): warning C4522: 'hb_array_t': multiple assignment operators specified [C:\projects\harfbuzz\build\harfbuzz.vcxproj] --- src/hb-array.hh | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/hb-array.hh b/src/hb-array.hh index 74b6757b2..ee34dd54d 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -43,20 +43,29 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> * Constructors. */ hb_array_t () : arrayZ (nullptr), length (0) {} - hb_array_t (const hb_array_t &o) : - hb_iter_with_fallback_t, Type&> (), - arrayZ (o.arrayZ), length (o.length) {} - template - hb_array_t (const hb_array_t > &o) : arrayZ (o.arrayZ), length (o.length) {} - hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {} template hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_) {} - template - hb_array_t& operator = (const hb_array_t > &o) - { arrayZ = o.arrayZ; length = o.length; return *this; } - hb_array_t& operator = (const hb_array_t &o) + template , U) || + hb_is_same (Type, hb_remove_reference) || + hb_is_same (hb_remove_const, hb_remove_reference) + )> + hb_array_t (const hb_array_t &o) : + hb_iter_with_fallback_t, Type&> (), + arrayZ (o.arrayZ), length (o.length) {} + template , U) || + hb_is_same (Type, hb_remove_reference) || + hb_is_same (hb_remove_const, hb_remove_reference) + )> + hb_array_t& operator = (const hb_array_t &o) { arrayZ = o.arrayZ; length = o.length; return *this; } + /* * Iterator implementation. */ From 518e6e07f29d9bb7e532313fb0af6177d8022ea5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 18 Apr 2019 12:21:25 -0400 Subject: [PATCH 05/69] Minor --- src/hb-ot-map.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc index ef0bcc716..b943d8493 100644 --- a/src/hb-ot-map.cc +++ b/src/hb-ot-map.cc @@ -219,7 +219,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, continue; /* Feature disabled, or not enough bits. */ - hb_bool_t found = false; + bool found = false; unsigned int feature_index[2]; for (unsigned int table_index = 0; table_index < 2; table_index++) { From dd4c37529bcecee33d43015a852a3fcf9e978b7f Mon Sep 17 00:00:00 2001 From: Michiharu Ariza Date: Thu, 18 Apr 2019 10:38:57 -0700 Subject: [PATCH 06/69] silence MVC warnings --- src/hb-cff-interp-common.hh | 2 +- src/hb-ot-cff1-table.cc | 4 ++-- src/hb-ot-cff2-table.cc | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hb-cff-interp-common.hh b/src/hb-cff-interp-common.hh index 78ef997b1..c5157c783 100644 --- a/src/hb-cff-interp-common.hh +++ b/src/hb-cff-interp-common.hh @@ -691,7 +691,7 @@ struct opset_t case OpCode_TwoByteNegInt0: case OpCode_TwoByteNegInt1: case OpCode_TwoByteNegInt2: case OpCode_TwoByteNegInt3: - env.argStack.push_int ((int16_t)(-(op - OpCode_TwoByteNegInt0) * 256 - env.str_ref[0] - 108)); + env.argStack.push_int ((-(int16_t)(op - OpCode_TwoByteNegInt0) * 256 - env.str_ref[0] - 108)); env.str_ref.inc (); break; diff --git a/src/hb-ot-cff1-table.cc b/src/hb-ot-cff1-table.cc index 8773c05a2..f62b80e3c 100644 --- a/src/hb-ot-cff1-table.cc +++ b/src/hb-ot-cff1-table.cc @@ -165,8 +165,8 @@ struct bounds_t { void init () { - min.set_int (0x7FFFFFFF, 0x7FFFFFFF); - max.set_int (-0x80000000, -0x80000000); + min.set_int ((1<<31)-1, (1<<31)-1); + max.set_int (-(1<<31), -(1<<31)); } void update (const point_t &pt) diff --git a/src/hb-ot-cff2-table.cc b/src/hb-ot-cff2-table.cc index 7daa53656..11619d779 100644 --- a/src/hb-ot-cff2-table.cc +++ b/src/hb-ot-cff2-table.cc @@ -34,10 +34,10 @@ struct extents_param_t void init () { path_open = false; - min_x.set_int (0x7FFFFFFF); - min_y.set_int (0x7FFFFFFF); - max_x.set_int (-0x80000000); - max_y.set_int (-0x80000000); + min_x.set_int ((1<<31)-1); + min_y.set_int ((1<<31)-1); + max_x.set_int (-(1<<31)); + max_y.set_int (-(1<<31)); } void start_path () { path_open = true; } From 705dde57fe7bd5aafe93f284db2aa809aad932dc Mon Sep 17 00:00:00 2001 From: Michiharu Ariza Date: Thu, 18 Apr 2019 11:32:10 -0700 Subject: [PATCH 07/69] silence MVC warnings 2nd attempt --- src/hb-ot-cff1-table.cc | 4 ++-- src/hb-ot-cff2-table.cc | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hb-ot-cff1-table.cc b/src/hb-ot-cff1-table.cc index f62b80e3c..3b5e5947b 100644 --- a/src/hb-ot-cff1-table.cc +++ b/src/hb-ot-cff1-table.cc @@ -165,8 +165,8 @@ struct bounds_t { void init () { - min.set_int ((1<<31)-1, (1<<31)-1); - max.set_int (-(1<<31), -(1<<31)); + min.set_int (2147483647, 2147483647); + max.set_int (-2147483648, -2147483648); } void update (const point_t &pt) diff --git a/src/hb-ot-cff2-table.cc b/src/hb-ot-cff2-table.cc index 11619d779..0f8a16df8 100644 --- a/src/hb-ot-cff2-table.cc +++ b/src/hb-ot-cff2-table.cc @@ -34,10 +34,10 @@ struct extents_param_t void init () { path_open = false; - min_x.set_int ((1<<31)-1); - min_y.set_int ((1<<31)-1); - max_x.set_int (-(1<<31)); - max_y.set_int (-(1<<31)); + min_x.set_int (2147483647); + min_y.set_int (2147483647); + max_x.set_int (-2147483648); + max_y.set_int (-2147483648); } void start_path () { path_open = true; } From 63a2108480cca2d9c1a2f61d6642d70496f1a5e3 Mon Sep 17 00:00:00 2001 From: Michiharu Ariza Date: Thu, 18 Apr 2019 13:54:58 -0700 Subject: [PATCH 08/69] silence MVC warnings 3rd attempt --- src/hb-ot-cff1-table.cc | 5 +++-- src/hb-ot-cff2-table.cc | 9 +++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/hb-ot-cff1-table.cc b/src/hb-ot-cff1-table.cc index 3b5e5947b..5132801bf 100644 --- a/src/hb-ot-cff1-table.cc +++ b/src/hb-ot-cff1-table.cc @@ -26,6 +26,7 @@ #include "hb-ot-cff1-table.hh" #include "hb-cff1-interp-cs.hh" +#include using namespace CFF; @@ -165,8 +166,8 @@ struct bounds_t { void init () { - min.set_int (2147483647, 2147483647); - max.set_int (-2147483648, -2147483648); + min.set_int (INT_MAX, INT_MAX); + max.set_int (INT_MIN, INT_MIN); } void update (const point_t &pt) diff --git a/src/hb-ot-cff2-table.cc b/src/hb-ot-cff2-table.cc index 0f8a16df8..15cdbaa85 100644 --- a/src/hb-ot-cff2-table.cc +++ b/src/hb-ot-cff2-table.cc @@ -26,6 +26,7 @@ #include "hb-ot-cff2-table.hh" #include "hb-cff2-interp-cs.hh" +#include using namespace CFF; @@ -34,10 +35,10 @@ struct extents_param_t void init () { path_open = false; - min_x.set_int (2147483647); - min_y.set_int (2147483647); - max_x.set_int (-2147483648); - max_y.set_int (-2147483648); + min_x.set_int (INT_MAX); + min_y.set_int (INT_MAX); + max_x.set_int (INT_MIN); + max_y.set_int (INT_MIN); } void start_path () { path_open = true; } From ba0386060d92dffcde2d14f9e523a46ea8713de2 Mon Sep 17 00:00:00 2001 From: Michiharu Ariza Date: Thu, 18 Apr 2019 14:53:35 -0700 Subject: [PATCH 09/69] fix oss-fuzz issue 14345 --- src/hb-ot-cff1-table.hh | 3 ++- ...-minimized-hb-subset-fuzzer-5923632099885056 | Bin 0 -> 25847 bytes 2 files changed, 2 insertions(+), 1 deletion(-) create mode 100644 test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5923632099885056 diff --git a/src/hb-ot-cff1-table.hh b/src/hb-ot-cff1-table.hh index 7fbda905e..51cc84694 100644 --- a/src/hb-ot-cff1-table.hh +++ b/src/hb-ot-cff1-table.hh @@ -110,7 +110,8 @@ struct Encoding1 { { if (glyph <= ranges[i].nLeft) { - return (hb_codepoint_t)ranges[i].first + glyph; + hb_codepoint_t code = (hb_codepoint_t)ranges[i].first + glyph; + return (likely (code < 0x100)? code: CFF_UNDEF_CODE); } glyph -= (ranges[i].nLeft + 1); } diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5923632099885056 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5923632099885056 new file mode 100644 index 0000000000000000000000000000000000000000..0a3c6df0ee0073d24d708bbc70d4d8acbba3a354 GIT binary patch literal 25847 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 Date: Thu, 18 Apr 2019 15:17:10 -0700 Subject: [PATCH 10/69] add spaces --- src/hb-ot-cff1-table.hh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hb-ot-cff1-table.hh b/src/hb-ot-cff1-table.hh index 51cc84694..f7ec00c34 100644 --- a/src/hb-ot-cff1-table.hh +++ b/src/hb-ot-cff1-table.hh @@ -110,8 +110,8 @@ struct Encoding1 { { if (glyph <= ranges[i].nLeft) { - hb_codepoint_t code = (hb_codepoint_t)ranges[i].first + glyph; - return (likely (code < 0x100)? code: CFF_UNDEF_CODE); + hb_codepoint_t code = (hb_codepoint_t) ranges[i].first + glyph; + return (likely (code < 0x100) ? code: CFF_UNDEF_CODE); } glyph -= (ranges[i].nLeft + 1); } From 42f4bd6b801f96fc33a365db8ab6390e74cef05a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 18 Apr 2019 19:04:59 -0400 Subject: [PATCH 11/69] Minor warning fix again --- src/hb-ot-map.cc | 20 ++++++++++---------- test/api/test-ot-face.c | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/hb-ot-map.cc b/src/hb-ot-map.cc index b943d8493..846414c9b 100644 --- a/src/hb-ot-map.cc +++ b/src/hb-ot-map.cc @@ -226,21 +226,21 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m, if (required_feature_tag[table_index] == info->tag) required_feature_stage[table_index] = info->stage[table_index]; - found |= hb_ot_layout_language_find_feature (face, - table_tags[table_index], - script_index[table_index], - language_index[table_index], - info->tag, - &feature_index[table_index]); + found |= (bool) hb_ot_layout_language_find_feature (face, + table_tags[table_index], + script_index[table_index], + language_index[table_index], + info->tag, + &feature_index[table_index]); } if (!found && (info->flags & F_GLOBAL_SEARCH)) { for (unsigned int table_index = 0; table_index < 2; table_index++) { - found |= hb_ot_layout_table_find_feature (face, - table_tags[table_index], - info->tag, - &feature_index[table_index]); + found |= (bool) hb_ot_layout_table_find_feature (face, + table_tags[table_index], + info->tag, + &feature_index[table_index]); } } if (!found && !(info->flags & F_HAS_FALLBACK)) diff --git a/test/api/test-ot-face.c b/test/api/test-ot-face.c index 9ebcb4e2b..12ac666a4 100644 --- a/test/api/test-ot-face.c +++ b/test/api/test-ot-face.c @@ -111,7 +111,7 @@ test_ot_face_empty (void) } static void -test_ot_var_axis_on_zero_named_instance () +test_ot_var_axis_on_zero_named_instance (void) { hb_face_t *face = hb_test_open_font_file ("fonts/Zycon.ttf"); g_assert (hb_ot_var_get_axis_count (face)); From 694cb1beeefe1c54b2e613d2d566a21e248a2c9c Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Fri, 19 Apr 2019 07:51:04 -0700 Subject: [PATCH 12/69] Add harfbuzzjs build configuration (#1636) --- CMakeLists.txt | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index f64f96d1c..b3133942b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,10 @@ if (HB_CHECK) endif () endif () +# https://github.com/harfbuzz/harfbuzzjs/ +# emcmake cmake -Bwasmbuild -H. -GNinja -DHB_HARFBUZZJS=1 && ninja -Cwasmbuild +option(HB_HARFBUZZJS "Enable our opinionated harfbuzzjs related build optimization" OFF) + include_directories(AFTER ${PROJECT_SOURCE_DIR}/src ${PROJECT_BINARY_DIR}/src @@ -295,6 +299,16 @@ if (HB_HAVE_GRAPHITE2) mark_as_advanced(GRAPHITE2_INCLUDE_DIR GRAPHITE2_LIBRARY) endif () +if (HB_HARFBUZZJS) + # we won't need multithread support in harfbuzzjs + add_definitions(-DHB_NO_MT) + + add_definitions(-DHB_NO_OPTIONS -DHB_NO_OT_FONT_CFF -DHB_NO_NAME_TABLE_AAT + -DHB_NO_OT_FONT_BITMAP -DHB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK + -DHB_NO_OT_SHAPE_FALLBACK -DHB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK + -DHB_NO_OT_LAYOUT_BLACKLIST -DHB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS) +endif () + if (HB_BUILTIN_UCDN) include_directories(src/hb-ucdn) add_definitions(-DHAVE_UCDN) @@ -538,6 +552,27 @@ endif () add_library(harfbuzz ${project_sources} ${project_extra_sources} ${project_headers}) target_link_libraries(harfbuzz ${THIRD_PARTY_LIBS}) +if (HB_HARFBUZZJS) + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -s MODULARIZE=1 \ + -s NO_FILESYSTEM=1 -s ALLOW_MEMORY_GROWTH=1 -s NO_EXIT_RUNTIME=1 -s STRICT=1 \ + -Oz --closure 1") + + # add_definitions("-DHB_EXTERN=__attribute__((used))") + # Alternatively, only the needed calls + set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s \"EXPORTED_FUNCTIONS=['_hb_version_string', \ + '_malloc', '_hb_blob_create', '_hb_face_create', '_hb_font_create', \ + '_hb_buffer_create', '_hb_buffer_add_utf8', '_hb_buffer_guess_segment_properties', \ + '_hb_buffer_set_direction', '_hb_shape', '_hb_buffer_serialize_glyphs', \ + '_hb_buffer_get_length', '_hb_buffer_serialize_glyphs', '_hb_buffer_destroy', \ + '_hb_font_destroy', '_hb_face_destroy', '_hb_blob_destroy', '_hb_blob_get_length', \ + '_hb_direction_from_string', '_free']\"") + + # Trick emscripten to create js/wasm from a library + add_executable(harfbuzzjs /dev/null) + + target_link_libraries(harfbuzzjs harfbuzz) +endif () + ## Define harfbuzz-subset library if (HB_BUILD_SUBSET) add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers}) From a464cbeecea73aeaa03c262f49fed8584057d9bb Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Fri, 19 Apr 2019 12:14:09 -0700 Subject: [PATCH 13/69] Revert "Add harfbuzzjs build configuration (#1636)" (#1675) This reverts commit 694cb1beeefe1c54b2e613d2d566a21e248a2c9c. --- CMakeLists.txt | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b3133942b..f64f96d1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,10 +85,6 @@ if (HB_CHECK) endif () endif () -# https://github.com/harfbuzz/harfbuzzjs/ -# emcmake cmake -Bwasmbuild -H. -GNinja -DHB_HARFBUZZJS=1 && ninja -Cwasmbuild -option(HB_HARFBUZZJS "Enable our opinionated harfbuzzjs related build optimization" OFF) - include_directories(AFTER ${PROJECT_SOURCE_DIR}/src ${PROJECT_BINARY_DIR}/src @@ -299,16 +295,6 @@ if (HB_HAVE_GRAPHITE2) mark_as_advanced(GRAPHITE2_INCLUDE_DIR GRAPHITE2_LIBRARY) endif () -if (HB_HARFBUZZJS) - # we won't need multithread support in harfbuzzjs - add_definitions(-DHB_NO_MT) - - add_definitions(-DHB_NO_OPTIONS -DHB_NO_OT_FONT_CFF -DHB_NO_NAME_TABLE_AAT - -DHB_NO_OT_FONT_BITMAP -DHB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK - -DHB_NO_OT_SHAPE_FALLBACK -DHB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK - -DHB_NO_OT_LAYOUT_BLACKLIST -DHB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS) -endif () - if (HB_BUILTIN_UCDN) include_directories(src/hb-ucdn) add_definitions(-DHAVE_UCDN) @@ -552,27 +538,6 @@ endif () add_library(harfbuzz ${project_sources} ${project_extra_sources} ${project_headers}) target_link_libraries(harfbuzz ${THIRD_PARTY_LIBS}) -if (HB_HARFBUZZJS) - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -s MODULARIZE=1 \ - -s NO_FILESYSTEM=1 -s ALLOW_MEMORY_GROWTH=1 -s NO_EXIT_RUNTIME=1 -s STRICT=1 \ - -Oz --closure 1") - - # add_definitions("-DHB_EXTERN=__attribute__((used))") - # Alternatively, only the needed calls - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -s \"EXPORTED_FUNCTIONS=['_hb_version_string', \ - '_malloc', '_hb_blob_create', '_hb_face_create', '_hb_font_create', \ - '_hb_buffer_create', '_hb_buffer_add_utf8', '_hb_buffer_guess_segment_properties', \ - '_hb_buffer_set_direction', '_hb_shape', '_hb_buffer_serialize_glyphs', \ - '_hb_buffer_get_length', '_hb_buffer_serialize_glyphs', '_hb_buffer_destroy', \ - '_hb_font_destroy', '_hb_face_destroy', '_hb_blob_destroy', '_hb_blob_get_length', \ - '_hb_direction_from_string', '_free']\"") - - # Trick emscripten to create js/wasm from a library - add_executable(harfbuzzjs /dev/null) - - target_link_libraries(harfbuzzjs harfbuzz) -endif () - ## Define harfbuzz-subset library if (HB_BUILD_SUBSET) add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers}) From 8ed7655be89c658219ab702e34a79734ba0efb73 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 21 Apr 2019 12:25:19 -0400 Subject: [PATCH 14/69] Update AUTHORS / COPYING --- AUTHORS | 3 +++ COPYING | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 0763761bb..83c0c66f9 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,11 +1,14 @@ Behdad Esfahbod +David Corbett David Turner Ebrahim Byagowi +Garret Rieger Jonathan Kew Khaled Hosny Lars Knoll Martin Hosken Owen Taylor +Roderick Sheeter Roozbeh Pournader Simon Hausmann Werner Lemberg diff --git a/COPYING b/COPYING index 9d1056f40..0278e60a5 100644 --- a/COPYING +++ b/COPYING @@ -2,7 +2,8 @@ HarfBuzz is licensed under the so-called "Old MIT" license. Details follow. For parts of HarfBuzz that are licensed under different licenses see individual files names COPYING in subdirectories where applicable. -Copyright © 2010,2011,2012 Google, Inc. +Copyright © 2010,2011,2012,2013,2014,2015,2016,2017,2018,2019 Google, Inc. +Copyright © 2019 Facebook, Inc. Copyright © 2012 Mozilla Foundation Copyright © 2011 Codethink Limited Copyright © 2008,2010 Nokia Corporation and/or its subsidiary(-ies) From ecac94ca763e80d217ba5db429745e8882b38464 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sun, 21 Apr 2019 12:27:32 -0400 Subject: [PATCH 15/69] [docs] Remove fdo repo Has not been updated. --- docs/harfbuzz-docs.xml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/docs/harfbuzz-docs.xml b/docs/harfbuzz-docs.xml index f4ad134ea..e48d17593 100644 --- a/docs/harfbuzz-docs.xml +++ b/docs/harfbuzz-docs.xml @@ -20,11 +20,7 @@ The canonical source-code tree is available at - github.com/harfbuzz/harfbuzz - and is also available at - cgit.freedesktop.org/harfbuzz. + github.com/harfbuzz/harfbuzz. See for release tarballs. From 9bab398462fa598047f34fd6d23e07a91305b1b3 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 22 Apr 2019 15:16:35 -0400 Subject: [PATCH 16/69] Simplify propagate_error() --- src/hb-serialize.hh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 311eacfe4..612a26a1e 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -120,12 +120,12 @@ struct hb_serialize_context_t this->packed.push (nullptr); } - bool propagate_error (bool e) - { return this->successful = this->successful && e; } - template bool propagate_error (const T &obj) - { return this->successful = this->successful && !obj.in_error (); } - template bool propagate_error (const T *obj) - { return this->successful = this->successful && !obj->in_error (); } + bool propagate_error (bool success) + { return this->successful = this->successful && success; } + + template bool propagate_error (T &&obj) + { return propagate_error (!hb_deref_pointer (obj).in_error ()); } + template bool propagate_error (T1 &&o1, T2 &&o2) { return propagate_error (o1) && propagate_error (o2); } template From 24da1d08603a7fe262ae88d687986efc0343956f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 22 Apr 2019 15:20:25 -0400 Subject: [PATCH 17/69] Use variadic template args for propagate_error() Let's see if bots happy. Not sure where else we can use these. Mm. Maybe in hb_invoke(). --- src/hb-serialize.hh | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 612a26a1e..12b615349 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -126,11 +126,8 @@ struct hb_serialize_context_t template bool propagate_error (T &&obj) { return propagate_error (!hb_deref_pointer (obj).in_error ()); } - template bool propagate_error (T1 &&o1, T2 &&o2) - { return propagate_error (o1) && propagate_error (o2); } - template - bool propagate_error (T1 &&o1, T2 &&o2, T3 &&o3) - { return propagate_error (o1) && propagate_error (o2, o3); } + template bool propagate_error (T1 &&o1, Ts &&...os) + { return propagate_error (o1) && propagate_error (os...); } /* To be called around main operation. */ template From ae8da4b61b4cc3b55242b85fe7c63393d65bd6cf Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 22 Apr 2019 15:25:11 -0400 Subject: [PATCH 18/69] Minor --- src/hb-iter.hh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index a4ffbd6f0..46d6c406b 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -209,13 +209,16 @@ template struct hb_is_iterable { private: + template - static auto test (int) -> decltype (hb_declval (U).iter (), hb_true_t ()); + static auto impl (hb_priority<1>) -> decltype (hb_declval (U).iter (), hb_true_t ()); + template - static hb_false_t test (...); + static hb_false_t impl (hb_priority<0>); public: - enum { value = decltype (test (0))::value }; + + enum { value = decltype (impl (hb_prioritize))::value }; }; #define hb_is_iterable(Iterable) hb_is_iterable::value From 9c724e48a2f5d61c31c79f0b4660f08e5d07db10 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 22 Apr 2019 15:37:10 -0400 Subject: [PATCH 19/69] [serializer] Add err_propagaged_error() --- src/hb-serialize.hh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 12b615349..b831ea626 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -121,7 +121,7 @@ struct hb_serialize_context_t } bool propagate_error (bool success) - { return this->successful = this->successful && success; } + { return this->successful && (success || (err_propagated_error (), false)); } template bool propagate_error (T &&obj) { return propagate_error (!hb_deref_pointer (obj).in_error ()); } @@ -322,8 +322,11 @@ struct hb_serialize_context_t return ret; } + /* Following two functions exist to allow setting breakpoint on. */ void err_ran_out_of_room () { this->ran_out_of_room = true; } + void + err_propagated_error () { this->successful = false; } template Type *allocate_size (unsigned int size) From c862a532df0bc3ce0b47f3fde9bf1dd300ff8bee Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 22 Apr 2019 17:32:19 -0400 Subject: [PATCH 20/69] Add variadic arguments to hb_invoke() --- src/hb-algs.hh | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 93677435b..779d3b70f 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -71,28 +71,28 @@ struct private: /* Pointer-to-member-function. */ - template auto - impl (Appl&& a, Val &&v, hb_priority<2>) const HB_AUTO_RETURN - (hb_forward (hb_deref_pointer (v)).*a ()) + template auto + impl (Appl&& a, hb_priority<2>, Val1 &&v1, Vals &&...vs) const HB_AUTO_RETURN + (hb_forward (hb_deref_pointer (v1)).*a (hb_forward (vs...))) /* Pointer-to-member. */ template auto - impl (Appl&& a, Val &&v, hb_priority<1>) const HB_AUTO_RETURN + impl (Appl&& a, hb_priority<1>, Val &&v) const HB_AUTO_RETURN (hb_forward (hb_deref_pointer (v)).*a) /* Operator(). */ - template auto - impl (Appl&& a, Val &&v, hb_priority<0>) const HB_AUTO_RETURN - (hb_deref_pointer (a) (hb_forward (v))) + template auto + impl (Appl&& a, hb_priority<0>, Vals &&...vs) const HB_AUTO_RETURN + (hb_deref_pointer (a) (hb_forward (vs...))) public: - template auto - operator () (Appl&& a, Val &&v) const HB_AUTO_RETURN + template auto + operator () (Appl&& a, Vals &&...vs) const HB_AUTO_RETURN ( impl (hb_forward (a), - hb_forward (v), - hb_prioritize) + hb_prioritize, + hb_forward (vs...)) ) } HB_FUNCOBJ (hb_invoke); From 25dd88efc6521b972babe1067c0de1b9d4f5dbe5 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Mon, 22 Apr 2019 17:45:23 -0400 Subject: [PATCH 21/69] Err, fix hb_invoke() variadic --- src/hb-algs.hh | 6 +++--- src/test-iter.cc | 5 ++++- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 779d3b70f..e54c6b434 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -73,7 +73,7 @@ struct /* Pointer-to-member-function. */ template auto impl (Appl&& a, hb_priority<2>, Val1 &&v1, Vals &&...vs) const HB_AUTO_RETURN - (hb_forward (hb_deref_pointer (v1)).*a (hb_forward (vs...))) + (hb_forward (hb_deref_pointer (v1)).*a (hb_forward (vs)...)) /* Pointer-to-member. */ template auto @@ -83,7 +83,7 @@ struct /* Operator(). */ template auto impl (Appl&& a, hb_priority<0>, Vals &&...vs) const HB_AUTO_RETURN - (hb_deref_pointer (a) (hb_forward (vs...))) + (hb_deref_pointer (a) (hb_forward (vs)...)) public: @@ -92,7 +92,7 @@ struct ( impl (hb_forward (a), hb_prioritize, - hb_forward (vs...)) + hb_forward (vs)...) ) } HB_FUNCOBJ (hb_invoke); diff --git a/src/test-iter.cc b/src/test-iter.cc index 675bbe397..93a48526d 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -181,7 +181,7 @@ main (int argc, char **argv) ; /* The result should be something like 0->10, 1->11, ..., 9->19 */ assert (hb_map_get (result, 9) == 19); - + unsigned int temp3 = 0; + hb_iter(src) | hb_map([&] (int i) -> int { return ++temp3; }) @@ -197,5 +197,8 @@ main (int argc, char **argv) long vl; s >> vl; + if (0) + hb_invoke (main, 0, nullptr); + return 0; } From 7c218351ab45c41e48147b2196393357f7b551d4 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Tue, 23 Apr 2019 12:40:29 +0430 Subject: [PATCH 22/69] .editorconfig, minor still doesn't work with vscode --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index 499147351..4850f2bf6 100644 --- a/.editorconfig +++ b/.editorconfig @@ -9,7 +9,7 @@ insert_final_newline = true [*.{c,cc,h,hh}] tab_width = 8 indent_size = 2 -indent_style = space +indent_style = tab # should be space [*.{py,sh}] indent_style = tab From 64ca2ffa4c88b961dcbd9d06be8ac7dd80ad8182 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Tue, 23 Apr 2019 01:10:46 -0700 Subject: [PATCH 23/69] Fix clang's -Wmain complain (#1678) --- src/test-iter.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/test-iter.cc b/src/test-iter.cc index 93a48526d..cf1e6d670 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -99,6 +99,12 @@ test_iterable (const Iterable &lst = Null(Iterable)) test_iterator (lst.iter ()); } +static char * +test_func (int a, char **b) +{ + return b[a]; +} + int main (int argc, char **argv) { @@ -198,7 +204,7 @@ main (int argc, char **argv) s >> vl; if (0) - hb_invoke (main, 0, nullptr); + hb_invoke (test_func, 0, nullptr); return 0; } From 20f3134789f65b10f301c4635c9f80c2dda0fb97 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Apr 2019 12:58:52 -0400 Subject: [PATCH 24/69] Use variadic templates in OffsetTo<> and various ArrayOf<>s --- src/hb-open-type.hh | 145 +++++++++++++++----------------------------- 1 file changed, 49 insertions(+), 96 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 23f7511b1..f4e7cd6d0 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -284,8 +284,8 @@ struct OffsetTo : Offset return * (Type *) Offset::serialize (c, base); } - template - bool serialize_subset (hb_subset_context_t *c, const T &src, const void *base) + template + bool serialize_subset (hb_subset_context_t *c, const T &src, const void *base, Ts ...ds) { *this = 0; if (has_null && &src == &Null (T)) @@ -295,7 +295,7 @@ struct OffsetTo : Offset s->push (); - bool ret = src.subset (c); + bool ret = src.subset (c, ds...); if (ret || !has_null) s->add_link (*this, s->pop_pack (), base); @@ -314,39 +314,13 @@ struct OffsetTo : Offset return_trace (true); } - bool sanitize (hb_sanitize_context_t *c, const void *base) const + template + bool sanitize (hb_sanitize_context_t *c, const void *base, Ts ...ds) const { TRACE_SANITIZE (this); return_trace (sanitize_shallow (c, base) && (this->is_null () || - StructAtOffset (base, *this).sanitize (c) || - neuter (c))); - } - template - bool sanitize (hb_sanitize_context_t *c, const void *base, T1 d1) const - { - TRACE_SANITIZE (this); - return_trace (sanitize_shallow (c, base) && - (this->is_null () || - StructAtOffset (base, *this).sanitize (c, d1) || - neuter (c))); - } - template - bool sanitize (hb_sanitize_context_t *c, const void *base, T1 d1, T2 d2) const - { - TRACE_SANITIZE (this); - return_trace (sanitize_shallow (c, base) && - (this->is_null () || - StructAtOffset (base, *this).sanitize (c, d1, d2) || - neuter (c))); - } - template - bool sanitize (hb_sanitize_context_t *c, const void *base, T1 d1, T2 d2, T3 d3) const - { - TRACE_SANITIZE (this); - return_trace (sanitize_shallow (c, base) && - (this->is_null () || - StructAtOffset (base, *this).sanitize (c, d1, d2, d3) || + StructAtOffset (base, *this).sanitize (c, ds...) || neuter (c))); } @@ -430,29 +404,26 @@ struct UnsizedArrayOf * we do not need to call their sanitize() as we already did * a bound check on the aggregate array size. We just include * a small unreachable expression to make sure the structs - * pointed to do have a simple sanitize(), ie. they do not + * pointed to do have a simple sanitize() as well as an + * assignment opreator. This ensures that they do not * reference other structs via offsets. */ - (void) (false && arrayZ[0].sanitize (c)); + if (false) + { + arrayZ[0].sanitize (c); + Type v; + v = arrayZ[0]; + } return_trace (true); } - bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base) const + template + bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base, Ts ...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c, count))) return_trace (false); for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base))) - return_trace (false); - return_trace (true); - } - template - bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base, T user_data) const - { - TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c, count))) return_trace (false); - for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base, user_data))) + if (unlikely (!arrayZ[i].sanitize (c, base, ds...))) return_trace (false); return_trace (true); } @@ -492,17 +463,12 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf return this+*p; } - - bool sanitize (hb_sanitize_context_t *c, unsigned int count) const + template + bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts ...ds) const { TRACE_SANITIZE (this); - return_trace ((UnsizedOffsetArrayOf::sanitize (c, count, this))); - } - template - bool sanitize (hb_sanitize_context_t *c, unsigned int count, T user_data) const - { - TRACE_SANITIZE (this); - return_trace ((UnsizedOffsetArrayOf::sanitize (c, count, this, user_data))); + return_trace ((UnsizedOffsetArrayOf + ::sanitize (c, count, this, ds...))); } }; @@ -622,24 +588,14 @@ struct ArrayOf return_trace (true); } - bool sanitize (hb_sanitize_context_t *c, const void *base) const + template + bool sanitize (hb_sanitize_context_t *c, const void *base, Ts ...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = len; for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base))) - return_trace (false); - return_trace (true); - } - template - bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const - { - TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c))) return_trace (false); - unsigned int count = len; - for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base, user_data))) + if (unlikely (!arrayZ[i].sanitize (c, base, ds...))) return_trace (false); return_trace (true); } @@ -706,16 +662,11 @@ struct OffsetListOf : OffsetArrayOf return_trace (true); } - bool sanitize (hb_sanitize_context_t *c) const + template + bool sanitize (hb_sanitize_context_t *c, Ts ...ds) const { TRACE_SANITIZE (this); - return_trace (OffsetArrayOf::sanitize (c, this)); - } - template - bool sanitize (hb_sanitize_context_t *c, T user_data) const - { - TRACE_SANITIZE (this); - return_trace (OffsetArrayOf::sanitize (c, this, user_data)); + return_trace (OffsetArrayOf::sanitize (c, this, ds...)); } }; @@ -763,10 +714,16 @@ struct HeadlessArrayOf * we do not need to call their sanitize() as we already did * a bound check on the aggregate array size. We just include * a small unreachable expression to make sure the structs - * pointed to do have a simple sanitize(), ie. they do not + * pointed to do have a simple sanitize() as well as an + * assignment opreator. This ensures that they do not * reference other structs via offsets. */ - (void) (false && arrayZ[0].sanitize (c)); + if (false) + { + arrayZ[0].sanitize (c); + Type v; + v = arrayZ[0]; + } return_trace (true); } @@ -807,14 +764,14 @@ struct ArrayOfM1 unsigned int get_size () const { return lenM1.static_size + (lenM1 + 1) * Type::static_size; } - template - bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const + template + bool sanitize (hb_sanitize_context_t *c, const void *base, Ts ...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = lenM1 + 1; for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base, user_data))) + if (unlikely (!arrayZ[i].sanitize (c, base, ds...))) return_trace (false); return_trace (true); } @@ -999,31 +956,27 @@ struct VarSizedBinSearchArrayOf * we do not need to call their sanitize() as we already did * a bound check on the aggregate array size. We just include * a small unreachable expression to make sure the structs - * pointed to do have a simple sanitize(), ie. they do not + * pointed to do have a simple sanitize() as well as an + * assignment opreator. This ensures that they do not * reference other structs via offsets. */ - (void) (false && StructAtOffset (&bytesZ, 0).sanitize (c)); + if (false) + { + (*this)[0].sanitize (c); + Type v; + v = (*this)[0]; + } return_trace (true); } - bool sanitize (hb_sanitize_context_t *c, const void *base) const + template + bool sanitize (hb_sanitize_context_t *c, const void *base, Ts ...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) - if (unlikely (!(*this)[i].sanitize (c, base))) - return_trace (false); - return_trace (true); - } - template - bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const - { - TRACE_SANITIZE (this); - if (unlikely (!sanitize_shallow (c))) return_trace (false); - unsigned int count = get_length (); - for (unsigned int i = 0; i < count; i++) - if (unlikely (!(*this)[i].sanitize (c, base, user_data))) + if (unlikely (!(*this)[i].sanitize (c, base, ds...))) return_trace (false); return_trace (true); } From 441cca235477a5399af214c9ac85320d4de69f0b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Apr 2019 23:49:21 -0400 Subject: [PATCH 25/69] Use hb_forward() when forwarding parameter pack --- src/hb-open-type.hh | 32 ++++++++++++++++---------------- src/hb-serialize.hh | 3 ++- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index f4e7cd6d0..d165f475f 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -285,7 +285,7 @@ struct OffsetTo : Offset } template - bool serialize_subset (hb_subset_context_t *c, const T &src, const void *base, Ts ...ds) + bool serialize_subset (hb_subset_context_t *c, const T &src, const void *base, Ts &&...ds) { *this = 0; if (has_null && &src == &Null (T)) @@ -295,7 +295,7 @@ struct OffsetTo : Offset s->push (); - bool ret = src.subset (c, ds...); + bool ret = src.subset (c, hb_forward (ds)...); if (ret || !has_null) s->add_link (*this, s->pop_pack (), base); @@ -315,12 +315,12 @@ struct OffsetTo : Offset } template - bool sanitize (hb_sanitize_context_t *c, const void *base, Ts ...ds) const + bool sanitize (hb_sanitize_context_t *c, const void *base, Ts &&...ds) const { TRACE_SANITIZE (this); return_trace (sanitize_shallow (c, base) && (this->is_null () || - StructAtOffset (base, *this).sanitize (c, ds...) || + StructAtOffset (base, *this).sanitize (c, hb_forward (ds)...) || neuter (c))); } @@ -418,12 +418,12 @@ struct UnsizedArrayOf return_trace (true); } template - bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base, Ts ...ds) const + bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base, Ts &&...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c, count))) return_trace (false); for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base, ds...))) + if (unlikely (!arrayZ[i].sanitize (c, base, hb_forward (ds)...))) return_trace (false); return_trace (true); } @@ -464,11 +464,11 @@ struct UnsizedOffsetListOf : UnsizedOffsetArrayOf } template - bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts ...ds) const + bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts &&...ds) const { TRACE_SANITIZE (this); return_trace ((UnsizedOffsetArrayOf - ::sanitize (c, count, this, ds...))); + ::sanitize (c, count, this, hb_forward (ds)...))); } }; @@ -589,13 +589,13 @@ struct ArrayOf return_trace (true); } template - bool sanitize (hb_sanitize_context_t *c, const void *base, Ts ...ds) const + bool sanitize (hb_sanitize_context_t *c, const void *base, Ts &&...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = len; for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base, ds...))) + if (unlikely (!arrayZ[i].sanitize (c, base, hb_forward (ds)...))) return_trace (false); return_trace (true); } @@ -663,10 +663,10 @@ struct OffsetListOf : OffsetArrayOf } template - bool sanitize (hb_sanitize_context_t *c, Ts ...ds) const + bool sanitize (hb_sanitize_context_t *c, Ts &&...ds) const { TRACE_SANITIZE (this); - return_trace (OffsetArrayOf::sanitize (c, this, ds...)); + return_trace (OffsetArrayOf::sanitize (c, this, hb_forward (ds)...)); } }; @@ -765,13 +765,13 @@ struct ArrayOfM1 { return lenM1.static_size + (lenM1 + 1) * Type::static_size; } template - bool sanitize (hb_sanitize_context_t *c, const void *base, Ts ...ds) const + bool sanitize (hb_sanitize_context_t *c, const void *base, Ts &&...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = lenM1 + 1; for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base, ds...))) + if (unlikely (!arrayZ[i].sanitize (c, base, hb_forward (ds)...))) return_trace (false); return_trace (true); } @@ -970,13 +970,13 @@ struct VarSizedBinSearchArrayOf return_trace (true); } template - bool sanitize (hb_sanitize_context_t *c, const void *base, Ts ...ds) const + bool sanitize (hb_sanitize_context_t *c, const void *base, Ts &&...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) - if (unlikely (!(*this)[i].sanitize (c, base, ds...))) + if (unlikely (!(*this)[i].sanitize (c, base, hb_forward (ds)...))) return_trace (false); return_trace (true); } diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index b831ea626..cab444e26 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -127,7 +127,8 @@ struct hb_serialize_context_t { return propagate_error (!hb_deref_pointer (obj).in_error ()); } template bool propagate_error (T1 &&o1, Ts &&...os) - { return propagate_error (o1) && propagate_error (os...); } + { return propagate_error (hb_forward (o1)) && + propagate_error (hb_forward (os)...); } /* To be called around main operation. */ template From 175bdad8bff5b0e9732ab1fb97617a9293680fd4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Tue, 23 Apr 2019 23:57:11 -0400 Subject: [PATCH 26/69] One more variadic parameter pack use --- src/hb-aat-layout-common.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh index 2508276c2..7c74d7938 100644 --- a/src/hb-aat-layout-common.hh +++ b/src/hb-aat-layout-common.hh @@ -153,13 +153,13 @@ struct LookupSegmentArray first <= last && valuesZ.sanitize (c, base, last - first + 1)); } - template - bool sanitize (hb_sanitize_context_t *c, const void *base, T2 user_data) const + template + bool sanitize (hb_sanitize_context_t *c, const void *base, Ts &&...ds) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && first <= last && - valuesZ.sanitize (c, base, last - first + 1, user_data)); + valuesZ.sanitize (c, base, last - first + 1, hb_forward (ds)...)); } GlyphID last; /* Last GlyphID in this segment */ From 3ad20c38ade76aca8aed024014977ecb5f2b636e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 09:09:00 -0400 Subject: [PATCH 27/69] [serialize] Fix a few overflow TODO items --- src/hb-open-type.hh | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index d165f475f..56c87b385 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -182,7 +182,8 @@ struct Offset : Type void *serialize (hb_serialize_context_t *c, const void *base) { void *t = c->start_embed (); - *this = (char *) t - (char *) base; /* TODO(serialize) Overflow? */ + unsigned int offset = (char *) t - (char *) base; + c->propagate_error ((*this = offset) == offset); return t; } @@ -548,7 +549,7 @@ struct ArrayOf { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); - len = items_len; /* TODO(serialize) Overflow? */ + c->propagate_error ((len = items_len) == items_len); if (unlikely (!c->extend (*this))) return_trace (false); return_trace (true); } @@ -698,7 +699,7 @@ struct HeadlessArrayOf { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); - lenP1 = items.length + 1; /* TODO(serialize) Overflow? */ + c->propagate_error ((lenP1 = items.length + 1) == items.length + 1); if (unlikely (!c->extend (*this))) return_trace (false); for (unsigned int i = 0; i < items.length; i++) arrayZ[i] = items[i]; From 27377a7e287dd39e3f7caad5c1e0691ae381ccf8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 09:22:14 -0400 Subject: [PATCH 28/69] Rely on variadic parameter pack more --- src/hb-open-type.hh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 56c87b385..d8cd3edb2 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -419,12 +419,12 @@ struct UnsizedArrayOf return_trace (true); } template - bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base, Ts &&...ds) const + bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts &&...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c, count))) return_trace (false); for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base, hb_forward (ds)...))) + if (unlikely (!arrayZ[i].sanitize (c, hb_forward (ds)...))) return_trace (false); return_trace (true); } @@ -590,13 +590,13 @@ struct ArrayOf return_trace (true); } template - bool sanitize (hb_sanitize_context_t *c, const void *base, Ts &&...ds) const + bool sanitize (hb_sanitize_context_t *c, Ts &&...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = len; for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base, hb_forward (ds)...))) + if (unlikely (!arrayZ[i].sanitize (c, hb_forward (ds)...))) return_trace (false); return_trace (true); } @@ -766,13 +766,13 @@ struct ArrayOfM1 { return lenM1.static_size + (lenM1 + 1) * Type::static_size; } template - bool sanitize (hb_sanitize_context_t *c, const void *base, Ts &&...ds) const + bool sanitize (hb_sanitize_context_t *c, Ts &&...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = lenM1 + 1; for (unsigned int i = 0; i < count; i++) - if (unlikely (!arrayZ[i].sanitize (c, base, hb_forward (ds)...))) + if (unlikely (!arrayZ[i].sanitize (c, hb_forward (ds)...))) return_trace (false); return_trace (true); } @@ -971,13 +971,13 @@ struct VarSizedBinSearchArrayOf return_trace (true); } template - bool sanitize (hb_sanitize_context_t *c, const void *base, Ts &&...ds) const + bool sanitize (hb_sanitize_context_t *c, Ts &&...ds) const { TRACE_SANITIZE (this); if (unlikely (!sanitize_shallow (c))) return_trace (false); unsigned int count = get_length (); for (unsigned int i = 0; i < count; i++) - if (unlikely (!(*this)[i].sanitize (c, base, hb_forward (ds)...))) + if (unlikely (!(*this)[i].sanitize (c, hb_forward (ds)...))) return_trace (false); return_trace (true); } From 12017db0bfe62e7777e1ab6ba5b14729dcd4c351 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 09:24:38 -0400 Subject: [PATCH 29/69] Move test code around --- src/test-algs.cc | 8 ++++++++ src/test-iter.cc | 9 --------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/test-algs.cc b/src/test-algs.cc index 42a9538dc..8ec93f009 100644 --- a/src/test-algs.cc +++ b/src/test-algs.cc @@ -28,6 +28,12 @@ #include "hb-algs.hh" +static char * +test_func (int a, char **b) +{ + return b ? b[a] : nullptr; +} + int main (int argc, char **argv) { @@ -46,5 +52,7 @@ main (int argc, char **argv) q.second = 4; assert (i == 4); + hb_invoke (test_func, 0, nullptr); + return 0; } diff --git a/src/test-iter.cc b/src/test-iter.cc index cf1e6d670..9ce8b0ca2 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -99,12 +99,6 @@ test_iterable (const Iterable &lst = Null(Iterable)) test_iterator (lst.iter ()); } -static char * -test_func (int a, char **b) -{ - return b[a]; -} - int main (int argc, char **argv) { @@ -203,8 +197,5 @@ main (int argc, char **argv) long vl; s >> vl; - if (0) - hb_invoke (test_func, 0, nullptr); - return 0; } From 11ab889a8d743304c8ec17920e209a514f46739d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 09:55:24 -0400 Subject: [PATCH 30/69] Rename a few test programs --- src/Makefile.am | 24 +++++++++---------- ...ize-params.cc => test-gpos-size-params.cc} | 0 ...itute.cc => test-gsub-would-substitute.cc} | 0 src/{test-name-table.cc => test-ot-name.cc} | 0 4 files changed, 12 insertions(+), 12 deletions(-) rename src/{test-size-params.cc => test-gpos-size-params.cc} (100%) rename src/{test-would-substitute.cc => test-gsub-would-substitute.cc} (100%) rename src/{test-name-table.cc => test-ot-name.cc} (100%) diff --git a/src/Makefile.am b/src/Makefile.am index 66a3b3177..9b5512f20 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -310,9 +310,9 @@ noinst_PROGRAMS = \ main \ test \ test-buffer-serialize \ - test-name-table \ - test-size-params \ - test-would-substitute \ + test-ot-name \ + test-gpos-size-params \ + test-gsub-would-substitute \ $(NULL) bin_PROGRAMS = @@ -328,17 +328,17 @@ test_buffer_serialize_SOURCES = test-buffer-serialize.cc test_buffer_serialize_CPPFLAGS = $(HBCFLAGS) test_buffer_serialize_LDADD = libharfbuzz.la $(HBLIBS) -test_name_table_SOURCES = test-name-table.cc -test_name_table_CPPFLAGS = $(HBCFLAGS) -test_name_table_LDADD = libharfbuzz.la $(HBLIBS) +test_ot_name_SOURCES = test-ot-name.cc +test_ot_name_CPPFLAGS = $(HBCFLAGS) +test_ot_name_LDADD = libharfbuzz.la $(HBLIBS) -test_size_params_SOURCES = test-size-params.cc -test_size_params_CPPFLAGS = $(HBCFLAGS) -test_size_params_LDADD = libharfbuzz.la $(HBLIBS) +test_gpos_size_params_SOURCES = test-gpos-size-params.cc +test_gpos_size_params_CPPFLAGS = $(HBCFLAGS) +test_gpos_size_params_LDADD = libharfbuzz.la $(HBLIBS) -test_would_substitute_SOURCES = test-would-substitute.cc -test_would_substitute_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS) -test_would_substitute_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS) +test_gsub_would_substitute_SOURCES = test-gsub-would-substitute.cc +test_gsub_would_substitute_CPPFLAGS = $(HBCFLAGS) $(FREETYPE_CFLAGS) +test_gsub_would_substitute_LDADD = libharfbuzz.la $(HBLIBS) $(FREETYPE_LIBS) if HAVE_FREETYPE if HAVE_CAIRO_FT diff --git a/src/test-size-params.cc b/src/test-gpos-size-params.cc similarity index 100% rename from src/test-size-params.cc rename to src/test-gpos-size-params.cc diff --git a/src/test-would-substitute.cc b/src/test-gsub-would-substitute.cc similarity index 100% rename from src/test-would-substitute.cc rename to src/test-gsub-would-substitute.cc diff --git a/src/test-name-table.cc b/src/test-ot-name.cc similarity index 100% rename from src/test-name-table.cc rename to src/test-ot-name.cc From 00a00bc1f23c681d64fbd4df33582ec0165e337a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 10:01:30 -0400 Subject: [PATCH 31/69] Fix two TODOs --- src/hb-ot-layout-gsub-table.hh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index e664e06f4..a08f21fb7 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -90,7 +90,7 @@ struct SingleSubstFormat1 TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs))) return_trace (false); - deltaGlyphID = delta; /* TODO(serialize) overflow? */ + c->propagate_error ((deltaGlyphID = delta) == delta); return_trace (true); } @@ -231,15 +231,14 @@ struct SingleSubst { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (u.format))) return_trace (false); - unsigned int format = 2; - int delta = 0; + unsigned format = 2; + unsigned delta = 0; if (glyphs.length) { format = 1; - /* TODO(serialize) check for wrap-around */ - delta = substitutes[0] - glyphs[0]; + delta = (unsigned) (substitutes[0] - glyphs[0]) & 0xFFFF; for (unsigned int i = 1; i < glyphs.length; i++) - if (delta != (int) (substitutes[i] - glyphs[i])) { + if (delta != ((unsigned) (substitutes[i] - glyphs[i]) & 0xFFFF)) { format = 2; break; } From 915b9ea5f48d56df21419761477b2d4ba2843b54 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 10:07:19 -0400 Subject: [PATCH 32/69] [serialize] Add c->check_assign() To check for assignment overflows. --- src/hb-open-type.hh | 7 +++---- src/hb-ot-layout-gsub-table.hh | 2 +- src/hb-serialize.hh | 20 +++++++++++++------- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index d8cd3edb2..b232fdbc1 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -182,8 +182,7 @@ struct Offset : Type void *serialize (hb_serialize_context_t *c, const void *base) { void *t = c->start_embed (); - unsigned int offset = (char *) t - (char *) base; - c->propagate_error ((*this = offset) == offset); + c->check_assign (*this, (char *) t - (char *) base); return t; } @@ -549,7 +548,7 @@ struct ArrayOf { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); - c->propagate_error ((len = items_len) == items_len); + c->check_assign (len, items_len); if (unlikely (!c->extend (*this))) return_trace (false); return_trace (true); } @@ -699,7 +698,7 @@ struct HeadlessArrayOf { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); - c->propagate_error ((lenP1 = items.length + 1) == items.length + 1); + c->check_assign (lenP1, items.length + 1); if (unlikely (!c->extend (*this))) return_trace (false); for (unsigned int i = 0; i < items.length; i++) arrayZ[i] = items[i]; diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index a08f21fb7..8574eb5c8 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -90,7 +90,7 @@ struct SingleSubstFormat1 TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs))) return_trace (false); - c->propagate_error ((deltaGlyphID = delta) == delta); + c->check_assign (deltaGlyphID, delta); return_trace (true); } diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index cab444e26..7e2d2f7b9 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -120,11 +120,19 @@ struct hb_serialize_context_t this->packed.push (nullptr); } - bool propagate_error (bool success) + bool check_success (bool success) { return this->successful && (success || (err_propagated_error (), false)); } + template + bool check_equal (T1 &&v1, T2 &&v2) + { return check_success (v1 == v2); } + + template + bool check_assign (T1 &v1, T2 &&v2) + { return check_equal (v1 = v2, v2); } + template bool propagate_error (T &&obj) - { return propagate_error (!hb_deref_pointer (obj).in_error ()); } + { return check_success (!hb_deref_pointer (obj).in_error ()); } template bool propagate_error (T1 &&o1, Ts &&...os) { return propagate_error (hb_forward (o1)) && @@ -170,7 +178,7 @@ struct hb_serialize_context_t { object_t *obj = object_pool.alloc (); if (unlikely (!obj)) - propagate_error (false); + check_success (false); else { obj->head = head; @@ -293,15 +301,13 @@ struct hb_serialize_context_t { auto &off = * ((BEInt *) (parent.head + link.position)); assert (0 == off); - off = offset; - propagate_error (off == offset); + check_assign (off, offset); } else { auto &off = * ((BEInt *) (parent.head + link.position)); assert (0 == off); - off = offset; - propagate_error (off == offset); + check_assign (off, offset); } } } From 085793d6cd35a1590a66712f39260030367490db Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 10:15:59 -0400 Subject: [PATCH 33/69] Remove wrong TODOs --- src/hb-ot-layout-gsubgpos.hh | 2 +- src/hb-ot-shape-complex-indic.cc | 1 - src/hb-ot-shape-complex-khmer.cc | 4 ++-- src/hb-ot-shape-complex-myanmar.cc | 3 ++- src/hb-ot-shape-complex-use.cc | 4 ++-- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/hb-ot-layout-gsubgpos.hh b/src/hb-ot-layout-gsubgpos.hh index 2e9165be2..840c142ab 100644 --- a/src/hb-ot-layout-gsubgpos.hh +++ b/src/hb-ot-layout-gsubgpos.hh @@ -286,7 +286,7 @@ struct hb_ot_apply_context_t : }; may_match_t may_match (const hb_glyph_info_t &info, - const HBUINT16 *glyph_data) const + const HBUINT16 *glyph_data) const { if (!(info.mask & mask) || (syllable && syllable != info.syllable ())) diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc index 1fd8fc670..6d46fe33c 100644 --- a/src/hb-ot-shape-complex-indic.cc +++ b/src/hb-ot-shape-complex-indic.cc @@ -1008,7 +1008,6 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, ginfo.cluster = buffer->cur().cluster; ginfo.mask = buffer->cur().mask; ginfo.syllable() = buffer->cur().syllable(); - /* TODO Set glyph_props? */ /* Insert dottedcircle after possible Repha. */ while (buffer->idx < buffer->len && buffer->successful && diff --git a/src/hb-ot-shape-complex-khmer.cc b/src/hb-ot-shape-complex-khmer.cc index 5746651d6..4c8847762 100644 --- a/src/hb-ot-shape-complex-khmer.cc +++ b/src/hb-ot-shape-complex-khmer.cc @@ -368,7 +368,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)) return; - /* Note: This loop is extra overhead, but should not be measurable. */ + /* Note: This loop is extra overhead, but should not be measurable. + * TODO Use a buffer scratch flag to remove the loop. */ bool has_broken_syllables = false; unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; @@ -407,7 +408,6 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, ginfo.cluster = buffer->cur().cluster; ginfo.mask = buffer->cur().mask; ginfo.syllable() = buffer->cur().syllable(); - /* TODO Set glyph_props? */ /* Insert dottedcircle after possible Repha. */ while (buffer->idx < buffer->len && buffer->successful && diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc index 70ab972c6..b1f6b65ef 100644 --- a/src/hb-ot-shape-complex-myanmar.cc +++ b/src/hb-ot-shape-complex-myanmar.cc @@ -301,7 +301,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)) return; - /* Note: This loop is extra overhead, but should not be measurable. */ + /* Note: This loop is extra overhead, but should not be measurable. + * TODO Use a buffer scratch flag to remove the loop. */ bool has_broken_syllables = false; unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index eecde6e85..ec4d4aa7e 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -526,7 +526,8 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, if (unlikely (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)) return; - /* Note: This loop is extra overhead, but should not be measurable. */ + /* Note: This loop is extra overhead, but should not be measurable. + * TODO Use a buffer scratch flag to remove the loop. */ bool has_broken_syllables = false; unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; @@ -560,7 +561,6 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, ginfo.cluster = buffer->cur().cluster; ginfo.mask = buffer->cur().mask; ginfo.syllable() = buffer->cur().syllable(); - /* TODO Set glyph_props? */ /* Insert dottedcircle after possible Repha. */ while (buffer->idx < buffer->len && buffer->successful && From 6cc9707c9c0885a3133b7844f615cdcdaeccec18 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 10:22:06 -0400 Subject: [PATCH 34/69] [serialize] Rename --- src/hb-serialize.hh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/hb-serialize.hh b/src/hb-serialize.hh index 7e2d2f7b9..7566881a8 100644 --- a/src/hb-serialize.hh +++ b/src/hb-serialize.hh @@ -121,7 +121,7 @@ struct hb_serialize_context_t } bool check_success (bool success) - { return this->successful && (success || (err_propagated_error (), false)); } + { return this->successful && (success || (err_other_error (), false)); } template bool check_equal (T1 &&v1, T2 &&v2) @@ -330,10 +330,8 @@ struct hb_serialize_context_t } /* Following two functions exist to allow setting breakpoint on. */ - void - err_ran_out_of_room () { this->ran_out_of_room = true; } - void - err_propagated_error () { this->successful = false; } + void err_ran_out_of_room () { this->ran_out_of_room = true; } + void err_other_error () { this->successful = false; } template Type *allocate_size (unsigned int size) From 42526d1697e2449fa23741f84721dcf2ce688af7 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 10:24:33 -0400 Subject: [PATCH 35/69] [serialize] Fix SingleSubstFormat1 failure --- src/hb-ot-layout-gsub-table.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh index 8574eb5c8..10c35e32c 100644 --- a/src/hb-ot-layout-gsub-table.hh +++ b/src/hb-ot-layout-gsub-table.hh @@ -85,7 +85,7 @@ struct SingleSubstFormat1 bool serialize (hb_serialize_context_t *c, hb_sorted_array_t glyphs, - int delta) + unsigned delta) { TRACE_SERIALIZE (this); if (unlikely (!c->extend_min (*this))) return_trace (false); @@ -127,8 +127,8 @@ struct SingleSubstFormat1 OffsetTo coverage; /* Offset to Coverage table--from * beginning of Substitution table */ - HBINT16 deltaGlyphID; /* Add to original GlyphID to get - * substitute GlyphID */ + HBUINT16 deltaGlyphID; /* Add to original GlyphID to get + * substitute GlyphID, modulo 0x10000 */ public: DEFINE_SIZE_STATIC (6); }; From 8f79a5750e8982f9ab73c0dc6a8534dffef74610 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 10:32:49 -0400 Subject: [PATCH 36/69] [algs] Add more hb_forward<>()'s --- src/hb-algs.hh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index e54c6b434..3f627c108 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -73,17 +73,17 @@ struct /* Pointer-to-member-function. */ template auto impl (Appl&& a, hb_priority<2>, Val1 &&v1, Vals &&...vs) const HB_AUTO_RETURN - (hb_forward (hb_deref_pointer (v1)).*a (hb_forward (vs)...)) + (hb_deref_pointer (hb_forward (v1)).*hb_forward (a) (hb_forward (vs)...)) /* Pointer-to-member. */ template auto impl (Appl&& a, hb_priority<1>, Val &&v) const HB_AUTO_RETURN - (hb_forward (hb_deref_pointer (v)).*a) + ((hb_deref_pointer (hb_forward (v))).*hb_forward (a)) /* Operator(). */ template auto impl (Appl&& a, hb_priority<0>, Vals &&...vs) const HB_AUTO_RETURN - (hb_deref_pointer (a) (hb_forward (vs)...)) + (hb_deref_pointer (hb_forward (a)) (hb_forward (vs)...)) public: @@ -102,7 +102,7 @@ struct template auto impl (Pred&& p, Val &&v, hb_priority<1>) const HB_AUTO_RETURN - (hb_deref_pointer (p).has (v)) + (hb_deref_pointer (hb_forward (p)).has (v)) template auto impl (Pred&& p, Val &&v, hb_priority<0>) const HB_AUTO_RETURN @@ -127,7 +127,7 @@ struct template auto impl (Proj&& f, Val &&v, hb_priority<1>) const HB_AUTO_RETURN - (hb_deref_pointer (f).get (hb_forward (v))) + (hb_deref_pointer (hb_forward (f)).get (hb_forward (v))) template auto impl (Proj&& f, Val &&v, hb_priority<0>) const HB_AUTO_RETURN From 0268db11965d022883d5ef2ef828c0635165b7bd Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 10:43:40 -0400 Subject: [PATCH 37/69] [map] Use hb_invoke() with pointer-to-method --- src/hb-algs.hh | 5 ++++- src/hb-map.hh | 4 ++-- src/test-algs.cc | 8 ++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/hb-algs.hh b/src/hb-algs.hh index 3f627c108..c3467800b 100644 --- a/src/hb-algs.hh +++ b/src/hb-algs.hh @@ -73,7 +73,7 @@ struct /* Pointer-to-member-function. */ template auto impl (Appl&& a, hb_priority<2>, Val1 &&v1, Vals &&...vs) const HB_AUTO_RETURN - (hb_deref_pointer (hb_forward (v1)).*hb_forward (a) (hb_forward (vs)...)) + ((hb_deref_pointer (hb_forward (v1)).*hb_forward (a)) (hb_forward (vs)...)) /* Pointer-to-member. */ template auto @@ -86,6 +86,9 @@ struct (hb_deref_pointer (hb_forward (a)) (hb_forward (vs)...)) public: + template auto + impl2 (Appl&& a, hb_priority<2>, Val1 &&v1, Vals &&...vs) const HB_AUTO_RETURN + (hb_deref_pointer (hb_forward (v1)).*hb_forward (a) (hb_forward (vs)...)) template auto operator () (Appl&& a, Vals &&...vs) const HB_AUTO_RETURN diff --git a/src/hb-map.hh b/src/hb-map.hh index b99fb8f4b..9ffa83a8a 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -122,7 +122,7 @@ struct hb_hashmap_t return false; } + hb_iter (new_items, new_size) - | hb_apply ([] (item_t &_) { _.clear (); }) /* TODO make pointer-to-methods invokable. */ + | hb_apply (&item_t::clear) ; unsigned int old_size = mask + 1; @@ -193,7 +193,7 @@ struct hb_hashmap_t return; if (items) + hb_iter (items, mask + 1) - | hb_apply ([] (item_t &_) { _.clear (); }) /* TODO make pointer-to-methods invokable. */ + | hb_apply (&item_t::clear) ; population = occupancy = 0; diff --git a/src/test-algs.cc b/src/test-algs.cc index 8ec93f009..163a79ad3 100644 --- a/src/test-algs.cc +++ b/src/test-algs.cc @@ -34,6 +34,11 @@ test_func (int a, char **b) return b ? b[a] : nullptr; } +struct A +{ + void a () {} +}; + int main (int argc, char **argv) { @@ -54,5 +59,8 @@ main (int argc, char **argv) hb_invoke (test_func, 0, nullptr); + A a; + hb_invoke (&A::a, a); + return 0; } From 4c6136e976af4f7332f703f5a7625505ffc296b6 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 10:44:24 -0400 Subject: [PATCH 38/69] [mutex] Remove TODO --- src/hb-mutex.hh | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/hb-mutex.hh b/src/hb-mutex.hh index 35f1fded1..a760e7317 100644 --- a/src/hb-mutex.hh +++ b/src/hb-mutex.hh @@ -127,8 +127,6 @@ typedef int hb_mutex_impl_t; struct hb_mutex_t { - /* TODO Add tracing. */ - hb_mutex_impl_t m; void init () { hb_mutex_impl_init (&m); } From 22da12318a3e9fd9955f24fd0092de1a4a1a940d Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 10:53:16 -0400 Subject: [PATCH 39/69] [map] Fix TODO --- src/hb-map.hh | 6 ++---- src/hb-meta.hh | 6 ++++++ src/hb-ot-cff1-table.cc | 1 - src/hb-ot-cff2-table.cc | 1 - src/hb.hh | 3 +-- 5 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/hb-map.hh b/src/hb-map.hh index 9ffa83a8a..bbb1bef5d 100644 --- a/src/hb-map.hh +++ b/src/hb-map.hh @@ -34,11 +34,9 @@ * hb_hashmap_t */ -/* TODO if K/V is signed integer, -1 is not a good default. - * Don't know how to get to -MAX using bit work. */ template + K kINVALID = hb_is_pointer (K) ? 0 : hb_is_signed (K) ? hb_int_min (K) : (K) -1, + V vINVALID = hb_is_pointer (V) ? 0 : hb_is_signed (V) ? hb_int_min (V) : (V) -1> struct hb_hashmap_t { HB_DELETE_COPY_ASSIGN (hb_hashmap_t); diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 0dcf79320..bb67b03a8 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -138,6 +138,12 @@ template <> struct hb_is_signed { enum { value = false }; }; template <> struct hb_is_signed { enum { value = false }; }; #define hb_is_signed(T) hb_is_signed::value +template struct hb_int_min { static constexpr T value = 0; }; +template <> struct hb_int_min { static constexpr char value = CHAR_MIN; }; +template <> struct hb_int_min { static constexpr int value = INT_MIN; }; +template <> struct hb_int_min { static constexpr long value = LONG_MIN; }; +#define hb_int_min(T) hb_int_min::value + template struct hb_signedness_int; template <> struct hb_signedness_int { typedef unsigned int value; }; template <> struct hb_signedness_int { typedef signed int value; }; diff --git a/src/hb-ot-cff1-table.cc b/src/hb-ot-cff1-table.cc index 5132801bf..1d97e5444 100644 --- a/src/hb-ot-cff1-table.cc +++ b/src/hb-ot-cff1-table.cc @@ -26,7 +26,6 @@ #include "hb-ot-cff1-table.hh" #include "hb-cff1-interp-cs.hh" -#include using namespace CFF; diff --git a/src/hb-ot-cff2-table.cc b/src/hb-ot-cff2-table.cc index 15cdbaa85..d2463d785 100644 --- a/src/hb-ot-cff2-table.cc +++ b/src/hb-ot-cff2-table.cc @@ -26,7 +26,6 @@ #include "hb-ot-cff2-table.hh" #include "hb-cff2-interp-cs.hh" -#include using namespace CFF; diff --git a/src/hb.hh b/src/hb.hh index ee35c4dd9..0336ed568 100644 --- a/src/hb.hh +++ b/src/hb.hh @@ -167,8 +167,7 @@ #include "hb-aat.h" #define HB_AAT_H_IN -#include "hb-aat.h" - +#include #include #include #include From 714307cc437f375f128e17e5ab01eba0c57aaf01 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 10:56:12 -0400 Subject: [PATCH 40/69] [iter] Remove fixed TODO --- src/hb-iter.hh | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 46d6c406b..2cab2dcd1 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -129,8 +129,6 @@ struct hb_iter_t #define hb_iter_t(Iterable) decltype (hb_declval (Iterable).iter ()) -/* TODO Change to function-object. */ - template struct hb_array_t; struct @@ -225,7 +223,6 @@ struct hb_is_iterable /* TODO Add hb_is_iterable_of(). * TODO Add random_access / sorted variants. */ - /* hb_is_iterator() / hb_is_random_access_iterator() / hb_is_sorted_iterator() */ template From 59a8fa53533b10b9c25458d9ba2d68b7b01c3ff0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 12:19:13 -0400 Subject: [PATCH 41/69] [iter] Add tests for casting to hb_iter_t<> base class for hb_sorted_array_t<> Something's phishy about hb_sorted_array_t<>. Can't get it work nicely with change I'm making. Ugh.. --- src/test-iter.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/test-iter.cc b/src/test-iter.cc index 9ce8b0ca2..3de340145 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -91,7 +91,7 @@ test_iterator (Iter it) } template + hb_enable_if (hb_is_iterable (Iterable))> static void test_iterable (const Iterable &lst = Null(Iterable)) { @@ -127,6 +127,11 @@ main (int argc, char **argv) hb_set_t st; test_iterable (st); hb_sorted_array_t sa; + (void) static_cast, hb_sorted_array_t::item_t>&> (sa); + (void) static_cast, hb_sorted_array_t::__item_t__>&> (sa); + (void) static_cast, int&>&>(sa); + (void) static_cast>&>(sa); + (void) static_cast, int&>&> (sa); test_iterable (sa); test_iterable > (); From 0ca358f21a2a6e86a3d5c145a70bb84ab6e2db32 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 16:36:29 -0400 Subject: [PATCH 42/69] Try fixing cmake build --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f64f96d1c..4ef0a2f79 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -844,7 +844,7 @@ endif () if (HB_BUILD_TESTS) ## src/ executables - foreach (prog main test test-would-substitute test-size-params test-buffer-serialize hb-ot-tag test-unicode-ranges) + foreach (prog main test test-gsub-would-substitute test-gpos-size-params test-buffer-serialize hb-ot-tag test-unicode-ranges test-ot-name) set (prog_name ${prog}) if (${prog_name} STREQUAL "test") # test can not be used as a valid executable name on cmake, lets special case it From f2d20dd9d3b52f434f5fe9dbef82bd95eb499edf Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 15:08:27 -0700 Subject: [PATCH 43/69] [THANKS] Add Ivan Kuckir https://github.com/harfbuzz/harfbuzz/issues/1633#issuecomment-485764140 --- THANKS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/THANKS b/THANKS index 940cfde5c..88cb7e9ea 100644 --- a/THANKS +++ b/THANKS @@ -1,6 +1,6 @@ Bradley Grainger -Khaled Hosny Kenichi Ishibashi +Ivan Kuckir Ryan Lortie Jeff Muizelaar suzuki toshiya From c69f02784ac53a7fd13eee559559b38d8224ef59 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 16:31:37 -0700 Subject: [PATCH 44/69] Fix sign-compare error on 32-bit systems --- src/hb-open-type.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index b232fdbc1..041b9843f 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -182,7 +182,7 @@ struct Offset : Type void *serialize (hb_serialize_context_t *c, const void *base) { void *t = c->start_embed (); - c->check_assign (*this, (char *) t - (char *) base); + c->check_assign (*this, (unsigned) ((char *) t - (char *) base)); return t; } From 3fc066314ac19005ea8157a6541412cfd24abbc2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 24 Apr 2019 16:41:57 -0700 Subject: [PATCH 45/69] Another try at fixing cmake build --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ef0a2f79..a8d12c163 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -844,7 +844,7 @@ endif () if (HB_BUILD_TESTS) ## src/ executables - foreach (prog main test test-gsub-would-substitute test-gpos-size-params test-buffer-serialize hb-ot-tag test-unicode-ranges test-ot-name) + foreach (prog main test test-gsub-would-substitute test-gpos-size-params test-buffer-serialize hb-ot-tag test-unicode-ranges) set (prog_name ${prog}) if (${prog_name} STREQUAL "test") # test can not be used as a valid executable name on cmake, lets special case it From 474f3587cd18fdaf86b2068647fa03b107557d8c Mon Sep 17 00:00:00 2001 From: Michiharu Ariza Date: Fri, 26 Apr 2019 10:12:38 -0700 Subject: [PATCH 46/69] copy retain_gids from input to plan --- src/hb-subset-plan.cc | 1 + src/hb-subset-plan.hh | 1 + 2 files changed, 2 insertions(+) diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index 8b7231494..6e32ed774 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -204,6 +204,7 @@ hb_subset_plan_create (hb_face_t *face, plan->drop_hints = input->drop_hints; plan->drop_layout = input->drop_layout; plan->desubroutinize = input->desubroutinize; + plan->retain_gids = input->retain_gids; plan->unicodes = hb_set_create(); plan->source = hb_face_reference (face); plan->dest = hb_face_builder_create (); diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh index 56726d4d0..afaeff4e8 100644 --- a/src/hb-subset-plan.hh +++ b/src/hb-subset-plan.hh @@ -42,6 +42,7 @@ struct hb_subset_plan_t bool drop_hints : 1; bool drop_layout : 1; bool desubroutinize : 1; + bool retain_gids : 1; // For each cp that we'd like to retain maps to the corresponding gid. hb_set_t *unicodes; From 52bb0346d319c322f117567a096fafa1bc804e26 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Apr 2019 12:52:28 -0700 Subject: [PATCH 47/69] [meta] Add hb_decay<> --- src/hb-meta.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index bb67b03a8..73f965f86 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -96,6 +96,8 @@ template struct hb_match_pointer { typedef T type; enum { valu template using hb_remove_pointer = typename hb_match_pointer::type; #define hb_is_pointer(T) hb_match_pointer::value +template using hb_decay = hb_remove_const>; + /* std::move and std::forward */ From 8ecae793aa79056a312d3c8518106cfeca42390e Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Apr 2019 12:57:56 -0700 Subject: [PATCH 48/69] [meta] Add hb_is_cr_convertible_to() --- src/hb-meta.hh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 73f965f86..005420364 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -98,6 +98,11 @@ template using hb_remove_pointer = typename hb_match_pointer::ty template using hb_decay = hb_remove_const>; +#define hb_is_cr_convertible_to(A, B) ( \ + hb_is_same (hb_decay, hb_decay) && \ + hb_is_const (A) <= hb_is_const (B) && \ + hb_is_reference (A) >= hb_is_reference (B)) + /* std::move and std::forward */ From b2758c360cc08d7a0334aae11845d0c5d50c46af Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Apr 2019 12:58:06 -0700 Subject: [PATCH 49/69] [array] Use hb_is_cr_convertible_to() --- src/hb-array.hh | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/hb-array.hh b/src/hb-array.hh index ee34dd54d..7a781bea3 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -47,22 +47,12 @@ struct hb_array_t : hb_iter_with_fallback_t, Type&> template hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_) {} template , U) || - hb_is_same (Type, hb_remove_reference) || - hb_is_same (hb_remove_const, hb_remove_reference) - )> + hb_enable_if (hb_is_cr_convertible_to(U, Type))> hb_array_t (const hb_array_t &o) : hb_iter_with_fallback_t, Type&> (), arrayZ (o.arrayZ), length (o.length) {} template , U) || - hb_is_same (Type, hb_remove_reference) || - hb_is_same (hb_remove_const, hb_remove_reference) - )> + hb_enable_if (hb_is_cr_convertible_to(U, Type))> hb_array_t& operator = (const hb_array_t &o) { arrayZ = o.arrayZ; length = o.length; return *this; } From c51f15ddfcae8578483693b761b81ceaebf05f2a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Apr 2019 13:03:41 -0700 Subject: [PATCH 50/69] [array] Adjust hb_sorted_array_t copy constructor/assignment to match hb_array_t --- src/hb-array.hh | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/hb-array.hh b/src/hb-array.hh index 7a781bea3..b4619ee9a 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -211,12 +211,19 @@ struct hb_sorted_array_t : static constexpr bool is_sorted_iterator = true; hb_sorted_array_t () : hb_array_t () {} - hb_sorted_array_t (const hb_array_t &o) : hb_array_t (o) {} - template - hb_sorted_array_t (const hb_sorted_array_t > &o) : hb_array_t (o) {} hb_sorted_array_t (Type *array_, unsigned int length_) : hb_array_t (array_, length_) {} template hb_sorted_array_t (Type (&array_)[length_]) : hb_array_t (array_) {} + template + hb_sorted_array_t (const hb_array_t &o) : + hb_iter_t, Type&> (), + hb_array_t (o) {} + template + hb_sorted_array_t& operator = (const hb_array_t &o) + { hb_array_t (*this) = o; return *this; } + hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int *seg_count /* IN/OUT */) const { return hb_sorted_array_t (((const hb_array_t *) (this))->sub_array (start_offset, seg_count)); } hb_sorted_array_t sub_array (unsigned int start_offset, unsigned int seg_count) const From 73c82f2301a52cf2111296b34691bc898a7a6363 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Apr 2019 13:16:48 -0700 Subject: [PATCH 51/69] [iter] Fix hb_is_iterator_of() to actually check item type --- src/hb-iter.hh | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 2cab2dcd1..f0947282d 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -225,19 +225,17 @@ struct hb_is_iterable /* hb_is_iterator() / hb_is_random_access_iterator() / hb_is_sorted_iterator() */ -template -struct _hb_is_iterator_of -{ - char operator () (...) { return 0; } - template int operator () (hb_iter_t *) { return 0; } - template int operator () (hb_iter_t *) { return 0; } - template int operator () (hb_iter_t *) { return 0; } - template int operator () (hb_iter_t *) { return 0; } - static_assert (sizeof (char) != sizeof (int), ""); -}; +template +static inline char _hb_is_iterator_of (hb_priority<0>, const void *) { return 0; } +template +static inline int _hb_is_iterator_of (hb_priority<2>, hb_iter_t *) { return 0; } + template struct hb_is_iterator_of { enum { - value = sizeof (int) == sizeof (hb_declval (_hb_is_iterator_of) (hb_declval (Iter*))) }; }; + value = sizeof (int) == sizeof (_hb_is_iterator_of (hb_prioritize, hb_declval (Iter*))) }; }; #define hb_is_iterator_of(Iter, Item) hb_is_iterator_of::value #define hb_is_iterator(Iter) hb_is_iterator_of (Iter, typename Iter::item_t) From 3a7f5bdd18314676425ec811199767a5f8e65a40 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Apr 2019 14:40:01 -0700 Subject: [PATCH 52/69] Rewrite hb_is_signed() --- src/hb-meta.hh | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index 005420364..c3efe48a6 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -134,15 +134,17 @@ template struct hb_is_same : hb_true_t {}; #define hb_is_same(T, T2) hb_is_same::value template struct hb_is_signed; -/* https://github.com/harfbuzz/harfbuzz/issues/1535 */ -template <> struct hb_is_signed { enum { value = true }; }; -template <> struct hb_is_signed { enum { value = true }; }; -template <> struct hb_is_signed { enum { value = true }; }; -template <> struct hb_is_signed { enum { value = true }; }; -template <> struct hb_is_signed { enum { value = false }; }; -template <> struct hb_is_signed { enum { value = false }; }; -template <> struct hb_is_signed { enum { value = false }; }; -template <> struct hb_is_signed { enum { value = false }; }; +template <> struct hb_is_signed { enum { value = CHAR_MIN < 0 }; }; +template <> struct hb_is_signed { enum { value = true }; }; +template <> struct hb_is_signed { enum { value = false }; }; +template <> struct hb_is_signed { enum { value = true }; }; +template <> struct hb_is_signed { enum { value = false }; }; +template <> struct hb_is_signed { enum { value = true }; }; +template <> struct hb_is_signed { enum { value = false }; }; +template <> struct hb_is_signed { enum { value = true }; }; +template <> struct hb_is_signed { enum { value = false }; }; +template <> struct hb_is_signed { enum { value = true }; }; +template <> struct hb_is_signed { enum { value = false }; }; #define hb_is_signed(T) hb_is_signed::value template struct hb_int_min { static constexpr T value = 0; }; From 408c1daeb4ff86d2204ed1bdd059513357ada392 Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Fri, 29 Mar 2019 10:34:32 -0700 Subject: [PATCH 53/69] [subset] subset name table step 1, write out table unmodified, use accelerator to access string --- src/hb-ot-name-table.hh | 53 +++++++++++++++++++++++++++++++++++++++++ src/hb-subset.cc | 4 ++++ 2 files changed, 57 insertions(+) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index fca509149..bacd5a8e6 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -158,6 +158,59 @@ struct name unsigned int get_size () const { return min_size + count * nameRecordZ.item_size; } + size_t get_subsetted_size(const name *source_name, hb_subset_plan_t *plan, hb_set_t *name_record_ids_to_retain) const + { + size_t result = min_size; + result += count * NameRecord::static_size; + + hb_face_t *face = plan->source; + accelerator_t acc; + acc.init (face); + + for(unsigned int i = 0; iadd(i); + } + } + + acc.fini(); + + return result; + } + + void serialize(void *dest, const void *source, size_t dest_size) const + { + memcpy(dest, source, dest_size); + } + + bool subset(hb_subset_plan_t *plan) const + { + hb_set_t *name_record_ids_to_retain = hb_set_create(); + size_t dest_size = get_subsetted_size(this, plan, name_record_ids_to_retain); + name *dest = (name *) malloc (dest_size); + if(unlikely (!dest)) + { + DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for name subset output.", + (unsigned long) dest_size); + return false; + } + + serialize(dest, this, dest_size); + hb_set_destroy(name_record_ids_to_retain); + + hb_blob_t *name_prime_blob = hb_blob_create((const char *) dest, + dest_size, + HB_MEMORY_MODE_READONLY, + dest, + free); + bool result = plan->add_table (HB_OT_TAG_name, name_prime_blob); + hb_blob_destroy (name_prime_blob); + + return result; + } bool sanitize_records (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); diff --git a/src/hb-subset.cc b/src/hb-subset.cc index bccb98d62..333e7d484 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -43,6 +43,7 @@ #include "hb-ot-cff1-table.hh" #include "hb-ot-cff2-table.hh" #include "hb-ot-vorg-table.hh" +#include "hb-ot-name-table.hh" #include "hb-ot-layout-gsub-table.hh" #include "hb-ot-layout-gpos-table.hh" @@ -158,6 +159,9 @@ _subset_table (hb_subset_plan_t *plan, case HB_OT_TAG_hdmx: result = _subset (plan); break; + case HB_OT_TAG_name: + result = _subset (plan); + break; case HB_OT_TAG_head: // TODO that won't work well if there is no glyf DEBUG_MSG(SUBSET, nullptr, "skip head, handled by glyf"); From 2637a81615c80443911a603cbd161ade525c79f1 Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Tue, 2 Apr 2019 13:38:27 -0700 Subject: [PATCH 54/69] [subset] subset name table step 2, add implementation for collecting subset elements and serialize method --- src/hb-ot-name-table.hh | 131 +++++++++++++++++++++++++++++++++------- 1 file changed, 109 insertions(+), 22 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index bacd5a8e6..a387e6e38 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -95,6 +95,28 @@ struct NameRecord return UNSUPPORTED; } + bool serialize (hb_serialize_context_t *c, const NameRecord& origin_namerecord, unsigned int *new_offset) + { + TRACE_SERIALIZE (this); + + if (unlikely (!c->allocate_size (NameRecord::static_size))) + { + DEBUG_MSG (SUBSET, nullptr, "Couldn't allocate enough space for NameRecord: %d.", + NameRecord::static_size); + return_trace (false); + } + + this->platformID.set (origin_namerecord.platformID); + this->encodingID.set (origin_namerecord.encodingID); + this->languageID.set (origin_namerecord.languageID); + this->nameID.set (origin_namerecord.nameID); + this->length.set (origin_namerecord.length); + this->offset.set (*new_offset); + *new_offset += origin_namerecord.length; + + return_trace (true); + } + bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -158,59 +180,124 @@ struct name unsigned int get_size () const { return min_size + count * nameRecordZ.item_size; } - size_t get_subsetted_size(const name *source_name, hb_subset_plan_t *plan, hb_set_t *name_record_ids_to_retain) const + size_t get_subsetted_size (const name *source_name, + const hb_subset_plan_t *plan, + hb_vector_t& name_record_idx_to_retain) const { size_t result = min_size; - result += count * NameRecord::static_size; hb_face_t *face = plan->source; accelerator_t acc; acc.init (face); - for(unsigned int i = 0; iadd(i); - } + if (format == 0 && (unsigned int) nameRecordZ[i].nameID > 25) + continue; + result += acc.get_name (i).get_size (); + name_record_idx_to_retain.push (i); } - acc.fini(); + acc.fini (); + + result += name_record_idx_to_retain.length * NameRecord::static_size; return result; } - void serialize(void *dest, const void *source, size_t dest_size) const + bool serialize (hb_serialize_context_t *c, + const name *source_name, + const hb_subset_plan_t *plan, + const hb_vector_t& name_record_idx_to_retain) { - memcpy(dest, source, dest_size); + TRACE_SERIALIZE (this); + + if (unlikely (!c->extend_min ((*this)))) return_trace (false); + + this->format.set (source_name->format); + this->count.set (name_record_idx_to_retain.length); + this->stringOffset.set (min_size + name_record_idx_to_retain.length * NameRecord::static_size); + + //write new NameRecord + unsigned int new_offset = 0; + for (unsigned int i = 0; i < name_record_idx_to_retain.length; i++) + { + unsigned int idx = name_record_idx_to_retain[i]; + if (unlikely (idx >= source_name->count)) + { + DEBUG_MSG (SUBSET, nullptr, "Invalid index: %d.", idx); + return_trace (false); + } + + const NameRecord &namerec = source_name->nameRecordZ[idx]; + + if (!c->start_embed ()->serialize (c, namerec, &new_offset)) + return_trace (false); + } + + hb_face_t *face = plan->source; + accelerator_t acc; + acc.init (face); + + for (unsigned int i = 0; i < name_record_idx_to_retain.length; i++) + { + unsigned int idx = name_record_idx_to_retain[i]; + unsigned int size = acc.get_name (idx).get_size (); + char *new_pos = c->allocate_size (size); + + if (unlikely (new_pos == nullptr)) + { + acc.fini (); + DEBUG_MSG (SUBSET, nullptr, "Couldn't allocate enough space for Name string: %d.", + size); + return_trace (false); + } + + unsigned int origin_offset = source_name->stringOffset + source_name->nameRecordZ[idx].offset; + + memcpy (new_pos, source_name + origin_offset, size); + } + + acc.fini (); + + return_trace (true); } - bool subset(hb_subset_plan_t *plan) const + bool subset (hb_subset_plan_t *plan) const { - hb_set_t *name_record_ids_to_retain = hb_set_create(); - size_t dest_size = get_subsetted_size(this, plan, name_record_ids_to_retain); + hb_vector_t name_record_idx_to_retain; + + size_t dest_size = get_subsetted_size (this, plan, name_record_idx_to_retain); name *dest = (name *) malloc (dest_size); if(unlikely (!dest)) { - DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for name subset output.", + DEBUG_MSG (SUBSET, nullptr, "Unable to alloc %lu for name subset output.", (unsigned long) dest_size); return false; } - serialize(dest, this, dest_size); - hb_set_destroy(name_record_ids_to_retain); + hb_serialize_context_t c (dest, dest_size); + name *name_prime = c.start_serialize (); + if (!name_prime || !name_prime->serialize (&c, this, plan, name_record_idx_to_retain)) + { + free (dest); + DEBUG_MSG (SUBSET, nullptr, "Failed to serialize write new name."); + c.end_serialize (); + return false; + } + c.end_serialize (); - hb_blob_t *name_prime_blob = hb_blob_create((const char *) dest, - dest_size, - HB_MEMORY_MODE_READONLY, - dest, - free); + hb_blob_t *name_prime_blob = hb_blob_create ((const char *) dest, + dest_size, + HB_MEMORY_MODE_READONLY, + dest, + free); bool result = plan->add_table (HB_OT_TAG_name, name_prime_blob); hb_blob_destroy (name_prime_blob); return result; } + bool sanitize_records (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); From e501ea143d1e63974903cdb41932c50f4222ff4e Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Fri, 5 Apr 2019 10:05:55 -0700 Subject: [PATCH 55/69] [subset] Subset name table step 3, add --nameids option to guide the selection of which name records to keep in the subset method. --- src/hb-ot-name-table.hh | 28 ++++++++++++++----------- src/hb-subset-input.cc | 8 ++++++++ src/hb-subset-input.hh | 3 ++- src/hb-subset-plan.cc | 10 +++++---- src/hb-subset-plan.hh | 3 +++ src/hb-subset.h | 3 +++ util/hb-subset.cc | 1 + util/options.cc | 45 +++++++++++++++++++++++++++++++++++++++++ util/options.hh | 8 ++++++++ 9 files changed, 92 insertions(+), 17 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index a387e6e38..cdb8dba54 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -106,12 +106,12 @@ struct NameRecord return_trace (false); } - this->platformID.set (origin_namerecord.platformID); - this->encodingID.set (origin_namerecord.encodingID); - this->languageID.set (origin_namerecord.languageID); - this->nameID.set (origin_namerecord.nameID); - this->length.set (origin_namerecord.length); - this->offset.set (*new_offset); + this->platformID = origin_namerecord.platformID; + this->encodingID = origin_namerecord.encodingID; + this->languageID = origin_namerecord.languageID; + this->nameID = origin_namerecord.nameID; + this->length = origin_namerecord.length; + this->offset = *new_offset; *new_offset += origin_namerecord.length; return_trace (true); @@ -194,6 +194,9 @@ struct name { if (format == 0 && (unsigned int) nameRecordZ[i].nameID > 25) continue; + if (!hb_set_is_empty (plan->name_ids) && + !hb_set_has (plan->name_ids, source_name->nameRecordZ[i].nameID)) + continue; result += acc.get_name (i).get_size (); name_record_idx_to_retain.push (i); } @@ -214,9 +217,9 @@ struct name if (unlikely (!c->extend_min ((*this)))) return_trace (false); - this->format.set (source_name->format); - this->count.set (name_record_idx_to_retain.length); - this->stringOffset.set (min_size + name_record_idx_to_retain.length * NameRecord::static_size); + this->format = source_name->format; + this->count = name_record_idx_to_retain.length; + this->stringOffset = min_size + name_record_idx_to_retain.length * NameRecord::static_size; //write new NameRecord unsigned int new_offset = 0; @@ -253,9 +256,10 @@ struct name return_trace (false); } - unsigned int origin_offset = source_name->stringOffset + source_name->nameRecordZ[idx].offset; - - memcpy (new_pos, source_name + origin_offset, size); + const HBUINT8* source_string_pool = (source_name + source_name->stringOffset).arrayZ; + unsigned int name_record_offset = source_name->nameRecordZ[idx].offset; + + memcpy (new_pos, source_string_pool + name_record_offset, size); } acc.fini (); diff --git a/src/hb-subset-input.cc b/src/hb-subset-input.cc index 4d203b545..b3b27d427 100644 --- a/src/hb-subset-input.cc +++ b/src/hb-subset-input.cc @@ -44,6 +44,7 @@ hb_subset_input_create_or_fail () input->unicodes = hb_set_create (); input->glyphs = hb_set_create (); + input->name_ids = hb_set_create (); input->drop_hints = false; input->drop_layout = true; input->desubroutinize = false; @@ -81,6 +82,7 @@ hb_subset_input_destroy (hb_subset_input_t *subset_input) hb_set_destroy (subset_input->unicodes); hb_set_destroy (subset_input->glyphs); + hb_set_destroy (subset_input->name_ids); free (subset_input); } @@ -109,6 +111,12 @@ hb_subset_input_glyph_set (hb_subset_input_t *subset_input) return subset_input->glyphs; } +HB_EXTERN hb_set_t * +hb_subset_input_nameid_set (hb_subset_input_t *subset_input) +{ + return subset_input->name_ids; +} + HB_EXTERN void hb_subset_input_set_drop_hints (hb_subset_input_t *subset_input, hb_bool_t drop_hints) diff --git a/src/hb-subset-input.hh b/src/hb-subset-input.hh index 04d6e121b..d01fecee0 100644 --- a/src/hb-subset-input.hh +++ b/src/hb-subset-input.hh @@ -40,6 +40,7 @@ struct hb_subset_input_t hb_set_t *unicodes; hb_set_t *glyphs; + hb_set_t *name_ids; bool drop_hints : 1; bool drop_layout : 1; @@ -49,7 +50,7 @@ struct hb_subset_input_t * * features * lookups - * nameIDs + * name_ids * ... */ }; diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index 6e32ed774..fe636b190 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -205,12 +205,13 @@ hb_subset_plan_create (hb_face_t *face, plan->drop_layout = input->drop_layout; plan->desubroutinize = input->desubroutinize; plan->retain_gids = input->retain_gids; - plan->unicodes = hb_set_create(); + plan->unicodes = hb_set_create (); + plan->name_ids = hb_set_reference (input->name_ids); plan->source = hb_face_reference (face); plan->dest = hb_face_builder_create (); - plan->codepoint_to_glyph = hb_map_create(); - plan->glyph_map = hb_map_create(); - plan->reverse_glyph_map = hb_map_create(); + plan->codepoint_to_glyph = hb_map_create (); + plan->glyph_map = hb_map_create (); + plan->reverse_glyph_map = hb_map_create (); plan->_glyphset = _populate_gids_to_retain (face, input->unicodes, input->glyphs, @@ -239,6 +240,7 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan) if (!hb_object_destroy (plan)) return; hb_set_destroy (plan->unicodes); + hb_set_destroy (plan->name_ids); hb_face_destroy (plan->source); hb_face_destroy (plan->dest); hb_map_destroy (plan->codepoint_to_glyph); diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh index afaeff4e8..abbab5e22 100644 --- a/src/hb-subset-plan.hh +++ b/src/hb-subset-plan.hh @@ -47,6 +47,9 @@ struct hb_subset_plan_t // For each cp that we'd like to retain maps to the corresponding gid. hb_set_t *unicodes; + //name_ids we would like to retain + hb_set_t *name_ids; + // The glyph subset hb_map_t *codepoint_to_glyph; diff --git a/src/hb-subset.h b/src/hb-subset.h index 657709ec8..50345061c 100644 --- a/src/hb-subset.h +++ b/src/hb-subset.h @@ -54,6 +54,9 @@ hb_subset_input_unicode_set (hb_subset_input_t *subset_input); HB_EXTERN hb_set_t * hb_subset_input_glyph_set (hb_subset_input_t *subset_input); +HB_EXTERN hb_set_t * +hb_subset_input_nameid_set (hb_subset_input_t *subset_input); + HB_EXTERN void hb_subset_input_set_drop_hints (hb_subset_input_t *subset_input, hb_bool_t drop_hints); diff --git a/util/hb-subset.cc b/util/hb-subset.cc index 33e584b75..682ca4c34 100644 --- a/util/hb-subset.cc +++ b/util/hb-subset.cc @@ -93,6 +93,7 @@ struct subset_consumer_t hb_subset_input_set_drop_hints (input, subset_options.drop_hints); hb_subset_input_set_retain_gids (input, subset_options.retain_gids); hb_subset_input_set_desubroutinize (input, subset_options.desubroutinize); + hb_set_set (hb_subset_input_nameid_set (input), subset_options.name_ids); hb_face_t *face = hb_font_get_face (font); diff --git a/util/options.cc b/util/options.cc index c5a4f0f0b..a9b3fc77e 100644 --- a/util/options.cc +++ b/util/options.cc @@ -971,6 +971,49 @@ format_options_t::serialize_buffer_of_glyphs (hb_buffer_t *buffer, g_string_append_c (gs, '\n'); } +static gboolean +parse_nameids (const char *name G_GNUC_UNUSED, + const char *arg, + gpointer data, + GError **error G_GNUC_UNUSED) +{ + subset_options_t *subset_opts = (subset_options_t *) data; + + hb_set_t *name_ids = hb_set_create (); + char *s = (char *) arg; + char *p; + + while (s && *s) + { + while (*s && strchr ("<+>{},;&#\\xXuUnNiI\n\t\v\f\r ", *s)) + s++; + if (!*s) + break; + + errno = 0; + hb_codepoint_t u = strtoul (s, &p, 10); + if (errno || s == p) + { + hb_set_destroy (name_ids); + g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, + "Failed parsing nameID values at: '%s'", s); + return false; + } + + hb_set_add (name_ids, u); + + s = p; + } + + hb_set_t *prev = subset_opts->name_ids; + subset_opts->name_ids = hb_set_reference (name_ids); + hb_set_destroy (prev); + hb_set_destroy (name_ids); + + return true; +} + + void subset_options_t::add_options (option_parser_t *parser) { @@ -980,6 +1023,7 @@ subset_options_t::add_options (option_parser_t *parser) {"no-hinting", 0, 0, G_OPTION_ARG_NONE, &this->drop_hints, "Whether to drop hints", nullptr}, {"retain-gids", 0, 0, G_OPTION_ARG_NONE, &this->retain_gids, "If set don't renumber glyph ids in the subset.", nullptr}, {"desubroutinize", 0, 0, G_OPTION_ARG_NONE, &this->desubroutinize, "Remove CFF/CFF2 use of subroutines", nullptr}, + {"name-IDs", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_nameids, "Subset specified nameids", "list of int numbers"}, {nullptr} }; @@ -989,3 +1033,4 @@ subset_options_t::add_options (option_parser_t *parser) "Options subsetting", this); } + diff --git a/util/options.hh b/util/options.hh index 84139f55c..2691e2269 100644 --- a/util/options.hh +++ b/util/options.hh @@ -677,16 +677,24 @@ struct subset_options_t : option_group_t drop_hints = false; retain_gids = false; desubroutinize = false; + name_ids = hb_set_create (); add_options (parser); } + virtual ~subset_options_t () + { + hb_set_destroy (name_ids); + } + + void add_options (option_parser_t *parser); hb_bool_t keep_layout; hb_bool_t drop_hints; hb_bool_t retain_gids; hb_bool_t desubroutinize; + hb_set_t *name_ids; }; /* fallback implementation for scalbn()/scalbnf() for pre-2013 MSVC */ From 6faac8df83bb59f08e5d329e76435ba438b2ea54 Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Wed, 10 Apr 2019 16:38:35 -0700 Subject: [PATCH 56/69] [subset] Subsetting Name Table Step 4 Add unit test and integration test --- test/api/Makefile.am | 2 + test/api/fonts/nameID.expected.ttf | Bin 0 -> 170696 bytes test/api/fonts/nameID.origin.ttf | Bin 0 -> 170976 bytes test/api/hb-subset-test.h | 9 +++ test/api/test-subset-nameids.c | 58 ++++++++++++++++++ .../Roboto-Regular.abc.name-ids.61,62,63.ttf | Bin 0 -> 2168 bytes .../Roboto-Regular.abc.name-ids.61,63.ttf | Bin 0 -> 1988 bytes .../basics/Roboto-Regular.abc.name-ids.61.ttf | Bin 0 -> 1792 bytes .../basics/Roboto-Regular.abc.name-ids.62.ttf | Bin 0 -> 1740 bytes .../basics/Roboto-Regular.abc.name-ids.63.ttf | Bin 0 -> 1716 bytes test/subset/data/profiles/name-ids.txt | 1 + test/subset/data/tests/basics.tests | 1 + 12 files changed, 71 insertions(+) create mode 100644 test/api/fonts/nameID.expected.ttf create mode 100644 test/api/fonts/nameID.origin.ttf create mode 100644 test/api/test-subset-nameids.c create mode 100644 test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61,62,63.ttf create mode 100644 test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61,63.ttf create mode 100644 test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61.ttf create mode 100644 test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.62.ttf create mode 100644 test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.63.ttf create mode 100644 test/subset/data/profiles/name-ids.txt diff --git a/test/api/Makefile.am b/test/api/Makefile.am index 67d66e16d..9d7b3198c 100644 --- a/test/api/Makefile.am +++ b/test/api/Makefile.am @@ -52,6 +52,7 @@ TEST_PROGS = \ test-subset-cff2 \ test-unicode \ test-version \ + test-subset-nameids \ $(NULL) test_subset_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la @@ -64,6 +65,7 @@ test_subset_post_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la test_subset_vmtx_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la test_subset_cff1_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la test_subset_cff2_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la +test_subset_nameids_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la test_unicode_CPPFLAGS = \ $(AM_CPPFLAGS) \ diff --git a/test/api/fonts/nameID.expected.ttf b/test/api/fonts/nameID.expected.ttf new file mode 100644 index 0000000000000000000000000000000000000000..ccd4b8bcd26816e7ffcd6afa58306373bc0534d9 GIT binary patch literal 170696 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%0Dkep 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 literal 0 HcmV?d00001 diff --git a/test/api/hb-subset-test.h b/test/api/hb-subset-test.h index 3e759a8a9..8f32aee67 100644 --- a/test/api/hb-subset-test.h +++ b/test/api/hb-subset-test.h @@ -65,6 +65,15 @@ hb_subset_test_create_input_from_glyphs (const hb_set_t *glyphs) return input; } +static inline hb_subset_input_t * +hb_subset_test_create_input_from_nameids (const hb_set_t *name_ids) +{ + hb_subset_input_t *input = hb_subset_input_create_or_fail (); + hb_set_t * input_name_ids = hb_subset_input_nameid_set (input); + hb_set_union (input_name_ids, name_ids); + return input; +} + static inline hb_face_t * hb_subset_test_create_subset (hb_face_t *source, hb_subset_input_t *input) diff --git a/test/api/test-subset-nameids.c b/test/api/test-subset-nameids.c new file mode 100644 index 000000000..0057a7b75 --- /dev/null +++ b/test/api/test-subset-nameids.c @@ -0,0 +1,58 @@ +/* + * Copyright © 2018 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Garret Rieger + */ + +#include "hb-test.h" +#include "hb-subset-test.h" + +static void +test_subset_nameids (void) +{ + hb_face_t *face_origin = hb_test_open_font_file ("fonts/nameID.origin.ttf"); + hb_face_t *face_expected = hb_test_open_font_file ("fonts/nameID.expected.ttf"); + + hb_set_t *name_ids = hb_set_create(); + hb_face_t *face_subset; + hb_set_add (name_ids, 0); + hb_set_add (name_ids, 9); + face_subset = hb_subset_test_create_subset (face_origin, hb_subset_test_create_input_from_nameids (name_ids)); + hb_set_destroy (name_ids); + + hb_subset_test_check (face_expected, face_subset, HB_TAG ('n','a','m','e')); + + hb_face_destroy (face_subset); + hb_face_destroy (face_origin); + hb_face_destroy (face_expected); +} + +int +main (int argc, char **argv) +{ + hb_test_init (&argc, &argv); + + hb_test_add (test_subset_nameids); + + return hb_test_run(); +} diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61,62,63.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61,62,63.ttf new file mode 100644 index 0000000000000000000000000000000000000000..12d92081b31eda6deaf2aa8b62e69c0535dfe225 GIT binary patch literal 2168 zcmZuydu&rx82`?_x9x3Lw%b`&*oEzu%ib*;+o&)Xm~k866vj5>cHyzo?nPEsSO=4c zqP%8#OcY}TL1Ks^8ab`#HipR(LE{5_fpI39nD7T05-_462(8~~J0`}{+~4_r-~G;a ze&0Dg=K=wMG}s0_1eP`ymj*kYO9kL>ptr^A_XI#D*8zkU}d;G23py>~s-->*0pt~m+^MeohW9)rkV{71zw%eZp=!2+tF>v6IUE_ZfmOvKd z!&4DkL7^pm9<@nS`5GwHXw+6Lhi#ej-Ekry5z>)d^ZM+n$@JS7+qTDW6$ZHm5vSouQwsmb+YKr5QGh z)iyb&)b-#TRhewf;PWNZv+p0fK*+DBgB!fN&h(t$G;&GEji#)4O+65OH>fo1`e4u7 zBg;KKzJ<$P(MFC(Q(xAkea(x0{&dA!+y>YiyCx`lfK-?YZISd$naN9+D33LZ#qmnb zSe$vhY#s?eUbY^Io|UZ=c~-W`%sOh8!s!#`P+kh#CTPiQV&&8sc?Q)|W^pO$mONIV z!IDu{>JpSIqZb0klfwZL`epdV=LhSTpWbl8Ua#(FJG$bR<_iS492riYFEn$=E99EwuYSxrfclX4D93hhqHJCs_==hQZ6 zs#^&up~b$CQmb@$d{oGZ_xPeU>6Hp%Ba0sHt|kEfkVNSiv|Sy`K*e_^+et-ws@Xnjx~S9#dhb+GXZY z?W!FWx~rYk=%{PdYEYsbC7K*Gzs5;Z9JByCvm=~G`jt?lHe7}K{ zEmIZ6D*Zzeu3OT_s+{DYRsBN>G;84ksFsJJfWKOeesd9pB8U))DG82r{lf`WfH%4U3rOr+WI-nBiL7Dp41?lK5{xWm(9K|g!6^nY2HBaUmyPIU zBYN40-bh*&8_VE2gX}DfTf<<0!B-4o3>IWza5sZu1>?FA*uf}-Blz_WK_6VgFWnMo zhTYHtPe3_W31=Y!`{5i$S)(mr>Cd$6=%~<0i>A_cl8Gc z0{iduz7HUZ0Nlj^?`RMtcnH_$aNRU8{8WF-dRf5u9*;+Th4&C>{Vm;>3DzUtjR8{=1(8=oV1VCg33uza{)EZh?F#g{Py| zvT}3QI%bubas?PPY0O$_i&%5ldlEoIAZDciAOHkW-YVjzs4?M~u@bjOGC7uBq1nH; z-S$MYj8-BQV*4Nim=UB}aYj#m} z{lj&tl5NQmO6BzDKRWXj$NltiXs>VT!szAk`Kw}a%((5OdNlSyNa>jR9LAYpqESW?L( znF&{zEHew)h;?bHY7Hr@$>7yOFxRDotHp^vP&B{ZcT75`8^65ghuB}C>&HI*O*$vd z3>`jk{NP0Qj8>sIxS=Y=pDZOS;E|l-UPUFKJFcric?C%?d<*?VnW9bZAWe&7V_VxsaDf+m zdWZq^ryb`(0q!&vhz&Z1KtcXw$C5!O>hMQsP>$wGw8Th09laYwJgtCFLBu>y%<(wl zgpZ$zpI%f?w-ge!Jlf5so|Jnd9Owu^00q2BBxClW`73X&Q1f zuGh(U2jj}^P9`{%W+oIhcWA0d2`k}E{;<-l40`=cEJ}D>=nH!)6$YK!5ZW%y&Ribb zV%X>LG&q?^G`It+!yY8qogzS=NLAi>iJk=@&Jk)@O#6C)K7on7-V}q$ES9##}ZAo^Y7>IyKeKCc|M{7&~}?7ygasIQVbE z_0I%8fu=cbvK^_=sdgJBRJ&?Ng&wz)862&hS`$jNqr`LvD{XQzql1;9GdUt9+_Vzz z)Xux`9s1@ZnC{ZfL#c2x=&>;s#VXTtGCsFdj=EgtV6N#o1-i9J8Mtldp-i~x#=NP5 zK?OuPnXllYW)AJFxuL4aCWBM~vs}v~tL+vHXL+qDhtyb-5H7x|-^X6D;ZDy{+|mlrtXmZ%Njfu1CYZ zM#?R-$R>lHqKwAsl9gtPGF`Q0d5OJp`=d!!fd7tZ*g*2VMK|PfqtPBR&ylIjZvX%Q literal 0 HcmV?d00001 diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.61.ttf new file mode 100644 index 0000000000000000000000000000000000000000..a699eea0bced6d31e273e28487cb5292da5bc78b GIT binary patch literal 1792 zcmZuyZERCj7=F*ax3{0H?d(?Ah3#H08{68_xs3{Qks8}ETx4aNaPOjQW!(p4b%k{> z4eI>DtAq$B+F$jX#WHAd$rQ)8I!U#+eubt?%irpvKeO=e*Bz z-uJ!lIrp4XAOPToIp87F+aGStPCV}d;0~iYJd#dkKq5aQzm8lRIhd6L?^;g-h~3Bs z#xmpSLw^px55PwO$i?yGbOvm24~{S6xNCg!$+4aDzimMK7Cy@psr0PfA~-PLcWiuO zG?}`!@0+KPuS6c1K*4d|au&IUeBDGkJ8S&`E+bDMw@prsBmupVdl1BQayG-Y@^*ap z4dn6@$@D0<;P@SfP9fivnVQZP(~v@bg^gzpjAqV`-TVSTzT6h5t#|4zi1CjYoHLRTiCZB*qdUp3$8aXk0YnJ)?X@#F0Nkt64)KRtNiiqKGS?mDHOD14BW`;L6_%6k_c zO-`q_?s!AH@OGi%b1SZckRJx<4SOF9I9aeEF}g|!6a@Sh-J>!xa6l+ZaMtf z)ggE1AF#@XBEY2^UiLlVD(PFkDc!zmZ?R1ywPS)(<6ni8FbHWDZ=EdQUb1hyDHR^J zx0G|6ZVWl#g(KuOtO6`2Ep7P9IAfq>YOO&kHixLq z%+RmVs6;_G43@87Qx!UA7?OcA_?s{Nn=cahuMqvGfGZGRBy$N&g`KKMOi&e7!3y3#9x0 z4T=xV1y1YU)L63kzK7cDtC=S3exx(7idmLOaP2BLv&8+6ceP5)vYt5fScl3i+cV>d z%{9!j55yx4r7Vtv!#$BTOmn`F+HU%}uH}u9PNuE!d0cjpSrwhF>sNc3<&L&DttrKN z5)YbH0p2WDoPhb=@>^=ibbg4zvkbyDB%AMLFvZ|FgAW-L8PwH~85S|aB4${`Ox|6~ zVj29(psp7Eh8P@Y@D+n1gDth_JjEa^qu&$)I~dJy8vjKMn1w5N<8FsRco~LaC$w{& za1ruw3@)LUuP_Wg?oE(+1)M?$_=Kb2!Sm`9S3(te2fX4EREXE`CNdj`H#44A!Hy@9 wokG**@WygMA56g>e6slT!6=Nw3{2vwJb+%MR@}$#{{LwNuNE6{c+TB_0gD%;od5s; literal 0 HcmV?d00001 diff --git a/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.62.ttf b/test/subset/data/expected/basics/Roboto-Regular.abc.name-ids.62.ttf new file mode 100644 index 0000000000000000000000000000000000000000..52706dc90320133d24a0a6c3109b9d1ef1bf8ec7 GIT binary patch literal 1740 zcmZuyUu;ul6hGg+x3|4rVQsC*c46F08DsR8&ao^o7pbuw;3BKrH1`r^>(>3l)mFB_ zG(i^?o!1Fse8Lb64~F0aUmKEb22B%r&WwaHG?=W_xS9q+Kt3nN`j&XPN!;^1E*? zCZ4=_>^;GEyZGJ7qcW^~_EzzS;)>&wE9Z;G`71ah+B*SGz#8ZWN14$~(1hzJS2?X$ z*)QmSw&C2^KyBwAQ0GD;z~!61Z6vR<-dlInm8(jNYYM4?3Cc}efRuC;7AW31S;Re7 z_TEv8k0~wH+!Z%M0YvF__6}A7j#G~9IOK+k6u*H{N>@!;iJ*G!wcR~EyCDigFeF0} zVAOd^01em~a*#S49EpafvoZ?_&kv4K=44xk8f7Di=L$MOLT?PjAK8aWr3#kLRBOgr zV59Ryt?Ywxh;$A{H&+s7j(a)PDK0gZC3cM1Rz%~_XHFpYn>vqL>OFPDvO2Xj zyfw^Sl?;6*kE$Fj+opVdW>DvIwyoMYgTHv;-+YO|e+|)p8gK>TOKdKIsZa!Ul?*{W zsAGjzEX)<7yU&bci8_|(Hu#o!nAaG*8HLBlHL-ck?lYI8xL?CdE|~8(mtl)|BWtNV zh{bC2OI}>Js*Ps3%HYxYB@OnQxn_u|%g`*|h@ssR;t+y7^9muB_c6ppUq?%$>IGK_ z7TKPMw&?*>7X@?AjxA+P?0vMYaShp|1CMux>PU068yo9tNt2&{rmIyY&3W?3(;Y$5 zTrZ6!cGi=o^vBybm$SGJ4|cb&CtJ;{seKhc&$YZg+)1`o0k21qNn737+O*C`T5Ytg zd3`z7n|P#B73BRjPMknx-}1Za*;Iaj;AMhHJ)6$=5M&5W5L_TA5p1YuGZZmH5i=Aq zldo-{Sc2aOHZ-8$0Ko}@uLw#6yBg3rLlDu>FN1&=0k*U++;=KuqMN|*x?GQIsRZP|&}DgcC5v<@ZHi43Uh4(hj28_DBYEwJdi1mL)jdSE0o znm+OS(EI4W3&5_8CZ;nW!y^FBMfAHzCtn=7^I_c$|&yjy@IFY(P z@$E~P`z7k|7#hkxc3eTf8}-()bavKt4GO3w)biw1G64g~fL%v$rW3Onp-og!zl&Ns znn(`|%VocyD~@_sW@@>x zwHr9Z4DM-BbDo+#W=Y5>U6acmE`H5D9_}N|ZTQ>O`e;L2`0a0Y_f-pflIP_m$MH{({!uXks7f#L| zJiM4=dV%8lov;cp;<_M!2J9UQ zkUAV3g@#|Dy$T7x6a0^oCfjCYRE=i*exMU1jK)O#kv&-~+E~22)-!!U6mO4G4ALY% zj6<-SD{&*o*jaOh72n{m*X9&)@JNWWpr*yfqnr(exDe!QyB^|VQ0wAiLsy^SH#JMM z4x}utOB+k1xYSUZ(J^e9EgFY@V;ph7(0RmEAJSpd>7 z#2vwIjf;(O<5`2xMO7Y&nyRjAFXyF$Og zBPs{evZ!9a;n(?`WvLdf;4fYHw_aiJUqj@d2Hb(z3Y&{#DV+SeN(R5~*Rex08sbW@ zyWfami#oPg7UbJvAzmKj%{aM(xh6KRS^dV<2)?i6iVX7u##PuR-pZIN_hYl#{E7$n zZOuljTo>e#`4tTg8o6eOs#l>|ycI>eJHR0TdFBxUEbnEA%ifOG2Gs*{0G8SQCwAyQ zq|1V_f7iAW6Z@WOZ>T1lbmW=Nz$RjjaB$0}N@C6z4tKSw#9VKkIMm@MCciQo-(5pY z8Hj}&OI6B_4|RuY$yREgHs6A<((l4wqmKESQDw@Rsa>gK!Fl;5ld)I^i1R;VjTS z>suWHpKuX0QHOG=1ANjM@Zfp%IXA+3_8xeh1*mY|#GA+-0@TrIl@vUQbP8=Q;Em;m nKA3{%@yX)T2g5K5GcXAWIEGQBQJkRr`hNz)t3?I@&w1saJT{N3 literal 0 HcmV?d00001 diff --git a/test/subset/data/profiles/name-ids.txt b/test/subset/data/profiles/name-ids.txt new file mode 100644 index 000000000..db42c09a4 --- /dev/null +++ b/test/subset/data/profiles/name-ids.txt @@ -0,0 +1 @@ +--name-IDs=0,1,2 diff --git a/test/subset/data/tests/basics.tests b/test/subset/data/tests/basics.tests index 4fc3f4eba..794510d87 100644 --- a/test/subset/data/tests/basics.tests +++ b/test/subset/data/tests/basics.tests @@ -6,6 +6,7 @@ default.txt drop-hints.txt drop-hints-retain-gids.txt retain-gids.txt +name-ids.txt SUBSETS: abc From 9ad14f56b6cf2a345104b3a897b52a1f4c0f33a5 Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Tue, 16 Apr 2019 11:20:58 -0700 Subject: [PATCH 57/69] [subset] update name table subsetting with new serializer --- src/hb-ot-name-table.hh | 156 +++++++++++++++++++++++----------------- 1 file changed, 90 insertions(+), 66 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index cdb8dba54..fde808c19 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -95,28 +95,6 @@ struct NameRecord return UNSUPPORTED; } - bool serialize (hb_serialize_context_t *c, const NameRecord& origin_namerecord, unsigned int *new_offset) - { - TRACE_SERIALIZE (this); - - if (unlikely (!c->allocate_size (NameRecord::static_size))) - { - DEBUG_MSG (SUBSET, nullptr, "Couldn't allocate enough space for NameRecord: %d.", - NameRecord::static_size); - return_trace (false); - } - - this->platformID = origin_namerecord.platformID; - this->encodingID = origin_namerecord.encodingID; - this->languageID = origin_namerecord.languageID; - this->nameID = origin_namerecord.nameID; - this->length = origin_namerecord.length; - this->offset = *new_offset; - *new_offset += origin_namerecord.length; - - return_trace (true); - } - bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); @@ -208,6 +186,88 @@ struct name return result; } + bool serialize_name_record (hb_serialize_context_t *c, + const name *source_name, + const hb_vector_t& name_record_idx_to_retain) + { + for (unsigned int i = 0; i < name_record_idx_to_retain.length; i++) + { + unsigned int idx = name_record_idx_to_retain[i]; + if (unlikely (idx >= source_name->count)) + { + DEBUG_MSG (SUBSET, nullptr, "Invalid index: %d.", idx); + return false; + } + + c->push (); + if (!c->embed (source_name->nameRecordZ[idx])) + return false; + } + + return true; + } + + bool serialize_strings (hb_serialize_context_t *c, + const name *source_name, + const hb_subset_plan_t *plan, + const hb_vector_t& name_record_idx_to_retain) + { + hb_face_t *face = plan->source; + accelerator_t acc; + acc.init (face); + + for (unsigned int i = 0; i < name_record_idx_to_retain.length; i++) + { + unsigned int idx = name_record_idx_to_retain[i]; + unsigned int size = acc.get_name (idx).get_size (); + + c->push (); + char *new_pos = c->allocate_size (size); + + if (unlikely (new_pos == nullptr)) + { + acc.fini (); + DEBUG_MSG (SUBSET, nullptr, "Couldn't allocate enough space for Name string: %u.", + size); + return false; + } + + const HBUINT8* source_string_pool = (source_name + source_name->stringOffset).arrayZ; + unsigned int name_record_offset = source_name->nameRecordZ[idx].offset; + + memcpy (new_pos, source_string_pool + name_record_offset, size); + } + + acc.fini (); + return true; + } + + bool pack_record_and_strings (name *dest_name_unpacked, + hb_serialize_context_t *c, + unsigned length) + { + hb_hashmap_t id_str_idx_map; + for (int i = length-1; i >= 0; i--) + { + unsigned objidx = c->pop_pack (); + id_str_idx_map.set ((unsigned)i, objidx); + } + + const void *base = & (dest_name_unpacked->nameRecordZ[length]); + for (int i = length-1; i >= 0; i--) + { + unsigned str_idx = id_str_idx_map.get ((unsigned)i); + NameRecord& namerecord = dest_name_unpacked->nameRecordZ[i]; + c->add_link (namerecord.offset, str_idx, base); + c->pop_pack (); + } + + if (c->in_error ()) + return false; + + return true; + } + bool serialize (hb_serialize_context_t *c, const name *source_name, const hb_subset_plan_t *plan, @@ -221,48 +281,15 @@ struct name this->count = name_record_idx_to_retain.length; this->stringOffset = min_size + name_record_idx_to_retain.length * NameRecord::static_size; - //write new NameRecord - unsigned int new_offset = 0; - for (unsigned int i = 0; i < name_record_idx_to_retain.length; i++) - { - unsigned int idx = name_record_idx_to_retain[i]; - if (unlikely (idx >= source_name->count)) - { - DEBUG_MSG (SUBSET, nullptr, "Invalid index: %d.", idx); - return_trace (false); - } - const NameRecord &namerec = source_name->nameRecordZ[idx]; + if (!serialize_name_record (c, source_name, name_record_idx_to_retain)) + return_trace (false); - if (!c->start_embed ()->serialize (c, namerec, &new_offset)) - return_trace (false); - } + if (!serialize_strings (c, source_name, plan, name_record_idx_to_retain)) + return_trace (false); - hb_face_t *face = plan->source; - accelerator_t acc; - acc.init (face); - - for (unsigned int i = 0; i < name_record_idx_to_retain.length; i++) - { - unsigned int idx = name_record_idx_to_retain[i]; - unsigned int size = acc.get_name (idx).get_size (); - char *new_pos = c->allocate_size (size); - - if (unlikely (new_pos == nullptr)) - { - acc.fini (); - DEBUG_MSG (SUBSET, nullptr, "Couldn't allocate enough space for Name string: %d.", - size); - return_trace (false); - } - - const HBUINT8* source_string_pool = (source_name + source_name->stringOffset).arrayZ; - unsigned int name_record_offset = source_name->nameRecordZ[idx].offset; - - memcpy (new_pos, source_string_pool + name_record_offset, size); - } - - acc.fini (); + if (!pack_record_and_strings (this, c, name_record_idx_to_retain.length)) + return_trace (false); return_trace (true); } @@ -289,13 +316,10 @@ struct name c.end_serialize (); return false; } + c.end_serialize (); - hb_blob_t *name_prime_blob = hb_blob_create ((const char *) dest, - dest_size, - HB_MEMORY_MODE_READONLY, - dest, - free); + hb_blob_t *name_prime_blob = c.copy_blob (); bool result = plan->add_table (HB_OT_TAG_name, name_prime_blob); hb_blob_destroy (name_prime_blob); From 1ca4b5c77012ed586413f39e730b03bf965e1305 Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Mon, 22 Apr 2019 11:31:23 -0700 Subject: [PATCH 58/69] [subset] Add unit test for str de-dup Also move the implementation of some methods from the .cc to the .hh --- src/Makefile.sources | 1 - src/hb-aat-layout.cc | 8 - src/hb-aat-layout.hh | 9 +- src/hb-ot-name-language.cc | 457 ------------------------- src/hb-ot-name-language.hh | 432 ++++++++++++++++++++++- test/api/fonts/nameID.dup.expected.ttf | Bin 0 -> 2340 bytes test/api/fonts/nameID.dup.origin.ttf | Bin 0 -> 170680 bytes test/api/test-subset-nameids.c | 21 ++ 8 files changed, 456 insertions(+), 472 deletions(-) delete mode 100644 src/hb-ot-name-language.cc create mode 100644 test/api/fonts/nameID.dup.expected.ttf create mode 100644 test/api/fonts/nameID.dup.origin.ttf diff --git a/src/Makefile.sources b/src/Makefile.sources index 17956c59d..803d229ac 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -84,7 +84,6 @@ HB_BASE_sources = \ hb-ot-math-table.hh \ hb-ot-math.cc \ hb-ot-maxp-table.hh \ - hb-ot-name-language.cc \ hb-ot-name-language.hh \ hb-ot-name-table.hh \ hb-ot-name.cc \ diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 5168a9c85..1966ded32 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -311,14 +311,6 @@ hb_aat_layout_track (const hb_ot_shape_plan_t *plan, trak.apply (&c); } - -hb_language_t -_hb_aat_language_get (hb_face_t *face, - unsigned int i) -{ - return face->table.ltag->get_language (i); -} - /** * hb_aat_layout_get_feature_types: * @face: a face object diff --git a/src/hb-aat-layout.hh b/src/hb-aat-layout.hh index 6340924bf..1ed009e12 100644 --- a/src/hb-aat-layout.hh +++ b/src/hb-aat-layout.hh @@ -30,6 +30,7 @@ #include "hb.hh" #include "hb-ot-shape.hh" +#include "hb-aat-ltag-table.hh" struct hb_aat_feature_mapping_t @@ -77,9 +78,13 @@ hb_aat_layout_track (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer); -HB_INTERNAL hb_language_t + +inline hb_language_t _hb_aat_language_get (hb_face_t *face, - unsigned int i); + unsigned int i) +{ + return face->table.ltag->get_language (i); +} #endif /* HB_AAT_LAYOUT_HH */ diff --git a/src/hb-ot-name-language.cc b/src/hb-ot-name-language.cc deleted file mode 100644 index 0e37e0acb..000000000 --- a/src/hb-ot-name-language.cc +++ /dev/null @@ -1,457 +0,0 @@ -/* - * Copyright © 2018 Google, Inc. - * - * This is part of HarfBuzz, a text shaping library. - * - * Permission is hereby granted, without written agreement and without - * license or royalty fees, to use, copy, modify, and distribute this - * software and its documentation for any purpose, provided that the - * above copyright notice and the following two paragraphs appear in - * all copies of this software. - * - * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR - * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN - * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, - * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO - * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - * - * Google Author(s): Behdad Esfahbod - */ - -#include "hb-ot-name-language.hh" - -/* Following two tables were generated by joining FreeType, FontConfig, - * and OpenType specification language lists, then filled in missing - * entries using: - * https://docs.microsoft.com/en-us/windows/desktop/intl/language-identifier-constants-and-strings - */ - -struct hb_ot_language_map_t -{ - static int cmp (const void *key, const void *item) - { - unsigned int a = * (unsigned int *) key; - unsigned int b = ((const hb_ot_language_map_t *) item)->code; - return a < b ? -1 : a > b ? +1 : 0; - } - - uint16_t code; - char lang[6]; -}; - -static const hb_ot_language_map_t -hb_ms_language_map[] = -{ - {0x0001, "ar"}, /* ??? */ - {0x0004, "zh"}, /* ??? */ - {0x0009, "en"}, /* ??? */ - {0x0401, "ar"}, /* Arabic (Saudi Arabia) */ - {0x0402, "bg"}, /* Bulgarian (Bulgaria) */ - {0x0403, "ca"}, /* Catalan (Catalan) */ - {0x0404, "zh-tw"}, /* Chinese (Taiwan) */ - {0x0405, "cs"}, /* Czech (Czech Republic) */ - {0x0406, "da"}, /* Danish (Denmark) */ - {0x0407, "de"}, /* German (Germany) */ - {0x0408, "el"}, /* Greek (Greece) */ - {0x0409, "en"}, /* English (United States) */ - {0x040A, "es"}, /* Spanish (Traditional Sort) (Spain) */ - {0x040B, "fi"}, /* Finnish (Finland) */ - {0x040C, "fr"}, /* French (France) */ - {0x040D, "he"}, /* Hebrew (Israel) */ - {0x040E, "hu"}, /* Hungarian (Hungary) */ - {0x040F, "is"}, /* Icelandic (Iceland) */ - {0x0410, "it"}, /* Italian (Italy) */ - {0x0411, "ja"}, /* Japanese (Japan) */ - {0x0412, "ko"}, /* Korean (Korea) */ - {0x0413, "nl"}, /* Dutch (Netherlands) */ - {0x0414, "no"}, /* Norwegian (Bokmal) (Norway) */ - {0x0415, "pl"}, /* Polish (Poland) */ - {0x0416, "pt"}, /* Portuguese (Brazil) */ - {0x0417, "rm"}, /* Romansh (Switzerland) */ - {0x0418, "ro"}, /* Romanian (Romania) */ - {0x0419, "ru"}, /* Russian (Russia) */ - {0x041A, "hr"}, /* Croatian (Croatia) */ - {0x041B, "sk"}, /* Slovak (Slovakia) */ - {0x041C, "sq"}, /* Albanian (Albania) */ - {0x041D, "sv"}, /* Swedish (Sweden) */ - {0x041E, "th"}, /* Thai (Thailand) */ - {0x041F, "tr"}, /* Turkish (Turkey) */ - {0x0420, "ur"}, /* Urdu (Islamic Republic of Pakistan) */ - {0x0421, "id"}, /* Indonesian (Indonesia) */ - {0x0422, "uk"}, /* Ukrainian (Ukraine) */ - {0x0423, "be"}, /* Belarusian (Belarus) */ - {0x0424, "sl"}, /* Slovenian (Slovenia) */ - {0x0425, "et"}, /* Estonian (Estonia) */ - {0x0426, "lv"}, /* Latvian (Latvia) */ - {0x0427, "lt"}, /* Lithuanian (Lithuania) */ - {0x0428, "tg"}, /* Tajik (Cyrillic) (Tajikistan) */ - {0x0429, "fa"}, /* Persian (Iran) */ - {0x042A, "vi"}, /* Vietnamese (Vietnam) */ - {0x042B, "hy"}, /* Armenian (Armenia) */ - {0x042C, "az"}, /* Azeri (Latin) (Azerbaijan) */ - {0x042D, "eu"}, /* Basque (Basque) */ - {0x042E, "hsb"}, /* Upper Sorbian (Germany) */ - {0x042F, "mk"}, /* Macedonian (FYROM) (Former Yugoslav Republic of Macedonia) */ - {0x0430, "st"}, /* ??? */ - {0x0431, "ts"}, /* ??? */ - {0x0432, "tn"}, /* Setswana (South Africa) */ - {0x0433, "ven"}, /* ??? */ - {0x0434, "xh"}, /* isiXhosa (South Africa) */ - {0x0435, "zu"}, /* isiZulu (South Africa) */ - {0x0436, "af"}, /* Afrikaans (South Africa) */ - {0x0437, "ka"}, /* Georgian (Georgia) */ - {0x0438, "fo"}, /* Faroese (Faroe Islands) */ - {0x0439, "hi"}, /* Hindi (India) */ - {0x043A, "mt"}, /* Maltese (Malta) */ - {0x043B, "se"}, /* Sami (Northern) (Norway) */ - {0x043C, "ga"}, /* ??? */ - {0x043D, "yi"}, /* ??? */ - {0x043E, "ms"}, /* Malay (Malaysia) */ - {0x043F, "kk"}, /* Kazakh (Kazakhstan) */ - {0x0440, "ky"}, /* Kyrgyz (Kyrgyzstan) */ - {0x0441, "sw"}, /* Kiswahili (Kenya) */ - {0x0442, "tk"}, /* Turkmen (Turkmenistan) */ - {0x0443, "uz"}, /* Uzbek (Latin) (Uzbekistan) */ - {0x0444, "tt"}, /* Tatar (Russia) */ - {0x0445, "bn"}, /* Bengali (India) */ - {0x0446, "pa"}, /* Punjabi (India) */ - {0x0447, "gu"}, /* Gujarati (India) */ - {0x0448, "or"}, /* Odia (formerly Oriya) (India) */ - {0x0449, "ta"}, /* Tamil (India) */ - {0x044A, "te"}, /* Telugu (India) */ - {0x044B, "kn"}, /* Kannada (India) */ - {0x044C, "ml"}, /* Malayalam (India) */ - {0x044D, "as"}, /* Assamese (India) */ - {0x044E, "mr"}, /* Marathi (India) */ - {0x044F, "sa"}, /* Sanskrit (India) */ - {0x0450, "mn"}, /* Mongolian (Cyrillic) (Mongolia) */ - {0x0451, "bo"}, /* Tibetan (PRC) */ - {0x0452, "cy"}, /* Welsh (United Kingdom) */ - {0x0453, "km"}, /* Khmer (Cambodia) */ - {0x0454, "lo"}, /* Lao (Lao P.D.R.) */ - {0x0455, "my"}, /* ??? */ - {0x0456, "gl"}, /* Galician (Galician) */ - {0x0457, "kok"}, /* Konkani (India) */ - {0x0458, "mni"}, /* ??? */ - {0x0459, "sd"}, /* ??? */ - {0x045A, "syr"}, /* Syriac (Syria) */ - {0x045B, "si"}, /* Sinhala (Sri Lanka) */ - {0x045C, "chr"}, /* ??? */ - {0x045D, "iu"}, /* Inuktitut (Canada) */ - {0x045E, "am"}, /* Amharic (Ethiopia) */ - {0x0460, "ks"}, /* ??? */ - {0x0461, "ne"}, /* Nepali (Nepal) */ - {0x0462, "fy"}, /* Frisian (Netherlands) */ - {0x0463, "ps"}, /* Pashto (Afghanistan) */ - {0x0464, "phi"}, /* Filipino (Philippines) */ - {0x0465, "div"}, /* Divehi (Maldives) */ - {0x0468, "ha"}, /* Hausa (Latin) (Nigeria) */ - {0x046A, "yo"}, /* Yoruba (Nigeria) */ - {0x046B, "quz"}, /* Quechua (Bolivia) */ - {0x046C, "nso"}, /* Sesotho sa Leboa (South Africa) */ - {0x046D, "ba"}, /* Bashkir (Russia) */ - {0x046E, "lb"}, /* Luxembourgish (Luxembourg) */ - {0x046F, "kl"}, /* Greenlandic (Greenland) */ - {0x0470, "ibo"}, /* Igbo (Nigeria) */ - {0x0471, "kau"}, /* ??? */ - {0x0472, "om"}, /* ??? */ - {0x0473, "ti"}, /* ??? */ - {0x0474, "gn"}, /* ??? */ - {0x0475, "haw"}, /* ??? */ - {0x0476, "la"}, /* ??? */ - {0x0477, "so"}, /* ??? */ - {0x0478, "ii"}, /* Yi (PRC) */ - {0x0479, "pap"}, /* ??? */ - {0x047A, "arn"}, /* Mapudungun (Chile) */ - {0x047C, "moh"}, /* Mohawk (Mohawk) */ - {0x047E, "br"}, /* Breton (France) */ - {0x0480, "ug"}, /* Uighur (PRC) */ - {0x0481, "mi"}, /* Maori (New Zealand) */ - {0x0482, "oc"}, /* Occitan (France) */ - {0x0483, "co"}, /* Corsican (France) */ - {0x0484, "gsw"}, /* Alsatian (France) */ - {0x0485, "sah"}, /* Yakut (Russia) */ - {0x0486, "qut"}, /* K'iche (Guatemala) */ - {0x0487, "rw"}, /* Kinyarwanda (Rwanda) */ - {0x0488, "wo"}, /* Wolof (Senegal) */ - {0x048C, "fa"}, /* Dari (Afghanistan) */ - {0x0801, "ar"}, /* Arabic (Iraq) */ - {0x0804, "zh-cn"}, /* Chinese (People’s Republic of China) */ - {0x0807, "de"}, /* German (Switzerland) */ - {0x0809, "en"}, /* English (United Kingdom) */ - {0x080A, "es"}, /* Spanish (Mexico) */ - {0x080C, "fr"}, /* French (Belgium) */ - {0x0810, "it"}, /* Italian (Switzerland) */ - {0x0812, "ko"}, /* ??? */ - {0x0813, "nl"}, /* Dutch (Belgium) */ - {0x0814, "nn"}, /* Norwegian (Nynorsk) (Norway) */ - {0x0816, "pt"}, /* Portuguese (Portugal) */ - {0x0818, "mo"}, /* ??? */ - {0x0819, "ru"}, /* ??? */ - {0x081A, "sr"}, /* Serbian (Latin) (Serbia) */ - {0x081D, "sv"}, /* Sweden (Finland) */ - {0x0820, "ur"}, /* ??? */ - {0x0827, "lt"}, /* ??? */ - {0x082C, "az"}, /* Azeri (Cyrillic) (Azerbaijan) */ - {0x082E, "dsb"}, /* Lower Sorbian (Germany) */ -//{0x083B, ""}, /* Sami (Northern) (Sweden) */ - {0x083C, "gd"}, /* Irish (Ireland) */ - {0x083E, "ms"}, /* Malay (Brunei Darussalam) */ - {0x0843, "uz"}, /* Uzbek (Cyrillic) (Uzbekistan) */ - {0x0845, "bn"}, /* Bengali (Bangladesh) */ - {0x0846, "ar"}, /* ??? */ - {0x0850, "mn"}, /* Mongolian (Traditional) (People’s Republic of China) */ - {0x0851, "dz"}, /* ??? */ - {0x085D, "iu"}, /* Inuktitut (Latin) (Canada) */ - {0x085F, "tzm"}, /* Tamazight (Latin) (Algeria) */ - {0x0861, "ne"}, /* ??? */ -//{0x086B, ""}, /* Quechua (Ecuador) */ - {0x0873, "ti"}, /* ??? */ - {0x0C01, "ar"}, /* Arabic (Egypt) */ - {0x0C04, "zh-hk"}, /* Chinese (Hong Kong S.A.R.) */ - {0x0C07, "de"}, /* German (Austria) */ - {0x0C09, "en"}, /* English (Australia) */ - {0x0C0A, "es"}, /* Spanish (Modern Sort) (Spain) */ - {0x0C0C, "fr"}, /* French (Canada) */ - {0x0C1A, "sr"}, /* Serbian (Cyrillic) (Serbia) */ - {0x0C3B, "se"}, /* Sami (Northern) (Finland) */ -//{0x0C6B, ""}, /* Quechua (Peru) */ - {0x1001, "ar"}, /* Arabic (Libya) */ - {0x1004, "zh-sg"}, /* Chinese (Singapore) */ - {0x1007, "de"}, /* German (Luxembourg) */ - {0x1009, "en"}, /* English (Canada) */ - {0x100A, "es"}, /* Spanish (Guatemala) */ - {0x100C, "fr"}, /* French (Switzerland) */ - {0x101A, "hr"}, /* Croatian (Latin) (Bosnia and Herzegovina) */ - {0x103B, "smj"}, /* Sami (Lule) (Norway) */ - {0x1401, "ar"}, /* Arabic (Algeria) */ -//{0x1404, ""}, /* Chinese (Macao S.A.R.) */ - {0x1407, "de"}, /* German (Liechtenstein) */ - {0x1409, "en"}, /* English (New Zealand) */ - {0x140A, "es"}, /* Spanish (Costa Rica) */ - {0x140C, "fr"}, /* French (Luxembourg) */ - {0x141A, "bs"}, /* Bosnian (Latin) (Bosnia and Herzegovina) */ -//{0x143B, ""}, /* Sami (Lule) (Sweden) */ - {0x1801, "ar"}, /* Arabic (Morocco) */ - {0x1809, "en"}, /* English (Ireland) */ - {0x180A, "es"}, /* Spanish (Panama) */ - {0x180C, "fr"}, /* French (Principality of Monaco) */ -//{0x181A, ""}, /* Serbian (Latin) (Bosnia and Herzegovina) */ - {0x183B, "sma"}, /* Sami (Southern) (Norway) */ - {0x1C01, "ar"}, /* Arabic (Tunisia) */ - {0x1C09, "en"}, /* English (South Africa) */ - {0x1C0A, "es"}, /* Spanish (Dominican Republic) */ - {0x1C0C, "fr"}, /* ??? */ -//{0x1C1A, ""}, /* Serbian (Cyrillic) (Bosnia and Herzegovina) */ -//{0x1C3B, ""}, /* Sami (Southern) (Sweden) */ - {0x2001, "ar"}, /* Arabic (Oman) */ - {0x2009, "en"}, /* English (Jamaica) */ - {0x200A, "es"}, /* Spanish (Venezuela) */ - {0x200C, "fr"}, /* ??? */ - {0x201A, "bs"}, /* Bosnian (Cyrillic) (Bosnia and Herzegovina) */ - {0x203B, "sms"}, /* Sami (Skolt) (Finland) */ - {0x2401, "ar"}, /* Arabic (Yemen) */ - {0x2409, "en"}, /* English (Caribbean) */ - {0x240A, "es"}, /* Spanish (Colombia) */ - {0x240C, "fr"}, /* ??? */ - {0x243B, "smn"}, /* Sami (Inari) (Finland) */ - {0x2801, "ar"}, /* Arabic (Syria) */ - {0x2809, "en"}, /* English (Belize) */ - {0x280A, "es"}, /* Spanish (Peru) */ - {0x280C, "fr"}, /* ??? */ - {0x2C01, "ar"}, /* Arabic (Jordan) */ - {0x2C09, "en"}, /* English (Trinidad and Tobago) */ - {0x2C0A, "es"}, /* Spanish (Argentina) */ - {0x2C0C, "fr"}, /* ??? */ - {0x3001, "ar"}, /* Arabic (Lebanon) */ - {0x3009, "en"}, /* English (Zimbabwe) */ - {0x300A, "es"}, /* Spanish (Ecuador) */ - {0x300C, "fr"}, /* ??? */ - {0x3401, "ar"}, /* Arabic (Kuwait) */ - {0x3409, "en"}, /* English (Republic of the Philippines) */ - {0x340A, "es"}, /* Spanish (Chile) */ - {0x340C, "fr"}, /* ??? */ - {0x3801, "ar"}, /* Arabic (U.A.E.) */ - {0x380A, "es"}, /* Spanish (Uruguay) */ - {0x380C, "fr"}, /* ??? */ - {0x3C01, "ar"}, /* Arabic (Bahrain) */ - {0x3C09, "en"}, /* ??? */ - {0x3C0A, "es"}, /* Spanish (Paraguay) */ - {0x3C0C, "fr"}, /* ??? */ - {0x4001, "ar"}, /* Arabic (Qatar) */ - {0x4009, "en"}, /* English (India) */ - {0x400A, "es"}, /* Spanish (Bolivia) */ - {0x4409, "en"}, /* English (Malaysia) */ - {0x440A, "es"}, /* Spanish (El Salvador) */ - {0x4809, "en"}, /* English (Singapore) */ - {0x480A, "es"}, /* Spanish (Honduras) */ - {0x4C0A, "es"}, /* Spanish (Nicaragua) */ - {0x500A, "es"}, /* Spanish (Puerto Rico) */ - {0x540A, "es"}, /* Spanish (United States) */ - {0xE40A, "es"}, /* ??? */ - {0xE40C, "fr"}, /* ??? */ -}; - -static const hb_ot_language_map_t -hb_mac_language_map[] = -{ - { 0, "en"}, /* English */ - { 1, "fr"}, /* French */ - { 2, "de"}, /* German */ - { 3, "it"}, /* Italian */ - { 4, "nl"}, /* Dutch */ - { 5, "sv"}, /* Swedish */ - { 6, "es"}, /* Spanish */ - { 7, "da"}, /* Danish */ - { 8, "pt"}, /* Portuguese */ - { 9, "no"}, /* Norwegian */ - { 10, "he"}, /* Hebrew */ - { 11, "ja"}, /* Japanese */ - { 12, "ar"}, /* Arabic */ - { 13, "fi"}, /* Finnish */ - { 14, "el"}, /* Greek */ - { 15, "is"}, /* Icelandic */ - { 16, "mt"}, /* Maltese */ - { 17, "tr"}, /* Turkish */ - { 18, "hr"}, /* Croatian */ - { 19, "zh-tw"}, /* Chinese (Traditional) */ - { 20, "ur"}, /* Urdu */ - { 21, "hi"}, /* Hindi */ - { 22, "th"}, /* Thai */ - { 23, "ko"}, /* Korean */ - { 24, "lt"}, /* Lithuanian */ - { 25, "pl"}, /* Polish */ - { 26, "hu"}, /* Hungarian */ - { 27, "et"}, /* Estonian */ - { 28, "lv"}, /* Latvian */ -//{ 29, ""}, /* Sami */ - { 30, "fo"}, /* Faroese */ - { 31, "fa"}, /* Farsi/Persian */ - { 32, "ru"}, /* Russian */ - { 33, "zh-cn"}, /* Chinese (Simplified) */ - { 34, "nl"}, /* Flemish */ - { 35, "ga"}, /* Irish Gaelic */ - { 36, "sq"}, /* Albanian */ - { 37, "ro"}, /* Romanian */ - { 38, "cs"}, /* Czech */ - { 39, "sk"}, /* Slovak */ - { 40, "sl"}, /* Slovenian */ - { 41, "yi"}, /* Yiddish */ - { 42, "sr"}, /* Serbian */ - { 43, "mk"}, /* Macedonian */ - { 44, "bg"}, /* Bulgarian */ - { 45, "uk"}, /* Ukrainian */ - { 46, "be"}, /* Byelorussian */ - { 47, "uz"}, /* Uzbek */ - { 48, "kk"}, /* Kazakh */ - { 49, "az"}, /* Azerbaijani (Cyrillic script) */ - { 50, "az"}, /* Azerbaijani (Arabic script) */ - { 51, "hy"}, /* Armenian */ - { 52, "ka"}, /* Georgian */ - { 53, "mo"}, /* Moldavian */ - { 54, "ky"}, /* Kirghiz */ - { 55, "tg"}, /* Tajiki */ - { 56, "tk"}, /* Turkmen */ - { 57, "mn"}, /* Mongolian (Mongolian script) */ - { 58, "mn"}, /* Mongolian (Cyrillic script) */ - { 59, "ps"}, /* Pashto */ - { 60, "ku"}, /* Kurdish */ - { 61, "ks"}, /* Kashmiri */ - { 62, "sd"}, /* Sindhi */ - { 63, "bo"}, /* Tibetan */ - { 64, "ne"}, /* Nepali */ - { 65, "sa"}, /* Sanskrit */ - { 66, "mr"}, /* Marathi */ - { 67, "bn"}, /* Bengali */ - { 68, "as"}, /* Assamese */ - { 69, "gu"}, /* Gujarati */ - { 70, "pa"}, /* Punjabi */ - { 71, "or"}, /* Oriya */ - { 72, "ml"}, /* Malayalam */ - { 73, "kn"}, /* Kannada */ - { 74, "ta"}, /* Tamil */ - { 75, "te"}, /* Telugu */ - { 76, "si"}, /* Sinhalese */ - { 77, "my"}, /* Burmese */ - { 78, "km"}, /* Khmer */ - { 79, "lo"}, /* Lao */ - { 80, "vi"}, /* Vietnamese */ - { 81, "id"}, /* Indonesian */ - { 82, "tl"}, /* Tagalog */ - { 83, "ms"}, /* Malay (Roman script) */ - { 84, "ms"}, /* Malay (Arabic script) */ - { 85, "am"}, /* Amharic */ - { 86, "ti"}, /* Tigrinya */ - { 87, "om"}, /* Galla */ - { 88, "so"}, /* Somali */ - { 89, "sw"}, /* Swahili */ - { 90, "rw"}, /* Kinyarwanda/Ruanda */ - { 91, "rn"}, /* Rundi */ - { 92, "ny"}, /* Nyanja/Chewa */ - { 93, "mg"}, /* Malagasy */ - { 94, "eo"}, /* Esperanto */ - {128, "cy"}, /* Welsh */ - {129, "eu"}, /* Basque */ - {130, "ca"}, /* Catalan */ - {131, "la"}, /* Latin */ - {132, "qu"}, /* Quechua */ - {133, "gn"}, /* Guarani */ - {134, "ay"}, /* Aymara */ - {135, "tt"}, /* Tatar */ - {136, "ug"}, /* Uighur */ - {137, "dz"}, /* Dzongkha */ - {138, "jw"}, /* Javanese (Roman script) */ - {139, "su"}, /* Sundanese (Roman script) */ - {140, "gl"}, /* Galician */ - {141, "af"}, /* Afrikaans */ - {142, "br"}, /* Breton */ - {143, "iu"}, /* Inuktitut */ - {144, "gd"}, /* Scottish Gaelic */ - {145, "gv"}, /* Manx Gaelic */ - {146, "ga"}, /* Irish Gaelic (with dot above) */ - {147, "to"}, /* Tongan */ - {148, "el"}, /* Greek (polytonic) */ - {149, "ik"}, /* Greenlandic */ - {150, "az"}, /* Azerbaijani (Roman script) */ -}; - - -static hb_language_t -_hb_ot_name_language_for (unsigned int code, - const hb_ot_language_map_t *array, - unsigned int len) -{ - const hb_ot_language_map_t *entry = (const hb_ot_language_map_t *) - hb_bsearch (&code, - array, - len, - sizeof (array[0]), - hb_ot_language_map_t::cmp); - - if (entry) - return hb_language_from_string (entry->lang, -1); - - return HB_LANGUAGE_INVALID; -} - -hb_language_t -_hb_ot_name_language_for_ms_code (unsigned int code) -{ - return _hb_ot_name_language_for (code, - hb_ms_language_map, - ARRAY_LENGTH (hb_ms_language_map)); -} - -hb_language_t -_hb_ot_name_language_for_mac_code (unsigned int code) -{ - return _hb_ot_name_language_for (code, - hb_mac_language_map, - ARRAY_LENGTH (hb_mac_language_map)); -} diff --git a/src/hb-ot-name-language.hh b/src/hb-ot-name-language.hh index 903076c0d..a5449764c 100644 --- a/src/hb-ot-name-language.hh +++ b/src/hb-ot-name-language.hh @@ -29,12 +29,436 @@ #include "hb.hh" +/* Following two tables were generated by joining FreeType, FontConfig, + * and OpenType specification language lists, then filled in missing + * entries using: + * https://docs.microsoft.com/en-us/windows/desktop/intl/language-identifier-constants-and-strings + */ -HB_INTERNAL hb_language_t -_hb_ot_name_language_for_ms_code (unsigned int code); +struct hb_ot_language_map_t +{ + static int cmp (const void *key, const void *item) + { + unsigned int a = * (unsigned int *) key; + unsigned int b = ((const hb_ot_language_map_t *) item)->code; + return a < b ? -1 : a > b ? +1 : 0; + } -HB_INTERNAL hb_language_t -_hb_ot_name_language_for_mac_code (unsigned int code); + uint16_t code; + char lang[6]; +}; + + +static const hb_ot_language_map_t +hb_ms_language_map[] = +{ + {0x0001, "ar"}, /* ??? */ + {0x0004, "zh"}, /* ??? */ + {0x0009, "en"}, /* ??? */ + {0x0401, "ar"}, /* Arabic (Saudi Arabia) */ + {0x0402, "bg"}, /* Bulgarian (Bulgaria) */ + {0x0403, "ca"}, /* Catalan (Catalan) */ + {0x0404, "zh-tw"}, /* Chinese (Taiwan) */ + {0x0405, "cs"}, /* Czech (Czech Republic) */ + {0x0406, "da"}, /* Danish (Denmark) */ + {0x0407, "de"}, /* German (Germany) */ + {0x0408, "el"}, /* Greek (Greece) */ + {0x0409, "en"}, /* English (United States) */ + {0x040A, "es"}, /* Spanish (Traditional Sort) (Spain) */ + {0x040B, "fi"}, /* Finnish (Finland) */ + {0x040C, "fr"}, /* French (France) */ + {0x040D, "he"}, /* Hebrew (Israel) */ + {0x040E, "hu"}, /* Hungarian (Hungary) */ + {0x040F, "is"}, /* Icelandic (Iceland) */ + {0x0410, "it"}, /* Italian (Italy) */ + {0x0411, "ja"}, /* Japanese (Japan) */ + {0x0412, "ko"}, /* Korean (Korea) */ + {0x0413, "nl"}, /* Dutch (Netherlands) */ + {0x0414, "no"}, /* Norwegian (Bokmal) (Norway) */ + {0x0415, "pl"}, /* Polish (Poland) */ + {0x0416, "pt"}, /* Portuguese (Brazil) */ + {0x0417, "rm"}, /* Romansh (Switzerland) */ + {0x0418, "ro"}, /* Romanian (Romania) */ + {0x0419, "ru"}, /* Russian (Russia) */ + {0x041A, "hr"}, /* Croatian (Croatia) */ + {0x041B, "sk"}, /* Slovak (Slovakia) */ + {0x041C, "sq"}, /* Albanian (Albania) */ + {0x041D, "sv"}, /* Swedish (Sweden) */ + {0x041E, "th"}, /* Thai (Thailand) */ + {0x041F, "tr"}, /* Turkish (Turkey) */ + {0x0420, "ur"}, /* Urdu (Islamic Republic of Pakistan) */ + {0x0421, "id"}, /* Indonesian (Indonesia) */ + {0x0422, "uk"}, /* Ukrainian (Ukraine) */ + {0x0423, "be"}, /* Belarusian (Belarus) */ + {0x0424, "sl"}, /* Slovenian (Slovenia) */ + {0x0425, "et"}, /* Estonian (Estonia) */ + {0x0426, "lv"}, /* Latvian (Latvia) */ + {0x0427, "lt"}, /* Lithuanian (Lithuania) */ + {0x0428, "tg"}, /* Tajik (Cyrillic) (Tajikistan) */ + {0x0429, "fa"}, /* Persian (Iran) */ + {0x042A, "vi"}, /* Vietnamese (Vietnam) */ + {0x042B, "hy"}, /* Armenian (Armenia) */ + {0x042C, "az"}, /* Azeri (Latin) (Azerbaijan) */ + {0x042D, "eu"}, /* Basque (Basque) */ + {0x042E, "hsb"}, /* Upper Sorbian (Germany) */ + {0x042F, "mk"}, /* Macedonian (FYROM) (Former Yugoslav Republic of Macedonia) */ + {0x0430, "st"}, /* ??? */ + {0x0431, "ts"}, /* ??? */ + {0x0432, "tn"}, /* Setswana (South Africa) */ + {0x0433, "ven"}, /* ??? */ + {0x0434, "xh"}, /* isiXhosa (South Africa) */ + {0x0435, "zu"}, /* isiZulu (South Africa) */ + {0x0436, "af"}, /* Afrikaans (South Africa) */ + {0x0437, "ka"}, /* Georgian (Georgia) */ + {0x0438, "fo"}, /* Faroese (Faroe Islands) */ + {0x0439, "hi"}, /* Hindi (India) */ + {0x043A, "mt"}, /* Maltese (Malta) */ + {0x043B, "se"}, /* Sami (Northern) (Norway) */ + {0x043C, "ga"}, /* ??? */ + {0x043D, "yi"}, /* ??? */ + {0x043E, "ms"}, /* Malay (Malaysia) */ + {0x043F, "kk"}, /* Kazakh (Kazakhstan) */ + {0x0440, "ky"}, /* Kyrgyz (Kyrgyzstan) */ + {0x0441, "sw"}, /* Kiswahili (Kenya) */ + {0x0442, "tk"}, /* Turkmen (Turkmenistan) */ + {0x0443, "uz"}, /* Uzbek (Latin) (Uzbekistan) */ + {0x0444, "tt"}, /* Tatar (Russia) */ + {0x0445, "bn"}, /* Bengali (India) */ + {0x0446, "pa"}, /* Punjabi (India) */ + {0x0447, "gu"}, /* Gujarati (India) */ + {0x0448, "or"}, /* Odia (formerly Oriya) (India) */ + {0x0449, "ta"}, /* Tamil (India) */ + {0x044A, "te"}, /* Telugu (India) */ + {0x044B, "kn"}, /* Kannada (India) */ + {0x044C, "ml"}, /* Malayalam (India) */ + {0x044D, "as"}, /* Assamese (India) */ + {0x044E, "mr"}, /* Marathi (India) */ + {0x044F, "sa"}, /* Sanskrit (India) */ + {0x0450, "mn"}, /* Mongolian (Cyrillic) (Mongolia) */ + {0x0451, "bo"}, /* Tibetan (PRC) */ + {0x0452, "cy"}, /* Welsh (United Kingdom) */ + {0x0453, "km"}, /* Khmer (Cambodia) */ + {0x0454, "lo"}, /* Lao (Lao P.D.R.) */ + {0x0455, "my"}, /* ??? */ + {0x0456, "gl"}, /* Galician (Galician) */ + {0x0457, "kok"}, /* Konkani (India) */ + {0x0458, "mni"}, /* ??? */ + {0x0459, "sd"}, /* ??? */ + {0x045A, "syr"}, /* Syriac (Syria) */ + {0x045B, "si"}, /* Sinhala (Sri Lanka) */ + {0x045C, "chr"}, /* ??? */ + {0x045D, "iu"}, /* Inuktitut (Canada) */ + {0x045E, "am"}, /* Amharic (Ethiopia) */ + {0x0460, "ks"}, /* ??? */ + {0x0461, "ne"}, /* Nepali (Nepal) */ + {0x0462, "fy"}, /* Frisian (Netherlands) */ + {0x0463, "ps"}, /* Pashto (Afghanistan) */ + {0x0464, "phi"}, /* Filipino (Philippines) */ + {0x0465, "div"}, /* Divehi (Maldives) */ + {0x0468, "ha"}, /* Hausa (Latin) (Nigeria) */ + {0x046A, "yo"}, /* Yoruba (Nigeria) */ + {0x046B, "quz"}, /* Quechua (Bolivia) */ + {0x046C, "nso"}, /* Sesotho sa Leboa (South Africa) */ + {0x046D, "ba"}, /* Bashkir (Russia) */ + {0x046E, "lb"}, /* Luxembourgish (Luxembourg) */ + {0x046F, "kl"}, /* Greenlandic (Greenland) */ + {0x0470, "ibo"}, /* Igbo (Nigeria) */ + {0x0471, "kau"}, /* ??? */ + {0x0472, "om"}, /* ??? */ + {0x0473, "ti"}, /* ??? */ + {0x0474, "gn"}, /* ??? */ + {0x0475, "haw"}, /* ??? */ + {0x0476, "la"}, /* ??? */ + {0x0477, "so"}, /* ??? */ + {0x0478, "ii"}, /* Yi (PRC) */ + {0x0479, "pap"}, /* ??? */ + {0x047A, "arn"}, /* Mapudungun (Chile) */ + {0x047C, "moh"}, /* Mohawk (Mohawk) */ + {0x047E, "br"}, /* Breton (France) */ + {0x0480, "ug"}, /* Uighur (PRC) */ + {0x0481, "mi"}, /* Maori (New Zealand) */ + {0x0482, "oc"}, /* Occitan (France) */ + {0x0483, "co"}, /* Corsican (France) */ + {0x0484, "gsw"}, /* Alsatian (France) */ + {0x0485, "sah"}, /* Yakut (Russia) */ + {0x0486, "qut"}, /* K'iche (Guatemala) */ + {0x0487, "rw"}, /* Kinyarwanda (Rwanda) */ + {0x0488, "wo"}, /* Wolof (Senegal) */ + {0x048C, "fa"}, /* Dari (Afghanistan) */ + {0x0801, "ar"}, /* Arabic (Iraq) */ + {0x0804, "zh-cn"}, /* Chinese (People’s Republic of China) */ + {0x0807, "de"}, /* German (Switzerland) */ + {0x0809, "en"}, /* English (United Kingdom) */ + {0x080A, "es"}, /* Spanish (Mexico) */ + {0x080C, "fr"}, /* French (Belgium) */ + {0x0810, "it"}, /* Italian (Switzerland) */ + {0x0812, "ko"}, /* ??? */ + {0x0813, "nl"}, /* Dutch (Belgium) */ + {0x0814, "nn"}, /* Norwegian (Nynorsk) (Norway) */ + {0x0816, "pt"}, /* Portuguese (Portugal) */ + {0x0818, "mo"}, /* ??? */ + {0x0819, "ru"}, /* ??? */ + {0x081A, "sr"}, /* Serbian (Latin) (Serbia) */ + {0x081D, "sv"}, /* Sweden (Finland) */ + {0x0820, "ur"}, /* ??? */ + {0x0827, "lt"}, /* ??? */ + {0x082C, "az"}, /* Azeri (Cyrillic) (Azerbaijan) */ + {0x082E, "dsb"}, /* Lower Sorbian (Germany) */ +//{0x083B, ""}, /* Sami (Northern) (Sweden) */ + {0x083C, "gd"}, /* Irish (Ireland) */ + {0x083E, "ms"}, /* Malay (Brunei Darussalam) */ + {0x0843, "uz"}, /* Uzbek (Cyrillic) (Uzbekistan) */ + {0x0845, "bn"}, /* Bengali (Bangladesh) */ + {0x0846, "ar"}, /* ??? */ + {0x0850, "mn"}, /* Mongolian (Traditional) (People’s Republic of China) */ + {0x0851, "dz"}, /* ??? */ + {0x085D, "iu"}, /* Inuktitut (Latin) (Canada) */ + {0x085F, "tzm"}, /* Tamazight (Latin) (Algeria) */ + {0x0861, "ne"}, /* ??? */ +//{0x086B, ""}, /* Quechua (Ecuador) */ + {0x0873, "ti"}, /* ??? */ + {0x0C01, "ar"}, /* Arabic (Egypt) */ + {0x0C04, "zh-hk"}, /* Chinese (Hong Kong S.A.R.) */ + {0x0C07, "de"}, /* German (Austria) */ + {0x0C09, "en"}, /* English (Australia) */ + {0x0C0A, "es"}, /* Spanish (Modern Sort) (Spain) */ + {0x0C0C, "fr"}, /* French (Canada) */ + {0x0C1A, "sr"}, /* Serbian (Cyrillic) (Serbia) */ + {0x0C3B, "se"}, /* Sami (Northern) (Finland) */ +//{0x0C6B, ""}, /* Quechua (Peru) */ + {0x1001, "ar"}, /* Arabic (Libya) */ + {0x1004, "zh-sg"}, /* Chinese (Singapore) */ + {0x1007, "de"}, /* German (Luxembourg) */ + {0x1009, "en"}, /* English (Canada) */ + {0x100A, "es"}, /* Spanish (Guatemala) */ + {0x100C, "fr"}, /* French (Switzerland) */ + {0x101A, "hr"}, /* Croatian (Latin) (Bosnia and Herzegovina) */ + {0x103B, "smj"}, /* Sami (Lule) (Norway) */ + {0x1401, "ar"}, /* Arabic (Algeria) */ +//{0x1404, ""}, /* Chinese (Macao S.A.R.) */ + {0x1407, "de"}, /* German (Liechtenstein) */ + {0x1409, "en"}, /* English (New Zealand) */ + {0x140A, "es"}, /* Spanish (Costa Rica) */ + {0x140C, "fr"}, /* French (Luxembourg) */ + {0x141A, "bs"}, /* Bosnian (Latin) (Bosnia and Herzegovina) */ +//{0x143B, ""}, /* Sami (Lule) (Sweden) */ + {0x1801, "ar"}, /* Arabic (Morocco) */ + {0x1809, "en"}, /* English (Ireland) */ + {0x180A, "es"}, /* Spanish (Panama) */ + {0x180C, "fr"}, /* French (Principality of Monaco) */ +//{0x181A, ""}, /* Serbian (Latin) (Bosnia and Herzegovina) */ + {0x183B, "sma"}, /* Sami (Southern) (Norway) */ + {0x1C01, "ar"}, /* Arabic (Tunisia) */ + {0x1C09, "en"}, /* English (South Africa) */ + {0x1C0A, "es"}, /* Spanish (Dominican Republic) */ + {0x1C0C, "fr"}, /* ??? */ +//{0x1C1A, ""}, /* Serbian (Cyrillic) (Bosnia and Herzegovina) */ +//{0x1C3B, ""}, /* Sami (Southern) (Sweden) */ + {0x2001, "ar"}, /* Arabic (Oman) */ + {0x2009, "en"}, /* English (Jamaica) */ + {0x200A, "es"}, /* Spanish (Venezuela) */ + {0x200C, "fr"}, /* ??? */ + {0x201A, "bs"}, /* Bosnian (Cyrillic) (Bosnia and Herzegovina) */ + {0x203B, "sms"}, /* Sami (Skolt) (Finland) */ + {0x2401, "ar"}, /* Arabic (Yemen) */ + {0x2409, "en"}, /* English (Caribbean) */ + {0x240A, "es"}, /* Spanish (Colombia) */ + {0x240C, "fr"}, /* ??? */ + {0x243B, "smn"}, /* Sami (Inari) (Finland) */ + {0x2801, "ar"}, /* Arabic (Syria) */ + {0x2809, "en"}, /* English (Belize) */ + {0x280A, "es"}, /* Spanish (Peru) */ + {0x280C, "fr"}, /* ??? */ + {0x2C01, "ar"}, /* Arabic (Jordan) */ + {0x2C09, "en"}, /* English (Trinidad and Tobago) */ + {0x2C0A, "es"}, /* Spanish (Argentina) */ + {0x2C0C, "fr"}, /* ??? */ + {0x3001, "ar"}, /* Arabic (Lebanon) */ + {0x3009, "en"}, /* English (Zimbabwe) */ + {0x300A, "es"}, /* Spanish (Ecuador) */ + {0x300C, "fr"}, /* ??? */ + {0x3401, "ar"}, /* Arabic (Kuwait) */ + {0x3409, "en"}, /* English (Republic of the Philippines) */ + {0x340A, "es"}, /* Spanish (Chile) */ + {0x340C, "fr"}, /* ??? */ + {0x3801, "ar"}, /* Arabic (U.A.E.) */ + {0x380A, "es"}, /* Spanish (Uruguay) */ + {0x380C, "fr"}, /* ??? */ + {0x3C01, "ar"}, /* Arabic (Bahrain) */ + {0x3C09, "en"}, /* ??? */ + {0x3C0A, "es"}, /* Spanish (Paraguay) */ + {0x3C0C, "fr"}, /* ??? */ + {0x4001, "ar"}, /* Arabic (Qatar) */ + {0x4009, "en"}, /* English (India) */ + {0x400A, "es"}, /* Spanish (Bolivia) */ + {0x4409, "en"}, /* English (Malaysia) */ + {0x440A, "es"}, /* Spanish (El Salvador) */ + {0x4809, "en"}, /* English (Singapore) */ + {0x480A, "es"}, /* Spanish (Honduras) */ + {0x4C0A, "es"}, /* Spanish (Nicaragua) */ + {0x500A, "es"}, /* Spanish (Puerto Rico) */ + {0x540A, "es"}, /* Spanish (United States) */ + {0xE40A, "es"}, /* ??? */ + {0xE40C, "fr"}, /* ??? */ +}; + +static const hb_ot_language_map_t +hb_mac_language_map[] = +{ + { 0, "en"}, /* English */ + { 1, "fr"}, /* French */ + { 2, "de"}, /* German */ + { 3, "it"}, /* Italian */ + { 4, "nl"}, /* Dutch */ + { 5, "sv"}, /* Swedish */ + { 6, "es"}, /* Spanish */ + { 7, "da"}, /* Danish */ + { 8, "pt"}, /* Portuguese */ + { 9, "no"}, /* Norwegian */ + { 10, "he"}, /* Hebrew */ + { 11, "ja"}, /* Japanese */ + { 12, "ar"}, /* Arabic */ + { 13, "fi"}, /* Finnish */ + { 14, "el"}, /* Greek */ + { 15, "is"}, /* Icelandic */ + { 16, "mt"}, /* Maltese */ + { 17, "tr"}, /* Turkish */ + { 18, "hr"}, /* Croatian */ + { 19, "zh-tw"}, /* Chinese (Traditional) */ + { 20, "ur"}, /* Urdu */ + { 21, "hi"}, /* Hindi */ + { 22, "th"}, /* Thai */ + { 23, "ko"}, /* Korean */ + { 24, "lt"}, /* Lithuanian */ + { 25, "pl"}, /* Polish */ + { 26, "hu"}, /* Hungarian */ + { 27, "et"}, /* Estonian */ + { 28, "lv"}, /* Latvian */ +//{ 29, ""}, /* Sami */ + { 30, "fo"}, /* Faroese */ + { 31, "fa"}, /* Farsi/Persian */ + { 32, "ru"}, /* Russian */ + { 33, "zh-cn"}, /* Chinese (Simplified) */ + { 34, "nl"}, /* Flemish */ + { 35, "ga"}, /* Irish Gaelic */ + { 36, "sq"}, /* Albanian */ + { 37, "ro"}, /* Romanian */ + { 38, "cs"}, /* Czech */ + { 39, "sk"}, /* Slovak */ + { 40, "sl"}, /* Slovenian */ + { 41, "yi"}, /* Yiddish */ + { 42, "sr"}, /* Serbian */ + { 43, "mk"}, /* Macedonian */ + { 44, "bg"}, /* Bulgarian */ + { 45, "uk"}, /* Ukrainian */ + { 46, "be"}, /* Byelorussian */ + { 47, "uz"}, /* Uzbek */ + { 48, "kk"}, /* Kazakh */ + { 49, "az"}, /* Azerbaijani (Cyrillic script) */ + { 50, "az"}, /* Azerbaijani (Arabic script) */ + { 51, "hy"}, /* Armenian */ + { 52, "ka"}, /* Georgian */ + { 53, "mo"}, /* Moldavian */ + { 54, "ky"}, /* Kirghiz */ + { 55, "tg"}, /* Tajiki */ + { 56, "tk"}, /* Turkmen */ + { 57, "mn"}, /* Mongolian (Mongolian script) */ + { 58, "mn"}, /* Mongolian (Cyrillic script) */ + { 59, "ps"}, /* Pashto */ + { 60, "ku"}, /* Kurdish */ + { 61, "ks"}, /* Kashmiri */ + { 62, "sd"}, /* Sindhi */ + { 63, "bo"}, /* Tibetan */ + { 64, "ne"}, /* Nepali */ + { 65, "sa"}, /* Sanskrit */ + { 66, "mr"}, /* Marathi */ + { 67, "bn"}, /* Bengali */ + { 68, "as"}, /* Assamese */ + { 69, "gu"}, /* Gujarati */ + { 70, "pa"}, /* Punjabi */ + { 71, "or"}, /* Oriya */ + { 72, "ml"}, /* Malayalam */ + { 73, "kn"}, /* Kannada */ + { 74, "ta"}, /* Tamil */ + { 75, "te"}, /* Telugu */ + { 76, "si"}, /* Sinhalese */ + { 77, "my"}, /* Burmese */ + { 78, "km"}, /* Khmer */ + { 79, "lo"}, /* Lao */ + { 80, "vi"}, /* Vietnamese */ + { 81, "id"}, /* Indonesian */ + { 82, "tl"}, /* Tagalog */ + { 83, "ms"}, /* Malay (Roman script) */ + { 84, "ms"}, /* Malay (Arabic script) */ + { 85, "am"}, /* Amharic */ + { 86, "ti"}, /* Tigrinya */ + { 87, "om"}, /* Galla */ + { 88, "so"}, /* Somali */ + { 89, "sw"}, /* Swahili */ + { 90, "rw"}, /* Kinyarwanda/Ruanda */ + { 91, "rn"}, /* Rundi */ + { 92, "ny"}, /* Nyanja/Chewa */ + { 93, "mg"}, /* Malagasy */ + { 94, "eo"}, /* Esperanto */ + {128, "cy"}, /* Welsh */ + {129, "eu"}, /* Basque */ + {130, "ca"}, /* Catalan */ + {131, "la"}, /* Latin */ + {132, "qu"}, /* Quechua */ + {133, "gn"}, /* Guarani */ + {134, "ay"}, /* Aymara */ + {135, "tt"}, /* Tatar */ + {136, "ug"}, /* Uighur */ + {137, "dz"}, /* Dzongkha */ + {138, "jw"}, /* Javanese (Roman script) */ + {139, "su"}, /* Sundanese (Roman script) */ + {140, "gl"}, /* Galician */ + {141, "af"}, /* Afrikaans */ + {142, "br"}, /* Breton */ + {143, "iu"}, /* Inuktitut */ + {144, "gd"}, /* Scottish Gaelic */ + {145, "gv"}, /* Manx Gaelic */ + {146, "ga"}, /* Irish Gaelic (with dot above) */ + {147, "to"}, /* Tongan */ + {148, "el"}, /* Greek (polytonic) */ + {149, "ik"}, /* Greenlandic */ + {150, "az"}, /* Azerbaijani (Roman script) */ +}; + +static hb_language_t +_hb_ot_name_language_for (unsigned int code, + const hb_ot_language_map_t *array, + unsigned int len) +{ + const hb_ot_language_map_t *entry = (const hb_ot_language_map_t *) + hb_bsearch (&code, + array, + len, + sizeof (array[0]), + hb_ot_language_map_t::cmp); + + if (entry) + return hb_language_from_string (entry->lang, -1); + + return HB_LANGUAGE_INVALID; +} + + +inline hb_language_t +_hb_ot_name_language_for_ms_code (unsigned int code) +{ + return _hb_ot_name_language_for (code, + hb_ms_language_map, + ARRAY_LENGTH (hb_ms_language_map)); +} + +inline hb_language_t +_hb_ot_name_language_for_mac_code (unsigned int code) +{ + return _hb_ot_name_language_for (code, + hb_mac_language_map, + ARRAY_LENGTH (hb_mac_language_map)); +} #endif /* HB_OT_NAME_LANGUAGE_HH */ diff --git a/test/api/fonts/nameID.dup.expected.ttf b/test/api/fonts/nameID.dup.expected.ttf new file mode 100644 index 0000000000000000000000000000000000000000..e9e7ff5b4c3c254d6128e11971fed1e64a1f83e5 GIT binary patch literal 2340 zcmZWq4Qx}_6+ZX9XZzVP@q3wxOCBWe@yH*sn~)z5(ulfh5@69FCF%NJl!h2PA*pa< zh=EipZTbhP%TL*;D#2*02~8cX%JnN733O7V(M{V_#xyp;rdF!dR&9l#mDq&nZ13FX zkidGad(QdJJ@@!K_wNA#03S>O56MkE^^K{K=Zn$vU+jaiL^KHsxdA}>5gW1HDYfox z*9pXD5cduzwWD{ox=Q$+7WNJ^?t_HOmUMAh&dq#Fzh^ZEQ+HpbOM%;F1;#YC~kuoGAbCtwoNFaejb zx{c5W`(Y4%0?k|-d;k_4f(sbu&kcf~I}R$ZL6Oi3e&HZU$j$G(4;GVOg6y1yV&_$G zVk}Syc2Re?ks;)eIZg5}(HECx-29e-5G6rX?HFyRWH3azASElc5aokvC*>Si&BLD=(`2$6Q=!r|g*kLh*N~yv z9-{7GSC7$w6g8yi3DTO55G@MQT2$U(rkYHt=^kSyf@dH$Ey7f)iNYl&owjt_a?vH+{SJe2^-6{-Uu)U`5J1UV(-JtqnUcCD&z6q zw7dn+B3n^T$`pHVHmuS#S>t6wWWsBtg=lC^t>3q$t3W3R0$G!ApyzjJ^P|jH+sO9Qe$u(+}@{KFPqUF&E$$x#HIh>0sabPyX=OR`%2!$X^pwyo$xJ1ct4W zGKJAAktmNfi}iMKUaZu6r)(Ypf2V9G0w>!ohsd+CJzl18qcbH7C0!kA3gKZQBJ;<``eMdPRRc5 zmE1paS;ucLp2`JJUBvU(k2`h^cWfDSSyFig{(0d{Nk~k(Ls>*1BFhXcu%IF|MYm=hnuKil-gBKYa4z+;^#~M}PCJcv?I>dhqzM7bf~1 ze>+a92~@oCpQ(SoH@g4Nv-u}xn<=_Ig2RDd4wlEYJ%_Kgd&6xd_ak?Mof!w_o4_A{ zxX=d)VJ{pI8lc~f5a2MBLNDG|mXGZ_{sp&U?mNNZ*)RBs{XQ3LcB5hQ*w(Ss7{=Kx z{{*}5-*41gN1+ZZB5`%Zk_pPQa%)4SB7s;3XUX~p?$`Wip5=`7t7~kF-~4cMWhwIs z13zx7Tf!_yIJkU?k6F$gk9RgI%yJ#s)8DEyOMGTq_nI%dH2?$hftI ziD#LpFC!^y6BA=h9A@G)6L}^o%E&G@V;7sTi_O?&`O4W`CT=iMQI2t2m^jSDUzo@< T@nAUyk1uyXb literal 0 HcmV?d00001 diff --git a/test/api/fonts/nameID.dup.origin.ttf b/test/api/fonts/nameID.dup.origin.ttf new file mode 100644 index 0000000000000000000000000000000000000000..aad75d421bd533c092d12f935d27a859aec6c26c GIT binary patch literal 170680 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 z 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 jwjfR_MgyKgSMv)q!A!KL+cRu8+ufdNdyuo#2~X Date: Wed, 24 Apr 2019 14:02:29 -0700 Subject: [PATCH 59/69] [subset] Update to use _subset2() for name table --- src/hb-ot-name-table.hh | 47 +++++++++-------------------------------- src/hb-subset.cc | 4 ++-- 2 files changed, 12 insertions(+), 39 deletions(-) diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index fde808c19..056a77a06 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -158,32 +158,19 @@ struct name unsigned int get_size () const { return min_size + count * nameRecordZ.item_size; } - size_t get_subsetted_size (const name *source_name, + void get_subsetted_ids (const name *source_name, const hb_subset_plan_t *plan, hb_vector_t& name_record_idx_to_retain) const { - size_t result = min_size; - - hb_face_t *face = plan->source; - accelerator_t acc; - acc.init (face); - for(unsigned int i = 0; i < count; i++) { - if (format == 0 && (unsigned int) nameRecordZ[i].nameID > 25) + if (format == 0 && (unsigned int) source_name->nameRecordZ[i].nameID > 25) continue; if (!hb_set_is_empty (plan->name_ids) && !hb_set_has (plan->name_ids, source_name->nameRecordZ[i].nameID)) continue; - result += acc.get_name (i).get_size (); name_record_idx_to_retain.push (i); } - - acc.fini (); - - result += name_record_idx_to_retain.length * NameRecord::static_size; - - return result; } bool serialize_name_record (hb_serialize_context_t *c, @@ -294,36 +281,22 @@ struct name return_trace (true); } - bool subset (hb_subset_plan_t *plan) const + bool subset (hb_subset_context_t *c) const { + hb_subset_plan_t *plan = c->plan; hb_vector_t name_record_idx_to_retain; - size_t dest_size = get_subsetted_size (this, plan, name_record_idx_to_retain); - name *dest = (name *) malloc (dest_size); - if(unlikely (!dest)) - { - DEBUG_MSG (SUBSET, nullptr, "Unable to alloc %lu for name subset output.", - (unsigned long) dest_size); - return false; - } + get_subsetted_ids (this, plan, name_record_idx_to_retain); - hb_serialize_context_t c (dest, dest_size); - name *name_prime = c.start_serialize (); - if (!name_prime || !name_prime->serialize (&c, this, plan, name_record_idx_to_retain)) + hb_serialize_context_t *serializer = c->serializer; + name *name_prime = serializer->start_embed (); + if (!name_prime || !name_prime->serialize (serializer, this, plan, name_record_idx_to_retain)) { - free (dest); DEBUG_MSG (SUBSET, nullptr, "Failed to serialize write new name."); - c.end_serialize (); return false; } - - c.end_serialize (); - - hb_blob_t *name_prime_blob = c.copy_blob (); - bool result = plan->add_table (HB_OT_TAG_name, name_prime_blob); - hb_blob_destroy (name_prime_blob); - - return result; + + return true; } bool sanitize_records (hb_sanitize_context_t *c) const diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 333e7d484..2165b8a72 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -88,7 +88,6 @@ _subset2 (hb_subset_plan_t *plan) serializer.start_serialize (); hb_subset_context_t c (plan, &serializer); result = table->subset (&c); - serializer.end_serialize (); if (serializer.ran_out_of_room) { buf_size += (buf_size >> 1) + 32; @@ -105,6 +104,7 @@ _subset2 (hb_subset_plan_t *plan) abort (); } + serializer.end_serialize (); if (result) { hb_blob_t *dest_blob = serializer.copy_blob (); @@ -160,7 +160,7 @@ _subset_table (hb_subset_plan_t *plan, result = _subset (plan); break; case HB_OT_TAG_name: - result = _subset (plan); + result = _subset2 (plan); break; case HB_OT_TAG_head: // TODO that won't work well if there is no glyf From 2f6ec35344db08d0c892152bc7a7eaa67e7c03f0 Mon Sep 17 00:00:00 2001 From: Garret Rieger Date: Wed, 24 Apr 2019 15:15:36 -0700 Subject: [PATCH 60/69] Move implementations of hb-ot-name-language.cc into a hb-static.cc --- src/hb-aat-layout.hh | 1 - src/hb-ot-name-language-static.hh | 462 ++++++++++++++++++++++++++++++ src/hb-ot-name-language.hh | 432 +--------------------------- src/hb-static.cc | 2 + 4 files changed, 468 insertions(+), 429 deletions(-) create mode 100644 src/hb-ot-name-language-static.hh diff --git a/src/hb-aat-layout.hh b/src/hb-aat-layout.hh index 1ed009e12..9a0e4468f 100644 --- a/src/hb-aat-layout.hh +++ b/src/hb-aat-layout.hh @@ -32,7 +32,6 @@ #include "hb-ot-shape.hh" #include "hb-aat-ltag-table.hh" - struct hb_aat_feature_mapping_t { hb_tag_t otFeatureTag; diff --git a/src/hb-ot-name-language-static.hh b/src/hb-ot-name-language-static.hh new file mode 100644 index 000000000..fac317856 --- /dev/null +++ b/src/hb-ot-name-language-static.hh @@ -0,0 +1,462 @@ +/* + * Copyright © 2018 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_OT_NAME_LANGUAGE_STATIC_HH +#define HB_OT_NAME_LANGUAGE_STATIC_HH + +#include "hb-ot-name-language.hh" + +/* Following two tables were generated by joining FreeType, FontConfig, + * and OpenType specification language lists, then filled in missing + * entries using: + * https://docs.microsoft.com/en-us/windows/desktop/intl/language-identifier-constants-and-strings + */ + +struct hb_ot_language_map_t +{ + static int cmp (const void *key, const void *item) + { + unsigned int a = * (unsigned int *) key; + unsigned int b = ((const hb_ot_language_map_t *) item)->code; + return a < b ? -1 : a > b ? +1 : 0; + } + + uint16_t code; + char lang[6]; +}; + +static const hb_ot_language_map_t +hb_ms_language_map[] = +{ + {0x0001, "ar"}, /* ??? */ + {0x0004, "zh"}, /* ??? */ + {0x0009, "en"}, /* ??? */ + {0x0401, "ar"}, /* Arabic (Saudi Arabia) */ + {0x0402, "bg"}, /* Bulgarian (Bulgaria) */ + {0x0403, "ca"}, /* Catalan (Catalan) */ + {0x0404, "zh-tw"}, /* Chinese (Taiwan) */ + {0x0405, "cs"}, /* Czech (Czech Republic) */ + {0x0406, "da"}, /* Danish (Denmark) */ + {0x0407, "de"}, /* German (Germany) */ + {0x0408, "el"}, /* Greek (Greece) */ + {0x0409, "en"}, /* English (United States) */ + {0x040A, "es"}, /* Spanish (Traditional Sort) (Spain) */ + {0x040B, "fi"}, /* Finnish (Finland) */ + {0x040C, "fr"}, /* French (France) */ + {0x040D, "he"}, /* Hebrew (Israel) */ + {0x040E, "hu"}, /* Hungarian (Hungary) */ + {0x040F, "is"}, /* Icelandic (Iceland) */ + {0x0410, "it"}, /* Italian (Italy) */ + {0x0411, "ja"}, /* Japanese (Japan) */ + {0x0412, "ko"}, /* Korean (Korea) */ + {0x0413, "nl"}, /* Dutch (Netherlands) */ + {0x0414, "no"}, /* Norwegian (Bokmal) (Norway) */ + {0x0415, "pl"}, /* Polish (Poland) */ + {0x0416, "pt"}, /* Portuguese (Brazil) */ + {0x0417, "rm"}, /* Romansh (Switzerland) */ + {0x0418, "ro"}, /* Romanian (Romania) */ + {0x0419, "ru"}, /* Russian (Russia) */ + {0x041A, "hr"}, /* Croatian (Croatia) */ + {0x041B, "sk"}, /* Slovak (Slovakia) */ + {0x041C, "sq"}, /* Albanian (Albania) */ + {0x041D, "sv"}, /* Swedish (Sweden) */ + {0x041E, "th"}, /* Thai (Thailand) */ + {0x041F, "tr"}, /* Turkish (Turkey) */ + {0x0420, "ur"}, /* Urdu (Islamic Republic of Pakistan) */ + {0x0421, "id"}, /* Indonesian (Indonesia) */ + {0x0422, "uk"}, /* Ukrainian (Ukraine) */ + {0x0423, "be"}, /* Belarusian (Belarus) */ + {0x0424, "sl"}, /* Slovenian (Slovenia) */ + {0x0425, "et"}, /* Estonian (Estonia) */ + {0x0426, "lv"}, /* Latvian (Latvia) */ + {0x0427, "lt"}, /* Lithuanian (Lithuania) */ + {0x0428, "tg"}, /* Tajik (Cyrillic) (Tajikistan) */ + {0x0429, "fa"}, /* Persian (Iran) */ + {0x042A, "vi"}, /* Vietnamese (Vietnam) */ + {0x042B, "hy"}, /* Armenian (Armenia) */ + {0x042C, "az"}, /* Azeri (Latin) (Azerbaijan) */ + {0x042D, "eu"}, /* Basque (Basque) */ + {0x042E, "hsb"}, /* Upper Sorbian (Germany) */ + {0x042F, "mk"}, /* Macedonian (FYROM) (Former Yugoslav Republic of Macedonia) */ + {0x0430, "st"}, /* ??? */ + {0x0431, "ts"}, /* ??? */ + {0x0432, "tn"}, /* Setswana (South Africa) */ + {0x0433, "ven"}, /* ??? */ + {0x0434, "xh"}, /* isiXhosa (South Africa) */ + {0x0435, "zu"}, /* isiZulu (South Africa) */ + {0x0436, "af"}, /* Afrikaans (South Africa) */ + {0x0437, "ka"}, /* Georgian (Georgia) */ + {0x0438, "fo"}, /* Faroese (Faroe Islands) */ + {0x0439, "hi"}, /* Hindi (India) */ + {0x043A, "mt"}, /* Maltese (Malta) */ + {0x043B, "se"}, /* Sami (Northern) (Norway) */ + {0x043C, "ga"}, /* ??? */ + {0x043D, "yi"}, /* ??? */ + {0x043E, "ms"}, /* Malay (Malaysia) */ + {0x043F, "kk"}, /* Kazakh (Kazakhstan) */ + {0x0440, "ky"}, /* Kyrgyz (Kyrgyzstan) */ + {0x0441, "sw"}, /* Kiswahili (Kenya) */ + {0x0442, "tk"}, /* Turkmen (Turkmenistan) */ + {0x0443, "uz"}, /* Uzbek (Latin) (Uzbekistan) */ + {0x0444, "tt"}, /* Tatar (Russia) */ + {0x0445, "bn"}, /* Bengali (India) */ + {0x0446, "pa"}, /* Punjabi (India) */ + {0x0447, "gu"}, /* Gujarati (India) */ + {0x0448, "or"}, /* Odia (formerly Oriya) (India) */ + {0x0449, "ta"}, /* Tamil (India) */ + {0x044A, "te"}, /* Telugu (India) */ + {0x044B, "kn"}, /* Kannada (India) */ + {0x044C, "ml"}, /* Malayalam (India) */ + {0x044D, "as"}, /* Assamese (India) */ + {0x044E, "mr"}, /* Marathi (India) */ + {0x044F, "sa"}, /* Sanskrit (India) */ + {0x0450, "mn"}, /* Mongolian (Cyrillic) (Mongolia) */ + {0x0451, "bo"}, /* Tibetan (PRC) */ + {0x0452, "cy"}, /* Welsh (United Kingdom) */ + {0x0453, "km"}, /* Khmer (Cambodia) */ + {0x0454, "lo"}, /* Lao (Lao P.D.R.) */ + {0x0455, "my"}, /* ??? */ + {0x0456, "gl"}, /* Galician (Galician) */ + {0x0457, "kok"}, /* Konkani (India) */ + {0x0458, "mni"}, /* ??? */ + {0x0459, "sd"}, /* ??? */ + {0x045A, "syr"}, /* Syriac (Syria) */ + {0x045B, "si"}, /* Sinhala (Sri Lanka) */ + {0x045C, "chr"}, /* ??? */ + {0x045D, "iu"}, /* Inuktitut (Canada) */ + {0x045E, "am"}, /* Amharic (Ethiopia) */ + {0x0460, "ks"}, /* ??? */ + {0x0461, "ne"}, /* Nepali (Nepal) */ + {0x0462, "fy"}, /* Frisian (Netherlands) */ + {0x0463, "ps"}, /* Pashto (Afghanistan) */ + {0x0464, "phi"}, /* Filipino (Philippines) */ + {0x0465, "div"}, /* Divehi (Maldives) */ + {0x0468, "ha"}, /* Hausa (Latin) (Nigeria) */ + {0x046A, "yo"}, /* Yoruba (Nigeria) */ + {0x046B, "quz"}, /* Quechua (Bolivia) */ + {0x046C, "nso"}, /* Sesotho sa Leboa (South Africa) */ + {0x046D, "ba"}, /* Bashkir (Russia) */ + {0x046E, "lb"}, /* Luxembourgish (Luxembourg) */ + {0x046F, "kl"}, /* Greenlandic (Greenland) */ + {0x0470, "ibo"}, /* Igbo (Nigeria) */ + {0x0471, "kau"}, /* ??? */ + {0x0472, "om"}, /* ??? */ + {0x0473, "ti"}, /* ??? */ + {0x0474, "gn"}, /* ??? */ + {0x0475, "haw"}, /* ??? */ + {0x0476, "la"}, /* ??? */ + {0x0477, "so"}, /* ??? */ + {0x0478, "ii"}, /* Yi (PRC) */ + {0x0479, "pap"}, /* ??? */ + {0x047A, "arn"}, /* Mapudungun (Chile) */ + {0x047C, "moh"}, /* Mohawk (Mohawk) */ + {0x047E, "br"}, /* Breton (France) */ + {0x0480, "ug"}, /* Uighur (PRC) */ + {0x0481, "mi"}, /* Maori (New Zealand) */ + {0x0482, "oc"}, /* Occitan (France) */ + {0x0483, "co"}, /* Corsican (France) */ + {0x0484, "gsw"}, /* Alsatian (France) */ + {0x0485, "sah"}, /* Yakut (Russia) */ + {0x0486, "qut"}, /* K'iche (Guatemala) */ + {0x0487, "rw"}, /* Kinyarwanda (Rwanda) */ + {0x0488, "wo"}, /* Wolof (Senegal) */ + {0x048C, "fa"}, /* Dari (Afghanistan) */ + {0x0801, "ar"}, /* Arabic (Iraq) */ + {0x0804, "zh-cn"}, /* Chinese (People’s Republic of China) */ + {0x0807, "de"}, /* German (Switzerland) */ + {0x0809, "en"}, /* English (United Kingdom) */ + {0x080A, "es"}, /* Spanish (Mexico) */ + {0x080C, "fr"}, /* French (Belgium) */ + {0x0810, "it"}, /* Italian (Switzerland) */ + {0x0812, "ko"}, /* ??? */ + {0x0813, "nl"}, /* Dutch (Belgium) */ + {0x0814, "nn"}, /* Norwegian (Nynorsk) (Norway) */ + {0x0816, "pt"}, /* Portuguese (Portugal) */ + {0x0818, "mo"}, /* ??? */ + {0x0819, "ru"}, /* ??? */ + {0x081A, "sr"}, /* Serbian (Latin) (Serbia) */ + {0x081D, "sv"}, /* Sweden (Finland) */ + {0x0820, "ur"}, /* ??? */ + {0x0827, "lt"}, /* ??? */ + {0x082C, "az"}, /* Azeri (Cyrillic) (Azerbaijan) */ + {0x082E, "dsb"}, /* Lower Sorbian (Germany) */ +//{0x083B, ""}, /* Sami (Northern) (Sweden) */ + {0x083C, "gd"}, /* Irish (Ireland) */ + {0x083E, "ms"}, /* Malay (Brunei Darussalam) */ + {0x0843, "uz"}, /* Uzbek (Cyrillic) (Uzbekistan) */ + {0x0845, "bn"}, /* Bengali (Bangladesh) */ + {0x0846, "ar"}, /* ??? */ + {0x0850, "mn"}, /* Mongolian (Traditional) (People’s Republic of China) */ + {0x0851, "dz"}, /* ??? */ + {0x085D, "iu"}, /* Inuktitut (Latin) (Canada) */ + {0x085F, "tzm"}, /* Tamazight (Latin) (Algeria) */ + {0x0861, "ne"}, /* ??? */ +//{0x086B, ""}, /* Quechua (Ecuador) */ + {0x0873, "ti"}, /* ??? */ + {0x0C01, "ar"}, /* Arabic (Egypt) */ + {0x0C04, "zh-hk"}, /* Chinese (Hong Kong S.A.R.) */ + {0x0C07, "de"}, /* German (Austria) */ + {0x0C09, "en"}, /* English (Australia) */ + {0x0C0A, "es"}, /* Spanish (Modern Sort) (Spain) */ + {0x0C0C, "fr"}, /* French (Canada) */ + {0x0C1A, "sr"}, /* Serbian (Cyrillic) (Serbia) */ + {0x0C3B, "se"}, /* Sami (Northern) (Finland) */ +//{0x0C6B, ""}, /* Quechua (Peru) */ + {0x1001, "ar"}, /* Arabic (Libya) */ + {0x1004, "zh-sg"}, /* Chinese (Singapore) */ + {0x1007, "de"}, /* German (Luxembourg) */ + {0x1009, "en"}, /* English (Canada) */ + {0x100A, "es"}, /* Spanish (Guatemala) */ + {0x100C, "fr"}, /* French (Switzerland) */ + {0x101A, "hr"}, /* Croatian (Latin) (Bosnia and Herzegovina) */ + {0x103B, "smj"}, /* Sami (Lule) (Norway) */ + {0x1401, "ar"}, /* Arabic (Algeria) */ +//{0x1404, ""}, /* Chinese (Macao S.A.R.) */ + {0x1407, "de"}, /* German (Liechtenstein) */ + {0x1409, "en"}, /* English (New Zealand) */ + {0x140A, "es"}, /* Spanish (Costa Rica) */ + {0x140C, "fr"}, /* French (Luxembourg) */ + {0x141A, "bs"}, /* Bosnian (Latin) (Bosnia and Herzegovina) */ +//{0x143B, ""}, /* Sami (Lule) (Sweden) */ + {0x1801, "ar"}, /* Arabic (Morocco) */ + {0x1809, "en"}, /* English (Ireland) */ + {0x180A, "es"}, /* Spanish (Panama) */ + {0x180C, "fr"}, /* French (Principality of Monaco) */ +//{0x181A, ""}, /* Serbian (Latin) (Bosnia and Herzegovina) */ + {0x183B, "sma"}, /* Sami (Southern) (Norway) */ + {0x1C01, "ar"}, /* Arabic (Tunisia) */ + {0x1C09, "en"}, /* English (South Africa) */ + {0x1C0A, "es"}, /* Spanish (Dominican Republic) */ + {0x1C0C, "fr"}, /* ??? */ +//{0x1C1A, ""}, /* Serbian (Cyrillic) (Bosnia and Herzegovina) */ +//{0x1C3B, ""}, /* Sami (Southern) (Sweden) */ + {0x2001, "ar"}, /* Arabic (Oman) */ + {0x2009, "en"}, /* English (Jamaica) */ + {0x200A, "es"}, /* Spanish (Venezuela) */ + {0x200C, "fr"}, /* ??? */ + {0x201A, "bs"}, /* Bosnian (Cyrillic) (Bosnia and Herzegovina) */ + {0x203B, "sms"}, /* Sami (Skolt) (Finland) */ + {0x2401, "ar"}, /* Arabic (Yemen) */ + {0x2409, "en"}, /* English (Caribbean) */ + {0x240A, "es"}, /* Spanish (Colombia) */ + {0x240C, "fr"}, /* ??? */ + {0x243B, "smn"}, /* Sami (Inari) (Finland) */ + {0x2801, "ar"}, /* Arabic (Syria) */ + {0x2809, "en"}, /* English (Belize) */ + {0x280A, "es"}, /* Spanish (Peru) */ + {0x280C, "fr"}, /* ??? */ + {0x2C01, "ar"}, /* Arabic (Jordan) */ + {0x2C09, "en"}, /* English (Trinidad and Tobago) */ + {0x2C0A, "es"}, /* Spanish (Argentina) */ + {0x2C0C, "fr"}, /* ??? */ + {0x3001, "ar"}, /* Arabic (Lebanon) */ + {0x3009, "en"}, /* English (Zimbabwe) */ + {0x300A, "es"}, /* Spanish (Ecuador) */ + {0x300C, "fr"}, /* ??? */ + {0x3401, "ar"}, /* Arabic (Kuwait) */ + {0x3409, "en"}, /* English (Republic of the Philippines) */ + {0x340A, "es"}, /* Spanish (Chile) */ + {0x340C, "fr"}, /* ??? */ + {0x3801, "ar"}, /* Arabic (U.A.E.) */ + {0x380A, "es"}, /* Spanish (Uruguay) */ + {0x380C, "fr"}, /* ??? */ + {0x3C01, "ar"}, /* Arabic (Bahrain) */ + {0x3C09, "en"}, /* ??? */ + {0x3C0A, "es"}, /* Spanish (Paraguay) */ + {0x3C0C, "fr"}, /* ??? */ + {0x4001, "ar"}, /* Arabic (Qatar) */ + {0x4009, "en"}, /* English (India) */ + {0x400A, "es"}, /* Spanish (Bolivia) */ + {0x4409, "en"}, /* English (Malaysia) */ + {0x440A, "es"}, /* Spanish (El Salvador) */ + {0x4809, "en"}, /* English (Singapore) */ + {0x480A, "es"}, /* Spanish (Honduras) */ + {0x4C0A, "es"}, /* Spanish (Nicaragua) */ + {0x500A, "es"}, /* Spanish (Puerto Rico) */ + {0x540A, "es"}, /* Spanish (United States) */ + {0xE40A, "es"}, /* ??? */ + {0xE40C, "fr"}, /* ??? */ +}; + +static const hb_ot_language_map_t +hb_mac_language_map[] = +{ + { 0, "en"}, /* English */ + { 1, "fr"}, /* French */ + { 2, "de"}, /* German */ + { 3, "it"}, /* Italian */ + { 4, "nl"}, /* Dutch */ + { 5, "sv"}, /* Swedish */ + { 6, "es"}, /* Spanish */ + { 7, "da"}, /* Danish */ + { 8, "pt"}, /* Portuguese */ + { 9, "no"}, /* Norwegian */ + { 10, "he"}, /* Hebrew */ + { 11, "ja"}, /* Japanese */ + { 12, "ar"}, /* Arabic */ + { 13, "fi"}, /* Finnish */ + { 14, "el"}, /* Greek */ + { 15, "is"}, /* Icelandic */ + { 16, "mt"}, /* Maltese */ + { 17, "tr"}, /* Turkish */ + { 18, "hr"}, /* Croatian */ + { 19, "zh-tw"}, /* Chinese (Traditional) */ + { 20, "ur"}, /* Urdu */ + { 21, "hi"}, /* Hindi */ + { 22, "th"}, /* Thai */ + { 23, "ko"}, /* Korean */ + { 24, "lt"}, /* Lithuanian */ + { 25, "pl"}, /* Polish */ + { 26, "hu"}, /* Hungarian */ + { 27, "et"}, /* Estonian */ + { 28, "lv"}, /* Latvian */ +//{ 29, ""}, /* Sami */ + { 30, "fo"}, /* Faroese */ + { 31, "fa"}, /* Farsi/Persian */ + { 32, "ru"}, /* Russian */ + { 33, "zh-cn"}, /* Chinese (Simplified) */ + { 34, "nl"}, /* Flemish */ + { 35, "ga"}, /* Irish Gaelic */ + { 36, "sq"}, /* Albanian */ + { 37, "ro"}, /* Romanian */ + { 38, "cs"}, /* Czech */ + { 39, "sk"}, /* Slovak */ + { 40, "sl"}, /* Slovenian */ + { 41, "yi"}, /* Yiddish */ + { 42, "sr"}, /* Serbian */ + { 43, "mk"}, /* Macedonian */ + { 44, "bg"}, /* Bulgarian */ + { 45, "uk"}, /* Ukrainian */ + { 46, "be"}, /* Byelorussian */ + { 47, "uz"}, /* Uzbek */ + { 48, "kk"}, /* Kazakh */ + { 49, "az"}, /* Azerbaijani (Cyrillic script) */ + { 50, "az"}, /* Azerbaijani (Arabic script) */ + { 51, "hy"}, /* Armenian */ + { 52, "ka"}, /* Georgian */ + { 53, "mo"}, /* Moldavian */ + { 54, "ky"}, /* Kirghiz */ + { 55, "tg"}, /* Tajiki */ + { 56, "tk"}, /* Turkmen */ + { 57, "mn"}, /* Mongolian (Mongolian script) */ + { 58, "mn"}, /* Mongolian (Cyrillic script) */ + { 59, "ps"}, /* Pashto */ + { 60, "ku"}, /* Kurdish */ + { 61, "ks"}, /* Kashmiri */ + { 62, "sd"}, /* Sindhi */ + { 63, "bo"}, /* Tibetan */ + { 64, "ne"}, /* Nepali */ + { 65, "sa"}, /* Sanskrit */ + { 66, "mr"}, /* Marathi */ + { 67, "bn"}, /* Bengali */ + { 68, "as"}, /* Assamese */ + { 69, "gu"}, /* Gujarati */ + { 70, "pa"}, /* Punjabi */ + { 71, "or"}, /* Oriya */ + { 72, "ml"}, /* Malayalam */ + { 73, "kn"}, /* Kannada */ + { 74, "ta"}, /* Tamil */ + { 75, "te"}, /* Telugu */ + { 76, "si"}, /* Sinhalese */ + { 77, "my"}, /* Burmese */ + { 78, "km"}, /* Khmer */ + { 79, "lo"}, /* Lao */ + { 80, "vi"}, /* Vietnamese */ + { 81, "id"}, /* Indonesian */ + { 82, "tl"}, /* Tagalog */ + { 83, "ms"}, /* Malay (Roman script) */ + { 84, "ms"}, /* Malay (Arabic script) */ + { 85, "am"}, /* Amharic */ + { 86, "ti"}, /* Tigrinya */ + { 87, "om"}, /* Galla */ + { 88, "so"}, /* Somali */ + { 89, "sw"}, /* Swahili */ + { 90, "rw"}, /* Kinyarwanda/Ruanda */ + { 91, "rn"}, /* Rundi */ + { 92, "ny"}, /* Nyanja/Chewa */ + { 93, "mg"}, /* Malagasy */ + { 94, "eo"}, /* Esperanto */ + {128, "cy"}, /* Welsh */ + {129, "eu"}, /* Basque */ + {130, "ca"}, /* Catalan */ + {131, "la"}, /* Latin */ + {132, "qu"}, /* Quechua */ + {133, "gn"}, /* Guarani */ + {134, "ay"}, /* Aymara */ + {135, "tt"}, /* Tatar */ + {136, "ug"}, /* Uighur */ + {137, "dz"}, /* Dzongkha */ + {138, "jw"}, /* Javanese (Roman script) */ + {139, "su"}, /* Sundanese (Roman script) */ + {140, "gl"}, /* Galician */ + {141, "af"}, /* Afrikaans */ + {142, "br"}, /* Breton */ + {143, "iu"}, /* Inuktitut */ + {144, "gd"}, /* Scottish Gaelic */ + {145, "gv"}, /* Manx Gaelic */ + {146, "ga"}, /* Irish Gaelic (with dot above) */ + {147, "to"}, /* Tongan */ + {148, "el"}, /* Greek (polytonic) */ + {149, "ik"}, /* Greenlandic */ + {150, "az"}, /* Azerbaijani (Roman script) */ +}; + + +static hb_language_t +_hb_ot_name_language_for (unsigned int code, + const hb_ot_language_map_t *array, + unsigned int len) +{ + const hb_ot_language_map_t *entry = (const hb_ot_language_map_t *) + hb_bsearch (&code, + array, + len, + sizeof (array[0]), + hb_ot_language_map_t::cmp); + + if (entry) + return hb_language_from_string (entry->lang, -1); + + return HB_LANGUAGE_INVALID; +} + +hb_language_t +_hb_ot_name_language_for_ms_code (unsigned int code) +{ + return _hb_ot_name_language_for (code, + hb_ms_language_map, + ARRAY_LENGTH (hb_ms_language_map)); +} + +hb_language_t +_hb_ot_name_language_for_mac_code (unsigned int code) +{ + return _hb_ot_name_language_for (code, + hb_mac_language_map, + ARRAY_LENGTH (hb_mac_language_map)); +} + +#endif /* HB_OT_NAME_LANGUAGE_STATIC_HH */ diff --git a/src/hb-ot-name-language.hh b/src/hb-ot-name-language.hh index a5449764c..903076c0d 100644 --- a/src/hb-ot-name-language.hh +++ b/src/hb-ot-name-language.hh @@ -29,436 +29,12 @@ #include "hb.hh" -/* Following two tables were generated by joining FreeType, FontConfig, - * and OpenType specification language lists, then filled in missing - * entries using: - * https://docs.microsoft.com/en-us/windows/desktop/intl/language-identifier-constants-and-strings - */ -struct hb_ot_language_map_t -{ - static int cmp (const void *key, const void *item) - { - unsigned int a = * (unsigned int *) key; - unsigned int b = ((const hb_ot_language_map_t *) item)->code; - return a < b ? -1 : a > b ? +1 : 0; - } +HB_INTERNAL hb_language_t +_hb_ot_name_language_for_ms_code (unsigned int code); - uint16_t code; - char lang[6]; -}; - - -static const hb_ot_language_map_t -hb_ms_language_map[] = -{ - {0x0001, "ar"}, /* ??? */ - {0x0004, "zh"}, /* ??? */ - {0x0009, "en"}, /* ??? */ - {0x0401, "ar"}, /* Arabic (Saudi Arabia) */ - {0x0402, "bg"}, /* Bulgarian (Bulgaria) */ - {0x0403, "ca"}, /* Catalan (Catalan) */ - {0x0404, "zh-tw"}, /* Chinese (Taiwan) */ - {0x0405, "cs"}, /* Czech (Czech Republic) */ - {0x0406, "da"}, /* Danish (Denmark) */ - {0x0407, "de"}, /* German (Germany) */ - {0x0408, "el"}, /* Greek (Greece) */ - {0x0409, "en"}, /* English (United States) */ - {0x040A, "es"}, /* Spanish (Traditional Sort) (Spain) */ - {0x040B, "fi"}, /* Finnish (Finland) */ - {0x040C, "fr"}, /* French (France) */ - {0x040D, "he"}, /* Hebrew (Israel) */ - {0x040E, "hu"}, /* Hungarian (Hungary) */ - {0x040F, "is"}, /* Icelandic (Iceland) */ - {0x0410, "it"}, /* Italian (Italy) */ - {0x0411, "ja"}, /* Japanese (Japan) */ - {0x0412, "ko"}, /* Korean (Korea) */ - {0x0413, "nl"}, /* Dutch (Netherlands) */ - {0x0414, "no"}, /* Norwegian (Bokmal) (Norway) */ - {0x0415, "pl"}, /* Polish (Poland) */ - {0x0416, "pt"}, /* Portuguese (Brazil) */ - {0x0417, "rm"}, /* Romansh (Switzerland) */ - {0x0418, "ro"}, /* Romanian (Romania) */ - {0x0419, "ru"}, /* Russian (Russia) */ - {0x041A, "hr"}, /* Croatian (Croatia) */ - {0x041B, "sk"}, /* Slovak (Slovakia) */ - {0x041C, "sq"}, /* Albanian (Albania) */ - {0x041D, "sv"}, /* Swedish (Sweden) */ - {0x041E, "th"}, /* Thai (Thailand) */ - {0x041F, "tr"}, /* Turkish (Turkey) */ - {0x0420, "ur"}, /* Urdu (Islamic Republic of Pakistan) */ - {0x0421, "id"}, /* Indonesian (Indonesia) */ - {0x0422, "uk"}, /* Ukrainian (Ukraine) */ - {0x0423, "be"}, /* Belarusian (Belarus) */ - {0x0424, "sl"}, /* Slovenian (Slovenia) */ - {0x0425, "et"}, /* Estonian (Estonia) */ - {0x0426, "lv"}, /* Latvian (Latvia) */ - {0x0427, "lt"}, /* Lithuanian (Lithuania) */ - {0x0428, "tg"}, /* Tajik (Cyrillic) (Tajikistan) */ - {0x0429, "fa"}, /* Persian (Iran) */ - {0x042A, "vi"}, /* Vietnamese (Vietnam) */ - {0x042B, "hy"}, /* Armenian (Armenia) */ - {0x042C, "az"}, /* Azeri (Latin) (Azerbaijan) */ - {0x042D, "eu"}, /* Basque (Basque) */ - {0x042E, "hsb"}, /* Upper Sorbian (Germany) */ - {0x042F, "mk"}, /* Macedonian (FYROM) (Former Yugoslav Republic of Macedonia) */ - {0x0430, "st"}, /* ??? */ - {0x0431, "ts"}, /* ??? */ - {0x0432, "tn"}, /* Setswana (South Africa) */ - {0x0433, "ven"}, /* ??? */ - {0x0434, "xh"}, /* isiXhosa (South Africa) */ - {0x0435, "zu"}, /* isiZulu (South Africa) */ - {0x0436, "af"}, /* Afrikaans (South Africa) */ - {0x0437, "ka"}, /* Georgian (Georgia) */ - {0x0438, "fo"}, /* Faroese (Faroe Islands) */ - {0x0439, "hi"}, /* Hindi (India) */ - {0x043A, "mt"}, /* Maltese (Malta) */ - {0x043B, "se"}, /* Sami (Northern) (Norway) */ - {0x043C, "ga"}, /* ??? */ - {0x043D, "yi"}, /* ??? */ - {0x043E, "ms"}, /* Malay (Malaysia) */ - {0x043F, "kk"}, /* Kazakh (Kazakhstan) */ - {0x0440, "ky"}, /* Kyrgyz (Kyrgyzstan) */ - {0x0441, "sw"}, /* Kiswahili (Kenya) */ - {0x0442, "tk"}, /* Turkmen (Turkmenistan) */ - {0x0443, "uz"}, /* Uzbek (Latin) (Uzbekistan) */ - {0x0444, "tt"}, /* Tatar (Russia) */ - {0x0445, "bn"}, /* Bengali (India) */ - {0x0446, "pa"}, /* Punjabi (India) */ - {0x0447, "gu"}, /* Gujarati (India) */ - {0x0448, "or"}, /* Odia (formerly Oriya) (India) */ - {0x0449, "ta"}, /* Tamil (India) */ - {0x044A, "te"}, /* Telugu (India) */ - {0x044B, "kn"}, /* Kannada (India) */ - {0x044C, "ml"}, /* Malayalam (India) */ - {0x044D, "as"}, /* Assamese (India) */ - {0x044E, "mr"}, /* Marathi (India) */ - {0x044F, "sa"}, /* Sanskrit (India) */ - {0x0450, "mn"}, /* Mongolian (Cyrillic) (Mongolia) */ - {0x0451, "bo"}, /* Tibetan (PRC) */ - {0x0452, "cy"}, /* Welsh (United Kingdom) */ - {0x0453, "km"}, /* Khmer (Cambodia) */ - {0x0454, "lo"}, /* Lao (Lao P.D.R.) */ - {0x0455, "my"}, /* ??? */ - {0x0456, "gl"}, /* Galician (Galician) */ - {0x0457, "kok"}, /* Konkani (India) */ - {0x0458, "mni"}, /* ??? */ - {0x0459, "sd"}, /* ??? */ - {0x045A, "syr"}, /* Syriac (Syria) */ - {0x045B, "si"}, /* Sinhala (Sri Lanka) */ - {0x045C, "chr"}, /* ??? */ - {0x045D, "iu"}, /* Inuktitut (Canada) */ - {0x045E, "am"}, /* Amharic (Ethiopia) */ - {0x0460, "ks"}, /* ??? */ - {0x0461, "ne"}, /* Nepali (Nepal) */ - {0x0462, "fy"}, /* Frisian (Netherlands) */ - {0x0463, "ps"}, /* Pashto (Afghanistan) */ - {0x0464, "phi"}, /* Filipino (Philippines) */ - {0x0465, "div"}, /* Divehi (Maldives) */ - {0x0468, "ha"}, /* Hausa (Latin) (Nigeria) */ - {0x046A, "yo"}, /* Yoruba (Nigeria) */ - {0x046B, "quz"}, /* Quechua (Bolivia) */ - {0x046C, "nso"}, /* Sesotho sa Leboa (South Africa) */ - {0x046D, "ba"}, /* Bashkir (Russia) */ - {0x046E, "lb"}, /* Luxembourgish (Luxembourg) */ - {0x046F, "kl"}, /* Greenlandic (Greenland) */ - {0x0470, "ibo"}, /* Igbo (Nigeria) */ - {0x0471, "kau"}, /* ??? */ - {0x0472, "om"}, /* ??? */ - {0x0473, "ti"}, /* ??? */ - {0x0474, "gn"}, /* ??? */ - {0x0475, "haw"}, /* ??? */ - {0x0476, "la"}, /* ??? */ - {0x0477, "so"}, /* ??? */ - {0x0478, "ii"}, /* Yi (PRC) */ - {0x0479, "pap"}, /* ??? */ - {0x047A, "arn"}, /* Mapudungun (Chile) */ - {0x047C, "moh"}, /* Mohawk (Mohawk) */ - {0x047E, "br"}, /* Breton (France) */ - {0x0480, "ug"}, /* Uighur (PRC) */ - {0x0481, "mi"}, /* Maori (New Zealand) */ - {0x0482, "oc"}, /* Occitan (France) */ - {0x0483, "co"}, /* Corsican (France) */ - {0x0484, "gsw"}, /* Alsatian (France) */ - {0x0485, "sah"}, /* Yakut (Russia) */ - {0x0486, "qut"}, /* K'iche (Guatemala) */ - {0x0487, "rw"}, /* Kinyarwanda (Rwanda) */ - {0x0488, "wo"}, /* Wolof (Senegal) */ - {0x048C, "fa"}, /* Dari (Afghanistan) */ - {0x0801, "ar"}, /* Arabic (Iraq) */ - {0x0804, "zh-cn"}, /* Chinese (People’s Republic of China) */ - {0x0807, "de"}, /* German (Switzerland) */ - {0x0809, "en"}, /* English (United Kingdom) */ - {0x080A, "es"}, /* Spanish (Mexico) */ - {0x080C, "fr"}, /* French (Belgium) */ - {0x0810, "it"}, /* Italian (Switzerland) */ - {0x0812, "ko"}, /* ??? */ - {0x0813, "nl"}, /* Dutch (Belgium) */ - {0x0814, "nn"}, /* Norwegian (Nynorsk) (Norway) */ - {0x0816, "pt"}, /* Portuguese (Portugal) */ - {0x0818, "mo"}, /* ??? */ - {0x0819, "ru"}, /* ??? */ - {0x081A, "sr"}, /* Serbian (Latin) (Serbia) */ - {0x081D, "sv"}, /* Sweden (Finland) */ - {0x0820, "ur"}, /* ??? */ - {0x0827, "lt"}, /* ??? */ - {0x082C, "az"}, /* Azeri (Cyrillic) (Azerbaijan) */ - {0x082E, "dsb"}, /* Lower Sorbian (Germany) */ -//{0x083B, ""}, /* Sami (Northern) (Sweden) */ - {0x083C, "gd"}, /* Irish (Ireland) */ - {0x083E, "ms"}, /* Malay (Brunei Darussalam) */ - {0x0843, "uz"}, /* Uzbek (Cyrillic) (Uzbekistan) */ - {0x0845, "bn"}, /* Bengali (Bangladesh) */ - {0x0846, "ar"}, /* ??? */ - {0x0850, "mn"}, /* Mongolian (Traditional) (People’s Republic of China) */ - {0x0851, "dz"}, /* ??? */ - {0x085D, "iu"}, /* Inuktitut (Latin) (Canada) */ - {0x085F, "tzm"}, /* Tamazight (Latin) (Algeria) */ - {0x0861, "ne"}, /* ??? */ -//{0x086B, ""}, /* Quechua (Ecuador) */ - {0x0873, "ti"}, /* ??? */ - {0x0C01, "ar"}, /* Arabic (Egypt) */ - {0x0C04, "zh-hk"}, /* Chinese (Hong Kong S.A.R.) */ - {0x0C07, "de"}, /* German (Austria) */ - {0x0C09, "en"}, /* English (Australia) */ - {0x0C0A, "es"}, /* Spanish (Modern Sort) (Spain) */ - {0x0C0C, "fr"}, /* French (Canada) */ - {0x0C1A, "sr"}, /* Serbian (Cyrillic) (Serbia) */ - {0x0C3B, "se"}, /* Sami (Northern) (Finland) */ -//{0x0C6B, ""}, /* Quechua (Peru) */ - {0x1001, "ar"}, /* Arabic (Libya) */ - {0x1004, "zh-sg"}, /* Chinese (Singapore) */ - {0x1007, "de"}, /* German (Luxembourg) */ - {0x1009, "en"}, /* English (Canada) */ - {0x100A, "es"}, /* Spanish (Guatemala) */ - {0x100C, "fr"}, /* French (Switzerland) */ - {0x101A, "hr"}, /* Croatian (Latin) (Bosnia and Herzegovina) */ - {0x103B, "smj"}, /* Sami (Lule) (Norway) */ - {0x1401, "ar"}, /* Arabic (Algeria) */ -//{0x1404, ""}, /* Chinese (Macao S.A.R.) */ - {0x1407, "de"}, /* German (Liechtenstein) */ - {0x1409, "en"}, /* English (New Zealand) */ - {0x140A, "es"}, /* Spanish (Costa Rica) */ - {0x140C, "fr"}, /* French (Luxembourg) */ - {0x141A, "bs"}, /* Bosnian (Latin) (Bosnia and Herzegovina) */ -//{0x143B, ""}, /* Sami (Lule) (Sweden) */ - {0x1801, "ar"}, /* Arabic (Morocco) */ - {0x1809, "en"}, /* English (Ireland) */ - {0x180A, "es"}, /* Spanish (Panama) */ - {0x180C, "fr"}, /* French (Principality of Monaco) */ -//{0x181A, ""}, /* Serbian (Latin) (Bosnia and Herzegovina) */ - {0x183B, "sma"}, /* Sami (Southern) (Norway) */ - {0x1C01, "ar"}, /* Arabic (Tunisia) */ - {0x1C09, "en"}, /* English (South Africa) */ - {0x1C0A, "es"}, /* Spanish (Dominican Republic) */ - {0x1C0C, "fr"}, /* ??? */ -//{0x1C1A, ""}, /* Serbian (Cyrillic) (Bosnia and Herzegovina) */ -//{0x1C3B, ""}, /* Sami (Southern) (Sweden) */ - {0x2001, "ar"}, /* Arabic (Oman) */ - {0x2009, "en"}, /* English (Jamaica) */ - {0x200A, "es"}, /* Spanish (Venezuela) */ - {0x200C, "fr"}, /* ??? */ - {0x201A, "bs"}, /* Bosnian (Cyrillic) (Bosnia and Herzegovina) */ - {0x203B, "sms"}, /* Sami (Skolt) (Finland) */ - {0x2401, "ar"}, /* Arabic (Yemen) */ - {0x2409, "en"}, /* English (Caribbean) */ - {0x240A, "es"}, /* Spanish (Colombia) */ - {0x240C, "fr"}, /* ??? */ - {0x243B, "smn"}, /* Sami (Inari) (Finland) */ - {0x2801, "ar"}, /* Arabic (Syria) */ - {0x2809, "en"}, /* English (Belize) */ - {0x280A, "es"}, /* Spanish (Peru) */ - {0x280C, "fr"}, /* ??? */ - {0x2C01, "ar"}, /* Arabic (Jordan) */ - {0x2C09, "en"}, /* English (Trinidad and Tobago) */ - {0x2C0A, "es"}, /* Spanish (Argentina) */ - {0x2C0C, "fr"}, /* ??? */ - {0x3001, "ar"}, /* Arabic (Lebanon) */ - {0x3009, "en"}, /* English (Zimbabwe) */ - {0x300A, "es"}, /* Spanish (Ecuador) */ - {0x300C, "fr"}, /* ??? */ - {0x3401, "ar"}, /* Arabic (Kuwait) */ - {0x3409, "en"}, /* English (Republic of the Philippines) */ - {0x340A, "es"}, /* Spanish (Chile) */ - {0x340C, "fr"}, /* ??? */ - {0x3801, "ar"}, /* Arabic (U.A.E.) */ - {0x380A, "es"}, /* Spanish (Uruguay) */ - {0x380C, "fr"}, /* ??? */ - {0x3C01, "ar"}, /* Arabic (Bahrain) */ - {0x3C09, "en"}, /* ??? */ - {0x3C0A, "es"}, /* Spanish (Paraguay) */ - {0x3C0C, "fr"}, /* ??? */ - {0x4001, "ar"}, /* Arabic (Qatar) */ - {0x4009, "en"}, /* English (India) */ - {0x400A, "es"}, /* Spanish (Bolivia) */ - {0x4409, "en"}, /* English (Malaysia) */ - {0x440A, "es"}, /* Spanish (El Salvador) */ - {0x4809, "en"}, /* English (Singapore) */ - {0x480A, "es"}, /* Spanish (Honduras) */ - {0x4C0A, "es"}, /* Spanish (Nicaragua) */ - {0x500A, "es"}, /* Spanish (Puerto Rico) */ - {0x540A, "es"}, /* Spanish (United States) */ - {0xE40A, "es"}, /* ??? */ - {0xE40C, "fr"}, /* ??? */ -}; - -static const hb_ot_language_map_t -hb_mac_language_map[] = -{ - { 0, "en"}, /* English */ - { 1, "fr"}, /* French */ - { 2, "de"}, /* German */ - { 3, "it"}, /* Italian */ - { 4, "nl"}, /* Dutch */ - { 5, "sv"}, /* Swedish */ - { 6, "es"}, /* Spanish */ - { 7, "da"}, /* Danish */ - { 8, "pt"}, /* Portuguese */ - { 9, "no"}, /* Norwegian */ - { 10, "he"}, /* Hebrew */ - { 11, "ja"}, /* Japanese */ - { 12, "ar"}, /* Arabic */ - { 13, "fi"}, /* Finnish */ - { 14, "el"}, /* Greek */ - { 15, "is"}, /* Icelandic */ - { 16, "mt"}, /* Maltese */ - { 17, "tr"}, /* Turkish */ - { 18, "hr"}, /* Croatian */ - { 19, "zh-tw"}, /* Chinese (Traditional) */ - { 20, "ur"}, /* Urdu */ - { 21, "hi"}, /* Hindi */ - { 22, "th"}, /* Thai */ - { 23, "ko"}, /* Korean */ - { 24, "lt"}, /* Lithuanian */ - { 25, "pl"}, /* Polish */ - { 26, "hu"}, /* Hungarian */ - { 27, "et"}, /* Estonian */ - { 28, "lv"}, /* Latvian */ -//{ 29, ""}, /* Sami */ - { 30, "fo"}, /* Faroese */ - { 31, "fa"}, /* Farsi/Persian */ - { 32, "ru"}, /* Russian */ - { 33, "zh-cn"}, /* Chinese (Simplified) */ - { 34, "nl"}, /* Flemish */ - { 35, "ga"}, /* Irish Gaelic */ - { 36, "sq"}, /* Albanian */ - { 37, "ro"}, /* Romanian */ - { 38, "cs"}, /* Czech */ - { 39, "sk"}, /* Slovak */ - { 40, "sl"}, /* Slovenian */ - { 41, "yi"}, /* Yiddish */ - { 42, "sr"}, /* Serbian */ - { 43, "mk"}, /* Macedonian */ - { 44, "bg"}, /* Bulgarian */ - { 45, "uk"}, /* Ukrainian */ - { 46, "be"}, /* Byelorussian */ - { 47, "uz"}, /* Uzbek */ - { 48, "kk"}, /* Kazakh */ - { 49, "az"}, /* Azerbaijani (Cyrillic script) */ - { 50, "az"}, /* Azerbaijani (Arabic script) */ - { 51, "hy"}, /* Armenian */ - { 52, "ka"}, /* Georgian */ - { 53, "mo"}, /* Moldavian */ - { 54, "ky"}, /* Kirghiz */ - { 55, "tg"}, /* Tajiki */ - { 56, "tk"}, /* Turkmen */ - { 57, "mn"}, /* Mongolian (Mongolian script) */ - { 58, "mn"}, /* Mongolian (Cyrillic script) */ - { 59, "ps"}, /* Pashto */ - { 60, "ku"}, /* Kurdish */ - { 61, "ks"}, /* Kashmiri */ - { 62, "sd"}, /* Sindhi */ - { 63, "bo"}, /* Tibetan */ - { 64, "ne"}, /* Nepali */ - { 65, "sa"}, /* Sanskrit */ - { 66, "mr"}, /* Marathi */ - { 67, "bn"}, /* Bengali */ - { 68, "as"}, /* Assamese */ - { 69, "gu"}, /* Gujarati */ - { 70, "pa"}, /* Punjabi */ - { 71, "or"}, /* Oriya */ - { 72, "ml"}, /* Malayalam */ - { 73, "kn"}, /* Kannada */ - { 74, "ta"}, /* Tamil */ - { 75, "te"}, /* Telugu */ - { 76, "si"}, /* Sinhalese */ - { 77, "my"}, /* Burmese */ - { 78, "km"}, /* Khmer */ - { 79, "lo"}, /* Lao */ - { 80, "vi"}, /* Vietnamese */ - { 81, "id"}, /* Indonesian */ - { 82, "tl"}, /* Tagalog */ - { 83, "ms"}, /* Malay (Roman script) */ - { 84, "ms"}, /* Malay (Arabic script) */ - { 85, "am"}, /* Amharic */ - { 86, "ti"}, /* Tigrinya */ - { 87, "om"}, /* Galla */ - { 88, "so"}, /* Somali */ - { 89, "sw"}, /* Swahili */ - { 90, "rw"}, /* Kinyarwanda/Ruanda */ - { 91, "rn"}, /* Rundi */ - { 92, "ny"}, /* Nyanja/Chewa */ - { 93, "mg"}, /* Malagasy */ - { 94, "eo"}, /* Esperanto */ - {128, "cy"}, /* Welsh */ - {129, "eu"}, /* Basque */ - {130, "ca"}, /* Catalan */ - {131, "la"}, /* Latin */ - {132, "qu"}, /* Quechua */ - {133, "gn"}, /* Guarani */ - {134, "ay"}, /* Aymara */ - {135, "tt"}, /* Tatar */ - {136, "ug"}, /* Uighur */ - {137, "dz"}, /* Dzongkha */ - {138, "jw"}, /* Javanese (Roman script) */ - {139, "su"}, /* Sundanese (Roman script) */ - {140, "gl"}, /* Galician */ - {141, "af"}, /* Afrikaans */ - {142, "br"}, /* Breton */ - {143, "iu"}, /* Inuktitut */ - {144, "gd"}, /* Scottish Gaelic */ - {145, "gv"}, /* Manx Gaelic */ - {146, "ga"}, /* Irish Gaelic (with dot above) */ - {147, "to"}, /* Tongan */ - {148, "el"}, /* Greek (polytonic) */ - {149, "ik"}, /* Greenlandic */ - {150, "az"}, /* Azerbaijani (Roman script) */ -}; - -static hb_language_t -_hb_ot_name_language_for (unsigned int code, - const hb_ot_language_map_t *array, - unsigned int len) -{ - const hb_ot_language_map_t *entry = (const hb_ot_language_map_t *) - hb_bsearch (&code, - array, - len, - sizeof (array[0]), - hb_ot_language_map_t::cmp); - - if (entry) - return hb_language_from_string (entry->lang, -1); - - return HB_LANGUAGE_INVALID; -} - - -inline hb_language_t -_hb_ot_name_language_for_ms_code (unsigned int code) -{ - return _hb_ot_name_language_for (code, - hb_ms_language_map, - ARRAY_LENGTH (hb_ms_language_map)); -} - -inline hb_language_t -_hb_ot_name_language_for_mac_code (unsigned int code) -{ - return _hb_ot_name_language_for (code, - hb_mac_language_map, - ARRAY_LENGTH (hb_mac_language_map)); -} +HB_INTERNAL hb_language_t +_hb_ot_name_language_for_mac_code (unsigned int code); #endif /* HB_OT_NAME_LANGUAGE_HH */ diff --git a/src/hb-static.cc b/src/hb-static.cc index 4c5158860..d2d8044a7 100644 --- a/src/hb-static.cc +++ b/src/hb-static.cc @@ -36,6 +36,8 @@ #include "hb-ot-head-table.hh" #include "hb-ot-maxp-table.hh" +#include "hb-ot-name-language-static.hh" + #ifndef HB_NO_VISIBILITY hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)] = {}; From 8c8922a019eb1ceb8beffc05ca638ee0ca25b565 Mon Sep 17 00:00:00 2001 From: Qunxin Liu Date: Thu, 25 Apr 2019 09:17:58 -0700 Subject: [PATCH 61/69] [subset] Updates due to changes in resolve_links() on master branch --- src/Makefile.sources | 1 + src/hb-ot-name-table.hh | 7 +++++-- src/hb-static.cc | 3 +-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Makefile.sources b/src/Makefile.sources index 803d229ac..e61315be6 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -84,6 +84,7 @@ HB_BASE_sources = \ hb-ot-math-table.hh \ hb-ot-math.cc \ hb-ot-maxp-table.hh \ + hb-ot-name-language-static.hh \ hb-ot-name-language.hh \ hb-ot-name-table.hh \ hb-ot-name.cc \ diff --git a/src/hb-ot-name-table.hh b/src/hb-ot-name-table.hh index 056a77a06..72deb10b4 100644 --- a/src/hb-ot-name-table.hh +++ b/src/hb-ot-name-table.hh @@ -187,8 +187,11 @@ struct name } c->push (); - if (!c->embed (source_name->nameRecordZ[idx])) + + NameRecord *p = c->embed (source_name->nameRecordZ[idx]); + if (!p) return false; + p->offset = 0; } return true; @@ -233,7 +236,7 @@ struct name hb_serialize_context_t *c, unsigned length) { - hb_hashmap_t id_str_idx_map; + hb_hashmap_t id_str_idx_map; for (int i = length-1; i >= 0; i--) { unsigned objidx = c->pop_pack (); diff --git a/src/hb-static.cc b/src/hb-static.cc index d2d8044a7..6b89183ca 100644 --- a/src/hb-static.cc +++ b/src/hb-static.cc @@ -36,9 +36,8 @@ #include "hb-ot-head-table.hh" #include "hb-ot-maxp-table.hh" -#include "hb-ot-name-language-static.hh" - #ifndef HB_NO_VISIBILITY +#include "hb-ot-name-language-static.hh" hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)] = {}; /*thread_local*/ hb_vector_size_impl_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)] = {}; From 750b65e9a980efc13e50ea5d0388ecf06e7a93b1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 26 Apr 2019 17:14:25 -0700 Subject: [PATCH 62/69] [meta] Add hb_type_identity<> To block template argument deduction. --- src/hb-meta.hh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/hb-meta.hh b/src/hb-meta.hh index c3efe48a6..b80358c2a 100644 --- a/src/hb-meta.hh +++ b/src/hb-meta.hh @@ -65,6 +65,9 @@ template <> struct hb_priority<0> {}; #define HB_FUNCOBJ(x) static_const x HB_UNUSED +template struct hb_match_identity { typedef T type; }; +template using hb_type_identity = typename hb_match_identity::type; + struct { template @@ -96,6 +99,7 @@ template struct hb_match_pointer { typedef T type; enum { valu template using hb_remove_pointer = typename hb_match_pointer::type; #define hb_is_pointer(T) hb_match_pointer::value +/* TODO Add feature-parity to std::decay. */ template using hb_decay = hb_remove_const>; #define hb_is_cr_convertible_to(A, B) ( \ From 2b051e7aa147c78cfbf953b6f0eb18c25b732eb2 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Apr 2019 10:01:11 -0700 Subject: [PATCH 63/69] [subset] Check error after calling serializer end --- src/hb-subset.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 2165b8a72..b40eba361 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -99,12 +99,11 @@ _subset2 (hb_subset_plan_t *plan) } goto retry; } - if (serializer.in_error ()) - { - abort (); - } - serializer.end_serialize (); + + if (serializer.in_error ()) + abort (); + if (result) { hb_blob_t *dest_blob = serializer.copy_blob (); From 6977a95fed8a35d6e915ed3fc3a3ea8709f3d4a4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Sat, 27 Apr 2019 10:05:25 -0700 Subject: [PATCH 64/69] [subset] Don't crash if subsetting GSUB/GPOS fails Fixes fuzzer issue. --- src/hb-subset.cc | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/src/hb-subset.cc b/src/hb-subset.cc index b40eba361..5f482e18a 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -68,11 +68,11 @@ template static bool _subset2 (hb_subset_plan_t *plan) { + bool result = true; hb_blob_t *source_blob = hb_sanitize_context_t ().reference_table (plan->source); const TableType *table = source_blob->as (); hb_tag_t tag = TableType::tableTag; - hb_bool_t result = false; if (source_blob->data) { hb_vector_t buf; @@ -87,7 +87,7 @@ _subset2 (hb_subset_plan_t *plan) hb_serialize_context_t serializer ((void *) buf, buf_size); serializer.start_serialize (); hb_subset_context_t c (plan, &serializer); - result = table->subset (&c); + bool needed = table->subset (&c); if (serializer.ran_out_of_room) { buf_size += (buf_size >> 1) + 32; @@ -101,20 +101,21 @@ _subset2 (hb_subset_plan_t *plan) } serializer.end_serialize (); - if (serializer.in_error ()) - abort (); + result = !serializer.in_error (); if (result) { - hb_blob_t *dest_blob = serializer.copy_blob (); - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG (tag), dest_blob->length); - result = c.plan->add_table (tag, dest_blob); - hb_blob_destroy (dest_blob); - } - else - { - DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag)); - result = true; + if (needed) + { + hb_blob_t *dest_blob = serializer.copy_blob (); + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG (tag), dest_blob->length); + result = c.plan->add_table (tag, dest_blob); + hb_blob_destroy (dest_blob); + } + else + { + DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag)); + } } } else From 62c6e170728303f4225aaa25523675fc260ae1ab Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sun, 28 Apr 2019 10:55:07 -0700 Subject: [PATCH 65/69] [test] Add crbug.com/oss-fuzz/14474 testcase Fixed at 6977a95f --- ...-minimized-hb-subset-fuzzer-5716947896893440 | Bin 0 -> 65833 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5716947896893440 diff --git a/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5716947896893440 b/test/fuzzing/fonts/clusterfuzz-testcase-minimized-hb-subset-fuzzer-5716947896893440 new file mode 100644 index 0000000000000000000000000000000000000000..639132038d0e7f0bb13b81d38993453b5781e591 GIT binary patch literal 65833 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 literal 0 HcmV?d00001 From 6d6edc8b25395c87477181a647a8e6d02f2cad4f Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Sun, 28 Apr 2019 11:54:07 -0700 Subject: [PATCH 66/69] [valgrind] Use libtool and support run-subset-fuzzer-tests (#1668) --- test/fuzzing/Makefile.am | 4 +- test/fuzzing/run-shape-fuzzer-tests.py | 28 ++++----- test/fuzzing/run-subset-fuzzer-tests.py | 75 +++++++++++++++++++++++-- 3 files changed, 85 insertions(+), 22 deletions(-) diff --git a/test/fuzzing/Makefile.am b/test/fuzzing/Makefile.am index a77df7061..5bd2d7e6d 100644 --- a/test/fuzzing/Makefile.am +++ b/test/fuzzing/Makefile.am @@ -55,8 +55,8 @@ hb_subset_fuzzer_CPPFLAGS = $(AM_CPPFLAGS) hb_subset_fuzzer_DEPENDENCIES = $(top_builddir)/src/libharfbuzz-subset.la check: - EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-shape-fuzzer-tests.py - EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-subset-fuzzer-tests.py + EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" LIBTOOL="$(LIBTOOL)" $(srcdir)/run-shape-fuzzer-tests.py + EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" LIBTOOL="$(LIBTOOL)" $(srcdir)/run-subset-fuzzer-tests.py check-valgrind: $(AM_V_at)RUN_VALGRIND=1 $(MAKE) $(AM_MAKEFLGS) check diff --git a/test/fuzzing/run-shape-fuzzer-tests.py b/test/fuzzing/run-shape-fuzzer-tests.py index 90ed509c7..ba480dd52 100755 --- a/test/fuzzing/run-shape-fuzzer-tests.py +++ b/test/fuzzing/run-shape-fuzzer-tests.py @@ -67,36 +67,36 @@ please provide it as the first argument to the tool""") print ('hb_shape_fuzzer:', hb_shape_fuzzer) fails = 0 +libtool = os.environ.get('LIBTOOL') valgrind = None if os.environ.get('RUN_VALGRIND', ''): valgrind = which ('valgrind') if valgrind is None: print ("""Valgrind requested but not found.""") sys.exit (1) + if libtool is None: + print ("""Valgrind support is currently autotools only and needs libtool but not found.""") + parent_path = os.path.join (srcdir, "fonts") for file in os.listdir (parent_path): path = os.path.join(parent_path, file) - text, returncode = cmd ([hb_shape_fuzzer, path]) - if text.strip (): + if valgrind: + text, returncode = cmd (libtool.split(' ') + ['--mode=execute', valgrind + ' --leak-check=full --error-exitcode=1', '--', hb_shape_fuzzer, path]) + else: + text, returncode = cmd ([hb_shape_fuzzer, path]) + if 'error' in text: + returncode = 1 + + if not valgrind and text.strip (): print (text) - failed = False - if returncode != 0 or 'error' in text: + if returncode != 0: print ('failure on %s' % file) - failed = True - - if valgrind: - text, returncode = cmd ([valgrind, '--error-exitcode=1', '--leak-check=full', hb_shape_fuzzer, path]) - if returncode: - print (text) - print ('failure on %s' % file) - failed = True - - if failed: fails = fails + 1 + if fails: print ("%i shape fuzzer related tests failed." % fails) sys.exit (1) diff --git a/test/fuzzing/run-subset-fuzzer-tests.py b/test/fuzzing/run-subset-fuzzer-tests.py index 7392a92ec..3ac22889e 100755 --- a/test/fuzzing/run-subset-fuzzer-tests.py +++ b/test/fuzzing/run-subset-fuzzer-tests.py @@ -2,7 +2,54 @@ from __future__ import print_function, division, absolute_import -import sys, os, subprocess +import sys, os, subprocess, tempfile, threading + + +def which(program): + # https://stackoverflow.com/a/377028 + def is_exe(fpath): + return os.path.isfile(fpath) and os.access(fpath, os.X_OK) + + fpath, _ = os.path.split(program) + if fpath: + if is_exe(program): + return program + else: + for path in os.environ["PATH"].split(os.pathsep): + exe_file = os.path.join(path, program) + if is_exe(exe_file): + return exe_file + + return None + + +def cmd(command): + # https://stackoverflow.com/a/4408409 + # https://stackoverflow.com/a/10012262 + with tempfile.TemporaryFile() as tempf: + p = subprocess.Popen (command, stderr=tempf) + is_killed = {'value': False} + + def timeout(p, is_killed): + is_killed['value'] = True + p.kill() + timer = threading.Timer (2, timeout, [p, is_killed]) + + try: + timer.start() + p.wait () + tempf.seek (0) + text = tempf.read().decode ("utf-8").strip () + returncode = p.returncode + finally: + timer.cancel() + + if is_killed['value']: + text = 'error: timeout, ' + text + returncode = 1 + + return text, returncode + srcdir = os.environ.get ("srcdir", ".") EXEEXT = os.environ.get ("EXEEXT", "") @@ -20,21 +67,37 @@ please provide it as the first argument to the tool""") print ('hb_subset_fuzzer:', hb_subset_fuzzer) fails = 0 +libtool = os.environ.get('LIBTOOL') +valgrind = None +if os.environ.get('RUN_VALGRIND', ''): + valgrind = which ('valgrind') + if valgrind is None: + print ("""Valgrind requested but not found.""") + sys.exit (1) + if libtool is None: + print ("""Valgrind support is currently autotools only and needs libtool but not found.""") + + def run_dir (parent_path): global fails for file in os.listdir (parent_path): path = os.path.join(parent_path, file) print ("running subset fuzzer against %s" % path) - p = subprocess.Popen ([hb_subset_fuzzer, path]) + if valgrind: + text, returncode = cmd (libtool.split(' ') + ['--mode=execute', valgrind + ' --leak-check=full --show-leak-kinds=all --error-exitcode=1', '--', hb_subset_fuzzer, path]) + else: + text, returncode = cmd ([hb_subset_fuzzer, path]) + if 'error' in text: + returncode = 1 - if p.wait () != 0: + if not valgrind and text.strip (): + print (text) + + if returncode != 0: print ("failed for %s" % path) fails = fails + 1 - if p.wait () != 0: - print ("failed for %s" % path) - fails = fails + 1 run_dir (os.path.join (srcdir, "..", "subset", "data", "fonts")) # TODO running these tests very slow tests. Fix and re-enable From 4aa546b70ad7b11154b901e67f98c1ec6bc5c364 Mon Sep 17 00:00:00 2001 From: David Corbett Date: Mon, 29 Apr 2019 14:16:51 -0400 Subject: [PATCH 67/69] Allow some Balinese Po & So as aksara modre bases --- src/gen-use-table.py | 10 ++++++++-- src/hb-ot-shape-complex-use-table.cc | 4 ++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/gen-use-table.py b/src/gen-use-table.py index 029e66e53..1a33b8af5 100755 --- a/src/gen-use-table.py +++ b/src/gen-use-table.py @@ -48,6 +48,12 @@ defaults = ('Other', 'Not_Applicable', 'Cn', 'No_Block') # TODO Characters that are not in Unicode Indic files, but used in USE data[0][0x034F] = defaults[0] data[0][0x2060] = defaults[0] +# TODO https://github.com/harfbuzz/harfbuzz/pull/1685 +data[0][0x1B5B] = 'Consonant_Placeholder' +data[0][0x1B5C] = 'Consonant_Placeholder' +data[0][0x1B5F] = 'Consonant_Placeholder' +data[0][0x1B62] = 'Consonant_Placeholder' +data[0][0x1B68] = 'Consonant_Placeholder' # TODO https://github.com/roozbehp/unicode-data/issues/9 data[0][0x11C44] = 'Consonant_Placeholder' data[0][0x11C45] = 'Consonant_Placeholder' @@ -171,7 +177,7 @@ def is_BASE(U, UISC, UGC): def is_BASE_IND(U, UISC, UGC): #SPEC-DRAFT return (UISC in [Consonant_Dead, Modifying_Letter] or UGC == Po) return (UISC in [Consonant_Dead, Modifying_Letter] or - (UGC == Po and not U in [0x104B, 0x104E, 0x2022, 0x111C8, 0x11A3F, 0x11A45, 0x11C44, 0x11C45]) or + (UGC == Po and not U in [0x104B, 0x104E, 0x1B5B, 0x1B5C, 0x1B5F, 0x2022, 0x111C8, 0x11A3F, 0x11A45, 0x11C44, 0x11C45]) or False # SPEC-DRAFT-OUTDATED! U == 0x002D ) def is_BASE_NUM(U, UISC, UGC): @@ -228,7 +234,7 @@ def is_REPHA(U, UISC, UGC): def is_SYM(U, UISC, UGC): if U == 0x25CC: return False #SPEC-DRAFT #SPEC-DRAFT return UGC in [So, Sc] or UISC == Symbol_Letter - return UGC in [So, Sc] + return UGC in [So, Sc] and U not in [0x1B62, 0x1B68] def is_SYM_MOD(U, UISC, UGC): return U in [0x1B6B, 0x1B6C, 0x1B6D, 0x1B6E, 0x1B6F, 0x1B70, 0x1B71, 0x1B72, 0x1B73] def is_VARIATION_SELECTOR(U, UISC, UGC): diff --git a/src/hb-ot-shape-complex-use-table.cc b/src/hb-ot-shape-complex-use-table.cc index cb5c358cd..ddf7053db 100644 --- a/src/hb-ot-shape-complex-use-table.cc +++ b/src/hb-ot-shape-complex-use-table.cc @@ -318,8 +318,8 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { /* 1B20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, /* 1B30 */ B, B, B, B, CMAbv, VPst, VAbv, VAbv, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VPre, VPre, /* 1B40 */ VPst, VPst, VAbv, VAbv, H, B, B, B, B, B, B, B, O, O, O, O, - /* 1B50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O, - /* 1B60 */ O, O, O, O, O, O, O, O, O, O, O, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv, + /* 1B50 */ B, B, B, B, B, B, B, B, B, B, O, GB, GB, O, O, GB, + /* 1B60 */ O, O, GB, O, O, O, O, O, GB, O, O, SMAbv, SMBlw, SMAbv, SMAbv, SMAbv, /* 1B70 */ SMAbv, SMAbv, SMAbv, SMAbv, O, O, O, O, O, O, O, O, O, O, O, O, /* Sundanese */ From e200d165a4e8a5f901165c705d617b6e457ec595 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Tue, 30 Apr 2019 02:10:50 +0430 Subject: [PATCH 68/69] [ci] Remove crosscompile-notest-freebsd9 bot It was testing an old version of freebsd and now it's image is gone. We really like to test the environment. --- .circleci/config.yml | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 1c901ebf1..9eeb1549e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -235,15 +235,6 @@ jobs: - run: CFLAGS="-Wno-attributes" CXXFLAGS="-Wno-attributes" ./autogen.sh --prefix=/usr/local/djgpp --host=i586-pc-msdosdjgpp - run: make -j32 - crosscompile-notest-freebsd9: - docker: - - image: donbowman/freebsd-cross-build - steps: - - checkout - - run: apt update && apt install -y pkg-config ragel - - run: ./autogen.sh --prefix=/freebsd --host=x86_64-pc-freebsd9 - - run: make -j32 - crosscompile-notest-psvita: docker: - image: dockcross/base @@ -327,7 +318,6 @@ workflows: # they can't be test thus are without tests ## autotools - crosscompile-notest-djgpp - - crosscompile-notest-freebsd9 - crosscompile-notest-psvita ## cmake From 9542bdd0ed2d581cdb4bd950ac3cd7e3bf899478 Mon Sep 17 00:00:00 2001 From: Ebrahim Byagowi Date: Mon, 29 Apr 2019 14:52:28 -0700 Subject: [PATCH 69/69] Add color channels getters ABI (#1513) So can be used with language wrappers --- src/hb-common.cc | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ src/hb-common.h | 44 ++++++++++++---------------------------- 2 files changed, 66 insertions(+), 31 deletions(-) diff --git a/src/hb-common.cc b/src/hb-common.cc index 60d16c8a4..c453443e7 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -1160,6 +1160,59 @@ hb_variation_to_string (hb_variation_t *variation, buf[len] = '\0'; } +/** + * hb_color_get_alpha: + * + * + * + * Since: REPLACEME + */ +uint8_t +(hb_color_get_alpha) (hb_color_t color) +{ + return hb_color_get_alpha (color); +} + +/** + * hb_color_get_red: + * + * + * + * Since: REPLACEME + */ +uint8_t +(hb_color_get_red) (hb_color_t color) +{ + return hb_color_get_red (color); +} + +/** + * hb_color_get_green: + * + * + * + * Since: REPLACEME + */ +uint8_t +(hb_color_get_green) (hb_color_t color) +{ + return hb_color_get_green (color); +} + +/** + * hb_color_get_blue: + * + * + * + * Since: REPLACEME + */ +uint8_t +(hb_color_get_blue) (hb_color_t color) +{ + return hb_color_get_blue (color); +} + + /* If there is no visibility control, then hb-static.cc will NOT * define anything. Instead, we get it to define one set in here * only, so only libharfbuzz.so defines them, not other libs. */ diff --git a/src/hb-common.h b/src/hb-common.h index 371b2bfc9..edd9ffb86 100644 --- a/src/hb-common.h +++ b/src/hb-common.h @@ -467,39 +467,21 @@ typedef uint32_t hb_color_t; #define HB_COLOR(b,g,r,a) ((hb_color_t) HB_TAG ((b),(g),(r),(a))) -/** - * hb_color_get_alpha: - * - * - * - * Since: 2.1.0 - */ +HB_EXTERN uint8_t +hb_color_get_alpha (hb_color_t color); #define hb_color_get_alpha(color) ((color) & 0xFF) -/** - * hb_color_get_red: - * - * - * - * Since: 2.1.0 - */ -#define hb_color_get_red(color) (((color) >> 8) & 0xFF) -/** - * hb_color_get_green: - * - * - * - * Since: 2.1.0 - */ -#define hb_color_get_green(color) (((color) >> 16) & 0xFF) -/** - * hb_color_get_blue: - * - * - * - * Since: 2.1.0 - */ -#define hb_color_get_blue(color) (((color) >> 24) & 0xFF) +HB_EXTERN uint8_t +hb_color_get_red (hb_color_t color); +#define hb_color_get_red(color) (((color) >> 8) & 0xFF) + +HB_EXTERN uint8_t +hb_color_get_green (hb_color_t color); +#define hb_color_get_green(color) (((color) >> 16) & 0xFF) + +HB_EXTERN uint8_t +hb_color_get_blue (hb_color_t color); +#define hb_color_get_blue(color) (((color) >> 24) & 0xFF) HB_END_DECLS