summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/harfbuzz-ng/src/graph/test-classdef-graph.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/graph/test-classdef-graph.cc')
-rw-r--r--src/3rdparty/harfbuzz-ng/src/graph/test-classdef-graph.cc223
1 files changed, 200 insertions, 23 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/graph/test-classdef-graph.cc b/src/3rdparty/harfbuzz-ng/src/graph/test-classdef-graph.cc
index 266be5e2d4..2da9348111 100644
--- a/src/3rdparty/harfbuzz-ng/src/graph/test-classdef-graph.cc
+++ b/src/3rdparty/harfbuzz-ng/src/graph/test-classdef-graph.cc
@@ -26,27 +26,119 @@
#include "gsubgpos-context.hh"
#include "classdef-graph.hh"
+#include "hb-iter.hh"
+#include "hb-serialize.hh"
typedef hb_codepoint_pair_t gid_and_class_t;
typedef hb_vector_t<gid_and_class_t> gid_and_class_list_t;
+template<typename It>
+static unsigned actual_class_def_size(It glyph_and_class) {
+ char buffer[100];
+ hb_serialize_context_t serializer(buffer, 100);
+ OT::ClassDef_serialize (&serializer, glyph_and_class);
+ serializer.end_serialize ();
+ assert(!serializer.in_error());
-static bool incremental_size_is (const gid_and_class_list_t& list, unsigned klass,
- unsigned cov_expected, unsigned class_def_expected)
+ hb_blob_t* blob = serializer.copy_blob();
+ unsigned size = hb_blob_get_length(blob);
+ hb_blob_destroy(blob);
+ return size;
+}
+
+static unsigned actual_class_def_size(gid_and_class_list_t consecutive_map, hb_vector_t<unsigned> classes) {
+ auto filtered_it =
+ + consecutive_map.as_sorted_array().iter()
+ | hb_filter([&] (unsigned c) {
+ for (unsigned klass : classes) {
+ if (c == klass) {
+ return true;
+ }
+ }
+ return false;
+ }, hb_second);
+ return actual_class_def_size(+ filtered_it);
+}
+
+template<typename It>
+static unsigned actual_coverage_size(It glyphs) {
+ char buffer[100];
+ hb_serialize_context_t serializer(buffer, 100);
+ OT::Layout::Common::Coverage_serialize (&serializer, glyphs);
+ serializer.end_serialize ();
+ assert(!serializer.in_error());
+
+ hb_blob_t* blob = serializer.copy_blob();
+ unsigned size = hb_blob_get_length(blob);
+ hb_blob_destroy(blob);
+ return size;
+}
+
+static unsigned actual_coverage_size(gid_and_class_list_t consecutive_map, hb_vector_t<unsigned> classes) {
+ auto filtered_it =
+ + consecutive_map.as_sorted_array().iter()
+ | hb_filter([&] (unsigned c) {
+ for (unsigned klass : classes) {
+ if (c == klass) {
+ return true;
+ }
+ }
+ return false;
+ }, hb_second);
+ return actual_coverage_size(+ filtered_it | hb_map_retains_sorting(hb_first));
+}
+
+static bool check_coverage_size(graph::class_def_size_estimator_t& estimator,
+ const gid_and_class_list_t& map,
+ hb_vector_t<unsigned> klasses)
+{
+ unsigned result = estimator.coverage_size();
+ unsigned expected = actual_coverage_size(map, klasses);
+ if (result != expected) {
+ printf ("FAIL: estimated coverage expected size %u but was %u\n", expected, result);
+ return false;
+ }
+ return true;
+}
+
+static bool check_add_class_def_size(graph::class_def_size_estimator_t& estimator,
+ const gid_and_class_list_t& map,
+ unsigned klass, hb_vector_t<unsigned> klasses)
+{
+ unsigned result = estimator.add_class_def_size(klass);
+ unsigned expected = actual_class_def_size(map, klasses);
+ if (result != expected) {
+ printf ("FAIL: estimated class def expected size %u but was %u\n", expected, result);
+ return false;
+ }
+
+ return check_coverage_size(estimator, map, klasses);
+}
+
+static bool check_add_class_def_size (const gid_and_class_list_t& list, unsigned klass)
{
graph::class_def_size_estimator_t estimator (list.iter ());
- unsigned result = estimator.incremental_coverage_size (klass);
- if (result != cov_expected)
+ unsigned result = estimator.add_class_def_size (klass);
+ auto filtered_it =
+ + list.as_sorted_array().iter()
+ | hb_filter([&] (unsigned c) {
+ return c == klass;
+ }, hb_second);
+
+ unsigned expected = actual_class_def_size(filtered_it);
+ if (result != expected)
{
- printf ("FAIL: coverage expected size %u but was %u\n", cov_expected, result);
+ printf ("FAIL: class def expected size %u but was %u\n", expected, result);
return false;
}
- result = estimator.incremental_class_def_size (klass);
- if (result != class_def_expected)
+ auto cov_it = + filtered_it | hb_map_retains_sorting(hb_first);
+ result = estimator.coverage_size ();
+ expected = actual_coverage_size(cov_it);
+ if (result != expected)
{
- printf ("FAIL: class def expected size %u but was %u\n", class_def_expected, result);
+ printf ("FAIL: coverage expected size %u but was %u\n", expected, result);
return false;
}
@@ -57,43 +149,45 @@ static void test_class_and_coverage_size_estimates ()
{
gid_and_class_list_t empty = {
};
- assert (incremental_size_is (empty, 0, 0, 0));
- assert (incremental_size_is (empty, 1, 0, 0));
+ assert (check_add_class_def_size (empty, 0));
+ assert (check_add_class_def_size (empty, 1));
gid_and_class_list_t class_zero = {
{5, 0},
};
- assert (incremental_size_is (class_zero, 0, 2, 0));
+ assert (check_add_class_def_size (class_zero, 0));
gid_and_class_list_t consecutive = {
{4, 0},
{5, 0},
+
{6, 1},
{7, 1},
+
{8, 2},
{9, 2},
{10, 2},
{11, 2},
};
- assert (incremental_size_is (consecutive, 0, 4, 0));
- assert (incremental_size_is (consecutive, 1, 4, 4));
- assert (incremental_size_is (consecutive, 2, 8, 6));
+ assert (check_add_class_def_size (consecutive, 0));
+ assert (check_add_class_def_size (consecutive, 1));
+ assert (check_add_class_def_size (consecutive, 2));
gid_and_class_list_t non_consecutive = {
{4, 0},
- {5, 0},
+ {6, 0},
- {6, 1},
- {7, 1},
+ {8, 1},
+ {10, 1},
{9, 2},
{10, 2},
{11, 2},
- {12, 2},
+ {13, 2},
};
- assert (incremental_size_is (non_consecutive, 0, 4, 0));
- assert (incremental_size_is (non_consecutive, 1, 4, 6));
- assert (incremental_size_is (non_consecutive, 2, 8, 6));
+ assert (check_add_class_def_size (non_consecutive, 0));
+ assert (check_add_class_def_size (non_consecutive, 1));
+ assert (check_add_class_def_size (non_consecutive, 2));
gid_and_class_list_t multiple_ranges = {
{4, 0},
@@ -108,12 +202,95 @@ static void test_class_and_coverage_size_estimates ()
{12, 1},
{13, 1},
};
- assert (incremental_size_is (multiple_ranges, 0, 4, 0));
- assert (incremental_size_is (multiple_ranges, 1, 2 * 6, 3 * 6));
+ assert (check_add_class_def_size (multiple_ranges, 0));
+ assert (check_add_class_def_size (multiple_ranges, 1));
+}
+
+static void test_running_class_and_coverage_size_estimates () {
+ // #### With consecutive gids: switches formats ###
+ gid_and_class_list_t consecutive_map = {
+ // range 1-4 (f1: 8 bytes), (f2: 6 bytes)
+ {1, 1},
+ {2, 1},
+ {3, 1},
+ {4, 1},
+
+ // (f1: 2 bytes), (f2: 6 bytes)
+ {5, 2},
+
+ // (f1: 14 bytes), (f2: 6 bytes)
+ {6, 3},
+ {7, 3},
+ {8, 3},
+ {9, 3},
+ {10, 3},
+ {11, 3},
+ {12, 3},
+ };
+
+ graph::class_def_size_estimator_t estimator1(consecutive_map.iter());
+ assert(check_add_class_def_size(estimator1, consecutive_map, 1, {1}));
+ assert(check_add_class_def_size(estimator1, consecutive_map, 2, {1, 2}));
+ assert(check_add_class_def_size(estimator1, consecutive_map, 2, {1, 2})); // check that adding the same class again works
+ assert(check_add_class_def_size(estimator1, consecutive_map, 3, {1, 2, 3}));
+
+ estimator1.reset();
+ assert(check_add_class_def_size(estimator1, consecutive_map, 2, {2}));
+ assert(check_add_class_def_size(estimator1, consecutive_map, 3, {2, 3}));
+
+ // #### With non-consecutive gids: always uses format 2 ###
+ gid_and_class_list_t non_consecutive_map = {
+ // range 1-4 (f1: 8 bytes), (f2: 6 bytes)
+ {1, 1},
+ {2, 1},
+ {3, 1},
+ {4, 1},
+
+ // (f1: 2 bytes), (f2: 12 bytes)
+ {6, 2},
+ {8, 2},
+
+ // (f1: 14 bytes), (f2: 6 bytes)
+ {9, 3},
+ {10, 3},
+ {11, 3},
+ {12, 3},
+ {13, 3},
+ {14, 3},
+ {15, 3},
+ };
+
+ graph::class_def_size_estimator_t estimator2(non_consecutive_map.iter());
+ assert(check_add_class_def_size(estimator2, non_consecutive_map, 1, {1}));
+ assert(check_add_class_def_size(estimator2, non_consecutive_map, 2, {1, 2}));
+ assert(check_add_class_def_size(estimator2, non_consecutive_map, 3, {1, 2, 3}));
+
+ estimator2.reset();
+ assert(check_add_class_def_size(estimator2, non_consecutive_map, 2, {2}));
+ assert(check_add_class_def_size(estimator2, non_consecutive_map, 3, {2, 3}));
+}
+
+static void test_running_class_size_estimates_with_locally_consecutive_glyphs () {
+ gid_and_class_list_t map = {
+ {1, 1},
+ {6, 2},
+ {7, 3},
+ };
+
+ graph::class_def_size_estimator_t estimator(map.iter());
+ assert(check_add_class_def_size(estimator, map, 1, {1}));
+ assert(check_add_class_def_size(estimator, map, 2, {1, 2}));
+ assert(check_add_class_def_size(estimator, map, 3, {1, 2, 3}));
+
+ estimator.reset();
+ assert(check_add_class_def_size(estimator, map, 2, {2}));
+ assert(check_add_class_def_size(estimator, map, 3, {2, 3}));
}
int
main (int argc, char **argv)
{
test_class_and_coverage_size_estimates ();
+ test_running_class_and_coverage_size_estimates ();
+ test_running_class_size_estimates_with_locally_consecutive_glyphs ();
}