diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a1a36dfb..f64f96d1c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -842,18 +842,6 @@ if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL) endif () endif () -if (UNIX AND CMAKE_GENERATOR STREQUAL "Ninja") - if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics") - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fcolor-diagnostics") - endif () - if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color") - set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdiagnostics-color") - endif () -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) diff --git a/src/hb-common.cc b/src/hb-common.cc index fb8c7b72f..ab93bf427 100644 --- a/src/hb-common.cc +++ b/src/hb-common.cc @@ -731,7 +731,7 @@ parse_uint (const char **pp, const char *end, unsigned int *pv) /* Intentionally use strtol instead of strtoul, such that * -1 turns into "big number"... */ errno = 0; - v = strtol (p, &pend, 0); + v = strtol (p, &pend, 10); if (errno || p == pend) return false; @@ -755,7 +755,7 @@ parse_uint32 (const char **pp, const char *end, uint32_t *pv) /* Intentionally use strtol instead of strtoul, such that * -1 turns into "big number"... */ errno = 0; - v = strtol (p, &pend, 0); + v = strtol (p, &pend, 10); if (errno || p == pend) return false; @@ -857,9 +857,14 @@ parse_bool (const char **pp, const char *end, uint32_t *pv) (*pp)++; /* CSS allows on/off as aliases 1/0. */ - if (*pp - p == 2 && 0 == strncmp (p, "on", 2)) + if (*pp - p == 2 + && TOLOWER (p[0]) == 'o' + && TOLOWER (p[1]) == 'n') *pv = 1; - else if (*pp - p == 3 && 0 == strncmp (p, "off", 3)) + else if (*pp - p == 3 + && TOLOWER (p[0]) == 'o' + && TOLOWER (p[1]) == 'f' + && TOLOWER (p[2]) == 'f') *pv = 0; else return false; @@ -975,8 +980,9 @@ parse_one_feature (const char **pp, const char *end, hb_feature_t *feature) * Parses a string into a #hb_feature_t. * * The format for specifying feature strings follows. All valid CSS - * font-feature-settings values other than 'normal' and 'inherited' are also - * accepted, though, not documented below. + * font-feature-settings values other than 'normal' and the global values are + * also accepted, though not documented below. CSS string escapes are not + * supported. * * The range indices refer to the positions between Unicode characters. The * position before the first character is always 0. diff --git a/src/hb-directwrite.cc b/src/hb-directwrite.cc index aaf10a1d6..137cd56c8 100644 --- a/src/hb-directwrite.cc +++ b/src/hb-directwrite.cc @@ -1,5 +1,5 @@ /* - * Copyright © 2015-2018 Ebrahim Byagowi + * Copyright © 2015-2019 Ebrahim Byagowi * * This is part of HarfBuzz, a text shaping library. * @@ -658,10 +658,10 @@ retry_getglyphs: * alignment needed after the WORD array. sizeof (WORD) == 2. */ unsigned int glyphs_size = (scratch_size * sizeof (int) - 2) / (sizeof (WORD) + - sizeof (DWRITE_SHAPING_GLYPH_PROPERTIES) + - sizeof (int) + - sizeof (DWRITE_GLYPH_OFFSET) + - sizeof (uint32_t)); + sizeof (DWRITE_SHAPING_GLYPH_PROPERTIES) + + sizeof (int) + + sizeof (DWRITE_GLYPH_OFFSET) + + sizeof (uint32_t)); ALLOCATE_ARRAY (uint32_t, vis_clusters, glyphs_size); #undef ALLOCATE_ARRAY @@ -868,3 +868,63 @@ hb_directwrite_shape_experimental_width (hb_font_t *font, return res; } + +struct _hb_directwrite_font_table_context { + IDWriteFontFace *face; + void *table_context; +}; + +static void +_hb_directwrite_table_data_release (void *data) +{ + _hb_directwrite_font_table_context *context = (_hb_directwrite_font_table_context *) data; + context->face->ReleaseFontTable (context->table_context); + delete context; +} + +static hb_blob_t * +reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data) +{ + IDWriteFontFace *dw_face = ((IDWriteFontFace *) user_data); + const void *data; + uint32_t length; + void *table_context; + BOOL exists; + if (!dw_face || FAILED (dw_face->TryGetFontTable (hb_uint32_swap (tag), &data, + &length, &table_context, &exists))) + return nullptr; + + if (!data || !exists || !length) + { + dw_face->ReleaseFontTable (table_context); + return nullptr; + } + + _hb_directwrite_font_table_context *context = new _hb_directwrite_font_table_context; + context->face = dw_face; + context->table_context = table_context; + + return hb_blob_create ((const char *) data, length, HB_MEMORY_MODE_READONLY, + context, _hb_directwrite_table_data_release); +} + +static void +_hb_directwrite_font_release (void *data) +{ + if (data) + ((IDWriteFontFace *) data)->Release (); +} + +/** + * hb_directwrite_face_create: + * @font_face: + * Since: REPLACEME + **/ +hb_face_t * +hb_directwrite_face_create (IDWriteFontFace *font_face) +{ + if (font_face) + font_face->AddRef (); + return hb_face_create_for_tables (reference_table, font_face, + _hb_directwrite_font_release); +} diff --git a/src/hb-directwrite.h b/src/hb-directwrite.h index 9bfd1f727..09776fd09 100644 --- a/src/hb-directwrite.h +++ b/src/hb-directwrite.h @@ -1,5 +1,5 @@ /* - * Copyright © 2015 Ebrahim Byagowi + * Copyright © 2015-2019 Ebrahim Byagowi * * This is part of HarfBuzz, a text shaping library. * @@ -34,6 +34,9 @@ hb_directwrite_shape_experimental_width (hb_font_t *font, hb_buffer_t *buffer, const hb_feature_t *features, unsigned int num_features, float width); +HB_EXTERN hb_face_t * +hb_directwrite_face_create (IDWriteFontFace *font_face); + HB_END_DECLS #endif /* HB_DIRECTWRITE_H */ diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index 5702d0173..49ab9e133 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -96,6 +96,7 @@ _remove_invalid_gids (hb_set_t *glyphs, static hb_set_t * _populate_gids_to_retain (hb_face_t *face, const hb_set_t *unicodes, + const hb_set_t *input_glyphs_to_retain, bool close_over_gsub, hb_set_t *unicodes_to_retain, hb_map_t *codepoint_to_glyph, @@ -110,6 +111,7 @@ _populate_gids_to_retain (hb_face_t *face, hb_set_t *initial_gids_to_retain = hb_set_create (); initial_gids_to_retain->add (0); // Not-def + hb_set_union (initial_gids_to_retain, input_glyphs_to_retain); hb_codepoint_t cp = HB_SET_VALUE_INVALID; while (unicodes->next (&cp)) @@ -213,6 +215,7 @@ hb_subset_plan_create (hb_face_t *face, plan->reverse_glyph_map = hb_map_create(); plan->_glyphset = _populate_gids_to_retain (face, input->unicodes, + input->glyphs, !plan->drop_layout, plan->unicodes, plan->codepoint_to_glyph, diff --git a/test/api/hb-subset-test.h b/test/api/hb-subset-test.h index cefa4e066..3e759a8a9 100644 --- a/test/api/hb-subset-test.h +++ b/test/api/hb-subset-test.h @@ -48,7 +48,7 @@ typedef short bool; HB_BEGIN_DECLS static inline hb_subset_input_t * -hb_subset_test_create_input(const hb_set_t *codepoints) +hb_subset_test_create_input (const hb_set_t *codepoints) { hb_subset_input_t *input = hb_subset_input_create_or_fail (); hb_set_t * input_codepoints = hb_subset_input_unicode_set (input); @@ -56,6 +56,15 @@ hb_subset_test_create_input(const hb_set_t *codepoints) return input; } +static inline hb_subset_input_t * +hb_subset_test_create_input_from_glyphs (const hb_set_t *glyphs) +{ + hb_subset_input_t *input = hb_subset_input_create_or_fail (); + hb_set_t * input_glyphs = hb_subset_input_glyph_set (input); + hb_set_union (input_glyphs, glyphs); + 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-glyf.c b/test/api/test-subset-glyf.c index e8609ca83..4671156f9 100644 --- a/test/api/test-subset-glyf.c +++ b/test/api/test-subset-glyf.c @@ -79,6 +79,29 @@ test_subset_glyf (void) hb_face_destroy (face_ac); } +static void +test_subset_glyf_with_input_glyphs (void) +{ + hb_face_t *face_abc = hb_test_open_font_file ("fonts/Roboto-Regular.abc.ttf"); + hb_face_t *face_ac = hb_test_open_font_file ("fonts/Roboto-Regular.ac.ttf"); + + hb_set_t *glyphs = hb_set_create(); + hb_face_t *face_abc_subset; + hb_set_add (glyphs, 1); + hb_set_add (glyphs, 3); + face_abc_subset = + hb_subset_test_create_subset (face_abc, hb_subset_test_create_input_from_glyphs (glyphs)); + hb_set_destroy (glyphs); + + hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('g','l','y','f')); + hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('l','o','c', 'a')); + check_maxp_num_glyphs(face_abc_subset, 3, true); + + hb_face_destroy (face_abc_subset); + hb_face_destroy (face_abc); + hb_face_destroy (face_ac); +} + static void test_subset_glyf_with_components (void) { @@ -291,6 +314,7 @@ main (int argc, char **argv) hb_test_add (test_subset_glyf_noop); hb_test_add (test_subset_glyf); + hb_test_add (test_subset_glyf_with_input_glyphs); hb_test_add (test_subset_glyf_strip_hints_simple); hb_test_add (test_subset_glyf_strip_hints_composite); hb_test_add (test_subset_glyf_strip_hints_invalid); diff --git a/util/options.cc b/util/options.cc index b315c6a75..c5a4f0f0b 100644 --- a/util/options.cc +++ b/util/options.cc @@ -432,7 +432,8 @@ shape_options_t::add_options (option_parser_t *parser) " Features can be enabled or disabled, either globally or limited to\n" " specific character ranges. The format for specifying feature settings\n" " follows. All valid CSS font-feature-settings values other than 'normal'\n" - " and 'inherited' are also accepted, though, not documented below.\n" + " and the global values are also accepted, though not documented below.\n" + " CSS string escapes are not supported." "\n" " The range indices refer to the positions between Unicode characters,\n" " unless the --utf8-clusters is provided, in which case range indices\n"