| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182 |
- #include <cassert>
- #include <cstdio>
- #include <cstdlib>
- #include <cstring>
- #include <thread>
- #include <condition_variable>
- #include <vector>
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include "hb-subset.h"
- enum operation_t
- {
- subset_codepoints,
- subset_glyphs
- };
- #define SUBSET_FONT_BASE_PATH "test/subset/data/fonts/"
- struct test_input_t
- {
- const char *font_path;
- const unsigned max_subset_size;
- } default_tests[] =
- {
- {SUBSET_FONT_BASE_PATH "Roboto-Regular.ttf", 4000},
- {SUBSET_FONT_BASE_PATH "Amiri-Regular.ttf", 4000},
- {SUBSET_FONT_BASE_PATH "NotoNastaliqUrdu-Regular.ttf", 1000},
- {SUBSET_FONT_BASE_PATH "NotoSansDevanagari-Regular.ttf", 1000},
- {SUBSET_FONT_BASE_PATH "Mplus1p-Regular.ttf", 10000},
- {SUBSET_FONT_BASE_PATH "SourceHanSans-Regular_subset.otf", 10000},
- {SUBSET_FONT_BASE_PATH "SourceSansPro-Regular.otf", 2000},
- };
- static test_input_t *tests = default_tests;
- static unsigned num_tests = sizeof (default_tests) / sizeof (default_tests[0]);
- // https://en.cppreference.com/w/cpp/thread/condition_variable/wait
- static std::condition_variable cv;
- static std::mutex cv_m;
- static bool ready = false;
- static unsigned num_repetitions = 1;
- static unsigned num_threads = 3;
- static void AddCodepoints(const hb_set_t* codepoints_in_font,
- unsigned subset_size,
- hb_subset_input_t* input)
- {
- auto *unicodes = hb_subset_input_unicode_set (input);
- hb_codepoint_t cp = HB_SET_VALUE_INVALID;
- for (unsigned i = 0; i < subset_size; i++) {
- if (!hb_set_next (codepoints_in_font, &cp)) return;
- hb_set_add (unicodes, cp);
- }
- }
- static void AddGlyphs(unsigned num_glyphs_in_font,
- unsigned subset_size,
- hb_subset_input_t* input)
- {
- auto *glyphs = hb_subset_input_glyph_set (input);
- for (unsigned i = 0; i < subset_size && i < num_glyphs_in_font; i++) {
- hb_set_add (glyphs, i);
- }
- }
- static void subset (operation_t operation,
- const test_input_t &test_input,
- hb_face_t *face)
- {
- // Wait till all threads are ready.
- {
- std::unique_lock<std::mutex> lk (cv_m);
- cv.wait(lk, [] {return ready;});
- }
- unsigned subset_size = test_input.max_subset_size;
- hb_subset_input_t* input = hb_subset_input_create_or_fail ();
- assert (input);
- switch (operation)
- {
- case subset_codepoints:
- {
- hb_set_t* all_codepoints = hb_set_create ();
- hb_face_collect_unicodes (face, all_codepoints);
- AddCodepoints(all_codepoints, subset_size, input);
- hb_set_destroy (all_codepoints);
- }
- break;
- case subset_glyphs:
- {
- unsigned num_glyphs = hb_face_get_glyph_count (face);
- AddGlyphs(num_glyphs, subset_size, input);
- }
- break;
- }
- for (unsigned i = 0; i < num_repetitions; i++)
- {
- hb_face_t* subset = hb_subset_or_fail (face, input);
- assert (subset);
- hb_face_destroy (subset);
- }
- hb_subset_input_destroy (input);
- }
- static void test_operation (operation_t operation,
- const char *operation_name,
- const test_input_t &test_input)
- {
- char name[1024] = "subset";
- const char *p;
- strcat (name, "/");
- p = strrchr (test_input.font_path, '/');
- strcat (name, p ? p + 1 : test_input.font_path);
- strcat (name, "/");
- strcat (name, operation_name);
- printf ("Testing %s\n", name);
- hb_face_t *face;
- {
- hb_blob_t *blob = hb_blob_create_from_file_or_fail (test_input.font_path);
- assert (blob);
- face = hb_face_create (blob, 0);
- hb_blob_destroy (blob);
- }
- std::vector<std::thread> threads;
- for (unsigned i = 0; i < num_threads; i++)
- threads.push_back (std::thread (subset, operation, test_input, face));
- {
- std::unique_lock<std::mutex> lk (cv_m);
- ready = true;
- }
- cv.notify_all();
- for (unsigned i = 0; i < num_threads; i++)
- threads[i].join ();
- hb_face_destroy (face);
- }
- int main(int argc, char** argv)
- {
- if (argc > 1)
- num_threads = atoi (argv[1]);
- if (argc > 2)
- num_repetitions = atoi (argv[2]);
- if (argc > 4)
- {
- num_tests = argc - 3;
- tests = (test_input_t *) calloc (num_tests, sizeof (test_input_t));
- for (unsigned i = 0; i < num_tests; i++)
- {
- tests[i].font_path = argv[3 + i];
- }
- }
- printf ("Num threads %u; num repetitions %u\n", num_threads, num_repetitions);
- for (unsigned i = 0; i < num_tests; i++)
- {
- auto& test_input = tests[i];
- test_operation (subset_codepoints, "codepoints", test_input);
- test_operation (subset_glyphs, "glyphs", test_input);
- }
- if (tests != default_tests)
- free (tests);
- }
|