diff --git a/.travis.yml b/.travis.yml index e2de5038d03137d901b2ec79246465105af3a1c0..fa9e5bc60ad7aeb0eda1567118c45d56ae21e87c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,7 @@ env: - NOCONFIGURE=1 # COVERITY_SCAN_TOKEN - secure: "MRJtVu/fQoWNwMAamvIJBCX/1SMvEuEUk/ljAif/y2/3syyWgxFGp17UGnDILdoZYyCqTM+jQciY2P0nVqbjjOAUlML4QOAalqw8kPp8iTsnHUe+KOMVrOVP6p6qAQxk1im1O41cCMkmVKvk+NXe/on5euz6LGF2laHZaOAMoes=" + - PROJECT_NAME="behdad/harfbuzz" # the project name on coverity matrix: include: diff --git a/configure.ac b/configure.ac index f77e0874295e418aed9cb17e7b67ce04594e339d..d8c38fe29f71609dcf8a63f4c8908ccb3277b926 100644 --- a/configure.ac +++ b/configure.ac @@ -57,11 +57,12 @@ m4_define([hb_libtool_current], HB_LIBTOOL_VERSION_INFO=hb_libtool_current:hb_libtool_revision:hb_libtool_age AC_SUBST(HB_LIBTOOL_VERSION_INFO) -AC_ARG_WITH([stdcpp], - [AS_HELP_STRING([--with-stdcpp], - [Do not try suppressing linkage to libstdcpp])],, - [with_stdcpp=no]) -AM_CONDITIONAL(WITHSTDCPP, [test "x$with_stdcpp" = "xyes"]) +AC_ARG_WITH([libstdc++], + [AS_HELP_STRING([--with-libstdc++=@<:@yes/no@:>@], + [Allow linking with libstdc++ @<:@default=no@:>@])], + [with_libstdcxx=$withval], + [with_libstdcxx=no]) +AM_CONDITIONAL(WITH_LIBSTDCXX, [test "x$with_libstdcxx" = "xyes"]) # Documentation have_gtk_doc=false diff --git a/docs/harfbuzz-sections.txt b/docs/harfbuzz-sections.txt index a9b4d53eb5b028d286a38400de9731846a34edbe..91faa0b7590d52b0fc2a2c0d8ce1b56645555bd7 100644 --- a/docs/harfbuzz-sections.txt +++ b/docs/harfbuzz-sections.txt @@ -9,6 +9,7 @@ HB_EXTERN hb-blob hb_blob_create hb_blob_create_sub_blob +hb_blob_copy_writable_or_fail hb_blob_destroy hb_blob_get_data hb_blob_get_data_writable @@ -527,7 +528,9 @@ hb_set_intersect hb_set_is_empty hb_set_is_equal hb_set_next +hb_set_previous hb_set_next_range +hb_set_previous_range hb_set_reference hb_set_set hb_set_set_user_data diff --git a/src/Makefile.am b/src/Makefile.am index 25728563639595967558ffa31c57b8fb2b92cb93..3b18ebd3e969aaadf26140f16d35bf612687563b 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,6 +9,8 @@ CLEANFILES = DISTCLEANFILES = MAINTAINERCLEANFILES = DISTCHECK_CONFIGURE_FLAGS = --enable-introspection +TESTS = +check_PROGRAMS = # The following warning options are useful for debugging: -Wpadded #AM_CXXFLAGS = @@ -30,12 +32,13 @@ HBSOURCES += $(HB_BASE_RAGEL_GENERATED_sources) HBHEADERS = $(HB_BASE_headers) HBNODISTHEADERS = $(HB_NODIST_headers) -if !WITHSTDCPP +if WITH_LIBSTDCXX +HBNOLIBCXXCFLAGS = +else # Make sure we don't link to libstdc++ -HBCFLAGS += -fno-rtti -fno-exceptions - -# No threadsafe statics and C++ as we do it ourselves -HBCFLAGS += -fno-threadsafe-statics +# No threadsafe statics in C++ as we do it ourselves +HBNOLIBCXXFLAGS = -fno-threadsafe-statics -fno-rtti -fno-exceptions +HBLIBCXXFLAGS = -fno-threadsafe-statics endif if HAVE_OT @@ -126,27 +129,24 @@ export_symbols_icu = -export-symbols harfbuzz-icu.def harfbuzz_icu_def_dependency = harfbuzz-icu.def export_symbols_subset = -export-symbols harfbuzz-subset.def harfbuzz_subset_def_dependency = harfbuzz-subset.def -choosed_linker = $(CXXLINK) +chosen_linker = $(CXXLINK) else -if WITHSTDCPP -choosed_linker = $(CXXLINK) +if WITH_LIBSTDCXX +chosen_linker = $(CXXLINK) else if HAVE_GCC # Use a C linker for GCC, not C++; Don't link to libstdc++ -choosed_linker = $(LINK) +chosen_linker = $(LINK) else -choosed_linker = $(CXXLINK) +chosen_linker = $(CXXLINK) endif endif endif -libharfbuzz_la_LINK = $(choosed_linker) $(libharfbuzz_la_LDFLAGS) -libharfbuzz_icu_la_LINK = $(choosed_linker) $(libharfbuzz_icu_la_LDFLAGS) -libharfbuzz_subset_la_LINK = $(choosed_linker) $(libharfbuzz_subset_la_LDFLAGS) - base_link_flags = $(AM_LDFLAGS) -lm -version-info $(HB_LIBTOOL_VERSION_INFO) -no-undefined +libharfbuzz_la_LINK = $(chosen_linker) $(libharfbuzz_la_LDFLAGS) libharfbuzz_la_SOURCES = $(HBSOURCES) $(HBHEADERS) $(HBNODISTHEADERS) -libharfbuzz_la_CPPFLAGS = $(HBCFLAGS) +libharfbuzz_la_CPPFLAGS = $(HBCFLAGS) $(HBNOLIBCXXFLAGS) libharfbuzz_la_LDFLAGS = $(base_link_flags) $(export_symbols) libharfbuzz_la_LIBADD = $(HBLIBS) EXTRA_libharfbuzz_la_DEPENDENCIES = $(harfbuzz_def_dependency) @@ -158,7 +158,7 @@ EXTRA_DIST += harfbuzz.pc.in lib_LTLIBRARIES += libharfbuzz-subset.la libharfbuzz_subset_la_SOURCES = $(HB_SUBSET_sources) -libharfbuzz_subset_la_CPPFLAGS = $(libharfbuzz_la_CPPFLAGS) +libharfbuzz_subset_la_CPPFLAGS = $(HBCFLAGS) $(HBNOLIBCXXFLAGS) libharfbuzz_subset_la_LDFLAGS = $(base_link_flags) $(export_symbols_subset) libharfbuzz_subset_la_LIBADD = libharfbuzz.la EXTRA_libharfbuzz_subset_la_DEPENDENCIES = $(harfbuzz_subset_def_dependency) @@ -178,9 +178,9 @@ FUZZING_CPPFLAGS = \ -DHB_BUFFER_MAX_OPS_DEFAULT=1024 \ $(NULL) EXTRA_LTLIBRARIES = libharfbuzz-fuzzing.la -libharfbuzz_fuzzing_la_LINK = $(libharfbuzz_la_LINK) +libharfbuzz_fuzzing_la_LINK = $(chosen_linker) $(libharfbuzz_fuzzing_la_LDFLAGS) libharfbuzz_fuzzing_la_SOURCES = $(libharfbuzz_la_SOURCES) -libharfbuzz_fuzzing_la_CPPFLAGS = $(libharfbuzz_la_CPPFLAGS) $(FUZZING_CPPFLAGS) +libharfbuzz_fuzzing_la_CPPFLAGS = $(HBCFLAGS) $(HBLIBCXXFLAGS) $(FUZZING_CPPFLAGS) libharfbuzz_fuzzing_la_LDFLAGS = $(AM_LDFLAGS) libharfbuzz_fuzzing_la_LIBADD = $(libharfbuzz_la_LIBADD) EXTRA_libharfbuzz_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_la_DEPENDENCIES) @@ -195,7 +195,7 @@ HBHEADERS += $(HB_ICU_headers) else lib_LTLIBRARIES += libharfbuzz-icu.la libharfbuzz_icu_la_SOURCES = $(HB_ICU_sources) -libharfbuzz_icu_la_CPPFLAGS = $(libharfbuzz_la_CPPFLAGS) $(ICU_CFLAGS) +libharfbuzz_icu_la_CPPFLAGS = $(HBCFLAGS) $(HBLIBCXXFLAGS) $(ICU_CFLAGS) libharfbuzz_icu_la_LDFLAGS = $(base_link_flags) $(export_symbols_icu) libharfbuzz_icu_la_LIBADD = $(ICU_LIBS) libharfbuzz.la EXTRA_libharfbuzz_icu_la_DEPENDENCIES = $(harfbuzz_icu_def_dependency) @@ -207,11 +207,11 @@ EXTRA_DIST += harfbuzz-icu.pc.in if HAVE_GOBJECT lib_LTLIBRARIES += libharfbuzz-gobject.la -libharfbuzz_gobject_la_LINK = $(libharfbuzz_la_LINK) +libharfbuzz_gobject_la_LINK = $(chosen_linker) $(libharfbuzz_gobject_la_LDFLAGS) libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_sources) nodist_libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_ENUM_sources) -libharfbuzz_gobject_la_CPPFLAGS = $(libharfbuzz_la_CPPFLAGS) $(GOBJECT_CFLAGS) -libharfbuzz_gobject_la_LDFLAGS = $(libharfbuzz_la_LDFLAGS) +libharfbuzz_gobject_la_CPPFLAGS = $(HBCFLAGS) $(HBNOLIBCXXFLAGS) $(GOBJECT_CFLAGS) +libharfbuzz_gobject_la_LDFLAGS = $(base_link_flags) libharfbuzz_gobject_la_LIBADD = $(GOBJECT_LIBS) libharfbuzz.la pkginclude_HEADERS += $(HB_GOBJECT_headers) nodist_pkginclude_HEADERS += $(HB_GOBJECT_ENUM_headers) @@ -340,19 +340,42 @@ dist_check_SCRIPTS = \ check-externs.sh \ check-header-guards.sh \ check-includes.sh \ - check-libstdc++.sh \ check-static-inits.sh \ check-symbols.sh \ $(NULL) +TESTS += $(dist_check_SCRIPTS) + +if !WITH_LIBSTDCXX +dist_check_SCRIPTS += \ + check-libstdc++.sh \ + $(NULL) +endif -check_PROGRAMS = \ - test-ot-tag \ +check_PROGRAMS += \ + dump-indic-data \ + dump-khmer-data \ + dump-myanmar-data \ + dump-use-data \ $(NULL) +dump_indic_data_SOURCES = dump-indic-data.cc hb-ot-shape-complex-indic-table.cc +dump_indic_data_CPPFLAGS = $(HBCFLAGS) +dump_indic_data_LDADD = libharfbuzz.la $(HBLIBS) +dump_khmer_data_SOURCES = dump-khmer-data.cc hb-ot-shape-complex-indic-table.cc +dump_khmer_data_CPPFLAGS = $(HBCFLAGS) +dump_khmer_data_LDADD = libharfbuzz.la $(HBLIBS) +dump_myanmar_data_SOURCES = dump-myanmar-data.cc hb-ot-shape-complex-indic-table.cc +dump_myanmar_data_CPPFLAGS = $(HBCFLAGS) +dump_myanmar_data_LDADD = libharfbuzz.la $(HBLIBS) +dump_use_data_SOURCES = dump-use-data.cc hb-ot-shape-complex-use-table.cc +dump_use_data_CPPFLAGS = $(HBCFLAGS) +dump_use_data_LDADD = libharfbuzz.la $(HBLIBS) + +check_PROGRAMS += test-ot-tag +TESTS += test-ot-tag test_ot_tag_SOURCES = hb-ot-tag.cc test_ot_tag_CPPFLAGS = $(HBCFLAGS) -DMAIN test_ot_tag_LDADD = libharfbuzz.la $(HBLIBS) -TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS) TESTS_ENVIRONMENT = \ srcdir="$(srcdir)" \ MAKE="$(MAKE) $(AM_MAKEFLAGS)" \ diff --git a/src/Makefile.sources b/src/Makefile.sources index f2821e3de2819d6aefd0e3dfaa53b2d16102cc16..ec60ec0a6ea5729dcd2d1253dd49751e3e731558 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -109,7 +109,9 @@ HB_OT_sources = \ hb-ot-shape-complex-indic.cc \ hb-ot-shape-complex-indic-private.hh \ hb-ot-shape-complex-indic-table.cc \ + hb-ot-shape-complex-khmer-private.hh \ hb-ot-shape-complex-khmer.cc \ + hb-ot-shape-complex-myanmar-private.hh \ hb-ot-shape-complex-myanmar.cc \ hb-ot-shape-complex-thai.cc \ hb-ot-shape-complex-tibetan.cc \ @@ -185,6 +187,7 @@ HB_ICU_headers = hb-icu.h HB_SUBSET_sources = \ hb-subset.cc \ hb-subset-glyf.cc \ + hb-subset-input.cc \ hb-subset-plan.cc \ $(NULL) diff --git a/src/check-libstdc++.sh b/src/check-libstdc++.sh index a7b4c495ffb4443c13b08e38cb3e562b003fcbd9..ce0bdab755f9ac5bbf1d1e68abac3fa1bbb13457 100755 --- a/src/check-libstdc++.sh +++ b/src/check-libstdc++.sh @@ -22,7 +22,8 @@ fi tested=false # harfbuzz-icu links to libstdc++ because icu does. -for soname in harfbuzz harfbuzz-subset harfbuzz-gobject; do +# harfbuzz-subset uses libstdc++. +for soname in harfbuzz harfbuzz-gobject; do for suffix in so dylib; do so=$libs/lib$soname.$suffix if ! test -f "$so"; then continue; fi diff --git a/src/dump-indic-data.cc b/src/dump-indic-data.cc new file mode 100644 index 0000000000000000000000000000000000000000..d57413884be3b4603d7bc6a288e27c75355b54cd --- /dev/null +++ b/src/dump-indic-data.cc @@ -0,0 +1,43 @@ +/* + * 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-shape-complex-indic-private.hh" + +int +main (void) +{ + for (hb_codepoint_t u = 0; u <= 0x10FFFF; u++) + { + hb_glyph_info_t info; + info.codepoint = u; + set_indic_properties (info); + if (info.indic_category() != INDIC_SYLLABIC_CATEGORY_OTHER || + info.indic_position() != INDIC_MATRA_CATEGORY_NOT_APPLICABLE) + printf("U+%04X %u %u\n", u, + info.indic_category(), + info.indic_position()); + } +} diff --git a/src/dump-khmer-data.cc b/src/dump-khmer-data.cc new file mode 100644 index 0000000000000000000000000000000000000000..7dd09b2b5ca57a6b710796d942d433492e3418a9 --- /dev/null +++ b/src/dump-khmer-data.cc @@ -0,0 +1,43 @@ +/* + * 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-shape-complex-khmer-private.hh" + +int +main (void) +{ + for (hb_codepoint_t u = 0; u <= 0x10FFFF; u++) + { + hb_glyph_info_t info; + info.codepoint = u; + set_khmer_properties (info); + if (info.khmer_category() != INDIC_SYLLABIC_CATEGORY_OTHER || + info.khmer_position() != INDIC_MATRA_CATEGORY_NOT_APPLICABLE) + printf("U+%04X %u %u\n", u, + info.khmer_category(), + info.khmer_position()); + } +} diff --git a/src/dump-myanmar-data.cc b/src/dump-myanmar-data.cc new file mode 100644 index 0000000000000000000000000000000000000000..2df9cd987f341a7471b5b40cb1ac57f76efffebc --- /dev/null +++ b/src/dump-myanmar-data.cc @@ -0,0 +1,43 @@ +/* + * 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-shape-complex-myanmar-private.hh" + +int +main (void) +{ + for (hb_codepoint_t u = 0; u <= 0x10FFFF; u++) + { + hb_glyph_info_t info; + info.codepoint = u; + set_myanmar_properties (info); + if (info.myanmar_category() != INDIC_SYLLABIC_CATEGORY_OTHER || + info.myanmar_position() != INDIC_MATRA_CATEGORY_NOT_APPLICABLE) + printf("U+%04X %u %u\n", u, + info.myanmar_category(), + info.myanmar_position()); + } +} diff --git a/src/dump-use-data.cc b/src/dump-use-data.cc new file mode 100644 index 0000000000000000000000000000000000000000..0e64688f1e06f202fed4cec79a9d942d6cf50544 --- /dev/null +++ b/src/dump-use-data.cc @@ -0,0 +1,38 @@ +/* + * 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-shape-complex-use-private.hh" + +int +main (void) +{ + for (hb_codepoint_t u = 0; u <= 0x10FFFF; u++) + { + unsigned int category = hb_use_get_category (u); + if (category != USE_O) + printf("U+%04X %u\n", u, category); + } +} diff --git a/src/gen-use-table.py b/src/gen-use-table.py index 5391f27eb3e18e74b2f4a4801bd8fe1d72ad906a..06817255c92c5dfd134e5390ef3f63eb234c83b4 100755 --- a/src/gen-use-table.py +++ b/src/gen-use-table.py @@ -449,7 +449,7 @@ page_bits = 12 print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy) print print "USE_TABLE_ELEMENT_TYPE" -print "hb_use_get_categories (hb_codepoint_t u)" +print "hb_use_get_category (hb_codepoint_t u)" print "{" print " switch (u >> %d)" % page_bits print " {" diff --git a/src/hb-aat-layout-morx-table.hh b/src/hb-aat-layout-morx-table.hh index 2bb80891335f87e090a45c4be7e05f0e5217a022..4cc2824214e4325accf259bfa72ce65b71df2506 100644 --- a/src/hb-aat-layout-morx-table.hh +++ b/src/hb-aat-layout-morx-table.hh @@ -40,6 +40,8 @@ using namespace OT; struct RearrangementSubtable { + typedef void EntryData; + struct driver_context_t { static const bool in_place = true; @@ -60,13 +62,13 @@ struct RearrangementSubtable ret (false), start (0), end (0) {} - inline bool is_actionable (StateTableDriver *driver, - const Entry *entry) + inline bool is_actionable (StateTableDriver *driver, + const Entry *entry) { return (entry->flags & Verb) && start < end; } - inline bool transition (StateTableDriver *driver, - const Entry *entry) + inline bool transition (StateTableDriver *driver, + const Entry *entry) { hb_buffer_t *buffer = driver->buffer; unsigned int flags = entry->flags; @@ -169,7 +171,7 @@ struct RearrangementSubtable } protected: - StateTable machine; + StateTable machine; public: DEFINE_SIZE_STATIC (16); }; diff --git a/src/hb-blob.cc b/src/hb-blob.cc index 80460125826a8764b1e8ccd7423d0647a4c74043..b5291f650cc81fb74fb01725250170169de638c3 100644 --- a/src/hb-blob.cc +++ b/src/hb-blob.cc @@ -170,6 +170,31 @@ hb_blob_create_sub_blob (hb_blob_t *parent, return blob; } +/** + * hb_blob_copy_writable_or_fail: + * @blob: A blob. + * + * Makes a writable copy of @blob. + * + * Return value: New blob, or nullptr if allocation failed. + * + * Since: 1.8.0 + **/ +hb_blob_t * +hb_blob_copy_writable_or_fail (hb_blob_t *blob) +{ + blob = hb_blob_create (blob->data, + blob->length, + HB_MEMORY_MODE_DUPLICATE, + nullptr, + nullptr); + + if (unlikely (blob == hb_blob_get_empty ())) + blob = nullptr; + + return blob; +} + /** * hb_blob_get_empty: * diff --git a/src/hb-blob.h b/src/hb-blob.h index 53682d3eb1c94333b0e514d204db86ef0d695ac8..fd561f73869740eb6e02e1056a134630c551d788 100644 --- a/src/hb-blob.h +++ b/src/hb-blob.h @@ -82,6 +82,9 @@ hb_blob_create_sub_blob (hb_blob_t *parent, unsigned int offset, unsigned int length); +HB_EXTERN hb_blob_t * +hb_blob_copy_writable_or_fail (hb_blob_t *blob); + HB_EXTERN hb_blob_t * hb_blob_get_empty (void); diff --git a/src/hb-face.h b/src/hb-face.h index 9842d52b650034b7010d3a77b0274e40257dce39..0ce8d0462d5cb3fc39bc271ea3e0ea7cd140545a 100644 --- a/src/hb-face.h +++ b/src/hb-face.h @@ -71,7 +71,6 @@ hb_face_set_user_data (hb_face_t *face, hb_destroy_func_t destroy, hb_bool_t replace); - HB_EXTERN void * hb_face_get_user_data (hb_face_t *face, hb_user_data_key_t *key); diff --git a/src/hb-ot-cbdt-table.hh b/src/hb-ot-cbdt-table.hh index 6c2b9a88ee1388bf46656dd899bc4896167ac148..e4519529b1e4e228981d6fd7227a38fe24a472f7 100644 --- a/src/hb-ot-cbdt-table.hh +++ b/src/hb-ot-cbdt-table.hh @@ -377,7 +377,7 @@ struct CBDT { inline void init (hb_face_t *face) { - upem = face->get_upem(); + upem = hb_face_get_upem (face); cblc_blob = Sanitizer().sanitize (face->reference_table (HB_OT_TAG_CBLC)); cbdt_blob = Sanitizer().sanitize (face->reference_table (HB_OT_TAG_CBDT)); diff --git a/src/hb-ot-hmtx-table.hh b/src/hb-ot-hmtx-table.hh index eed489026116be4bd0cf317899de06d92544acc2..b4ba2490ca4dc7d25aff5a9d27822a9f6b677d61 100644 --- a/src/hb-ot-hmtx-table.hh +++ b/src/hb-ot-hmtx-table.hh @@ -69,7 +69,7 @@ struct hmtxvmtx inline void init (hb_face_t *face, unsigned int default_advance_ = 0) { - default_advance = default_advance_ ? default_advance_ : face->get_upem (); + default_advance = default_advance_ ? default_advance_ : hb_face_get_upem (face); bool got_font_extents = false; if (T::os2Tag) diff --git a/src/hb-ot-shape-complex-indic-private.hh b/src/hb-ot-shape-complex-indic-private.hh index a64e9d03919d2e32a743af5bc0a5595de9b22fca..867b936278beb6e18c72853a68c2a9ae57c22d7c 100644 --- a/src/hb-ot-shape-complex-indic-private.hh +++ b/src/hb-ot-shape-complex-indic-private.hh @@ -34,6 +34,11 @@ #include "hb-ot-shape-private.hh" /* XXX Remove */ +/* buffer var allocations */ +#define indic_category() complex_var_u8_0() /* indic_category_t */ +#define indic_position() complex_var_u8_1() /* indic_position_t */ + + #define INDIC_TABLE_ELEMENT_TYPE uint16_t /* Cateories used in the OpenType spec: @@ -77,29 +82,29 @@ enum indic_category_t { /* Visual positions in a syllable from left to right. */ enum indic_position_t { - POS_START, + POS_START = 0, - POS_RA_TO_BECOME_REPH, - POS_PRE_M, - POS_PRE_C, + POS_RA_TO_BECOME_REPH = 1, + POS_PRE_M = 2, + POS_PRE_C = 3, - POS_BASE_C, - POS_AFTER_MAIN, + POS_BASE_C = 4, + POS_AFTER_MAIN = 5, - POS_ABOVE_C, + POS_ABOVE_C = 6, - POS_BEFORE_SUB, - POS_BELOW_C, - POS_AFTER_SUB, + POS_BEFORE_SUB = 7, + POS_BELOW_C = 8, + POS_AFTER_SUB = 9, - POS_BEFORE_POST, - POS_POST_C, - POS_AFTER_POST, + POS_BEFORE_POST = 10, + POS_POST_C = 11, + POS_AFTER_POST = 12, - POS_FINAL_C, - POS_SMVD, + POS_FINAL_C = 13, + POS_SMVD = 14, - POS_END + POS_END = 15 }; /* Categories used in IndicSyllabicCategory.txt from UCD. */ @@ -186,4 +191,211 @@ enum indic_matra_category_t { HB_INTERNAL INDIC_TABLE_ELEMENT_TYPE hb_indic_get_categories (hb_codepoint_t u); + +static inline bool +is_one_of (const hb_glyph_info_t &info, unsigned int flags) +{ + /* If it ligated, all bets are off. */ + if (_hb_glyph_info_ligated (&info)) return false; + return !!(FLAG_UNSAFE (info.indic_category()) & flags); +} + +static inline bool +is_joiner (const hb_glyph_info_t &info) +{ + return is_one_of (info, JOINER_FLAGS); +} + +static inline bool +is_consonant (const hb_glyph_info_t &info) +{ + return is_one_of (info, CONSONANT_FLAGS); +} + +static inline bool +is_halant (const hb_glyph_info_t &info) +{ + return is_one_of (info, FLAG (OT_H)); +} + +#define IN_HALF_BLOCK(u, Base) (((u) & ~0x7Fu) == (Base)) + +#define IS_DEVA(u) (IN_HALF_BLOCK (u, 0x0900u)) +#define IS_BENG(u) (IN_HALF_BLOCK (u, 0x0980u)) +#define IS_GURU(u) (IN_HALF_BLOCK (u, 0x0A00u)) +#define IS_GUJR(u) (IN_HALF_BLOCK (u, 0x0A80u)) +#define IS_ORYA(u) (IN_HALF_BLOCK (u, 0x0B00u)) +#define IS_TAML(u) (IN_HALF_BLOCK (u, 0x0B80u)) +#define IS_TELU(u) (IN_HALF_BLOCK (u, 0x0C00u)) +#define IS_KNDA(u) (IN_HALF_BLOCK (u, 0x0C80u)) +#define IS_MLYM(u) (IN_HALF_BLOCK (u, 0x0D00u)) +#define IS_SINH(u) (IN_HALF_BLOCK (u, 0x0D80u)) + + +#define MATRA_POS_LEFT(u) POS_PRE_M +#define MATRA_POS_RIGHT(u) ( \ + IS_DEVA(u) ? POS_AFTER_SUB : \ + IS_BENG(u) ? POS_AFTER_POST : \ + IS_GURU(u) ? POS_AFTER_POST : \ + IS_GUJR(u) ? POS_AFTER_POST : \ + IS_ORYA(u) ? POS_AFTER_POST : \ + IS_TAML(u) ? POS_AFTER_POST : \ + IS_TELU(u) ? (u <= 0x0C42u ? POS_BEFORE_SUB : POS_AFTER_SUB) : \ + IS_KNDA(u) ? (u < 0x0CC3u || u > 0xCD6u ? POS_BEFORE_SUB : POS_AFTER_SUB) : \ + IS_MLYM(u) ? POS_AFTER_POST : \ + IS_SINH(u) ? POS_AFTER_SUB : \ + /*default*/ POS_AFTER_SUB \ + ) +#define MATRA_POS_TOP(u) ( /* BENG and MLYM don't have top matras. */ \ + IS_DEVA(u) ? POS_AFTER_SUB : \ + IS_GURU(u) ? POS_AFTER_POST : /* Deviate from spec */ \ + IS_GUJR(u) ? POS_AFTER_SUB : \ + IS_ORYA(u) ? POS_AFTER_MAIN : \ + IS_TAML(u) ? POS_AFTER_SUB : \ + IS_TELU(u) ? POS_BEFORE_SUB : \ + IS_KNDA(u) ? POS_BEFORE_SUB : \ + IS_SINH(u) ? POS_AFTER_SUB : \ + /*default*/ POS_AFTER_SUB \ + ) +#define MATRA_POS_BOTTOM(u) ( \ + IS_DEVA(u) ? POS_AFTER_SUB : \ + IS_BENG(u) ? POS_AFTER_SUB : \ + IS_GURU(u) ? POS_AFTER_POST : \ + IS_GUJR(u) ? POS_AFTER_POST : \ + IS_ORYA(u) ? POS_AFTER_SUB : \ + IS_TAML(u) ? POS_AFTER_POST : \ + IS_TELU(u) ? POS_BEFORE_SUB : \ + IS_KNDA(u) ? POS_BEFORE_SUB : \ + IS_MLYM(u) ? POS_AFTER_POST : \ + IS_SINH(u) ? POS_AFTER_SUB : \ + /*default*/ POS_AFTER_SUB \ + ) + +static inline indic_position_t +matra_position_indic (hb_codepoint_t u, indic_position_t side) +{ + switch ((int) side) + { + case POS_PRE_C: return MATRA_POS_LEFT (u); + case POS_POST_C: return MATRA_POS_RIGHT (u); + case POS_ABOVE_C: return MATRA_POS_TOP (u); + case POS_BELOW_C: return MATRA_POS_BOTTOM (u); + }; + return side; +} + +/* XXX + * This is a hack for now. We should move this data into the main Indic table. + * Or completely remove it and just check in the tables. + */ +static const hb_codepoint_t ra_chars[] = { + 0x0930u, /* Devanagari */ + 0x09B0u, /* Bengali */ + 0x09F0u, /* Bengali */ + 0x0A30u, /* Gurmukhi */ /* No Reph */ + 0x0AB0u, /* Gujarati */ + 0x0B30u, /* Oriya */ + 0x0BB0u, /* Tamil */ /* No Reph */ + 0x0C30u, /* Telugu */ /* Reph formed only with ZWJ */ + 0x0CB0u, /* Kannada */ + 0x0D30u, /* Malayalam */ /* No Reph, Logical Repha */ + + 0x0DBBu, /* Sinhala */ /* Reph formed only with ZWJ */ +}; + +static inline bool +is_ra (hb_codepoint_t u) +{ + for (unsigned int i = 0; i < ARRAY_LENGTH (ra_chars); i++) + if (u == ra_chars[i]) + return true; + return false; +} + +static inline void +set_indic_properties (hb_glyph_info_t &info) +{ + hb_codepoint_t u = info.codepoint; + unsigned int type = hb_indic_get_categories (u); + indic_category_t cat = (indic_category_t) (type & 0x7Fu); + indic_position_t pos = (indic_position_t) (type >> 8); + + + /* + * Re-assign category + */ + + /* The following act more like the Bindus. */ + if (unlikely (hb_in_range (u, 0x0953u, 0x0954u))) + cat = OT_SM; + /* The following act like consonants. */ + else if (unlikely (hb_in_ranges (u, 0x0A72u, 0x0A73u, + 0x1CF5u, 0x1CF6u))) + cat = OT_C; + /* TODO: The following should only be allowed after a Visarga. + * For now, just treat them like regular tone marks. */ + else if (unlikely (hb_in_range (u, 0x1CE2u, 0x1CE8u))) + cat = OT_A; + /* TODO: The following should only be allowed after some of + * the nasalization marks, maybe only for U+1CE9..U+1CF1. + * For now, just treat them like tone marks. */ + else if (unlikely (u == 0x1CEDu)) + cat = OT_A; + /* The following take marks in standalone clusters, similar to Avagraha. */ + else if (unlikely (hb_in_ranges (u, 0xA8F2u, 0xA8F7u, + 0x1CE9u, 0x1CECu, + 0x1CEEu, 0x1CF1u))) + { + cat = OT_Symbol; + static_assert (((int) INDIC_SYLLABIC_CATEGORY_AVAGRAHA == OT_Symbol), ""); + } + else if (unlikely (u == 0x0A51u)) + { + /* https://github.com/harfbuzz/harfbuzz/issues/524 */ + cat = OT_M; + pos = POS_BELOW_C; + } + + /* According to ScriptExtensions.txt, these Grantha marks may also be used in Tamil, + * so the Indic shaper needs to know their categories. */ + else if (unlikely (u == 0x11301u || u == 0x11303u)) cat = OT_SM; + else if (unlikely (u == 0x1133cu)) cat = OT_N; + + else if (unlikely (u == 0x0AFBu)) cat = OT_N; /* https://github.com/harfbuzz/harfbuzz/issues/552 */ + + else if (unlikely (u == 0x0980u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/issues/538 */ + else if (unlikely (u == 0x0C80u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/pull/623 */ + else if (unlikely (hb_in_range (u, 0x2010u, 0x2011u))) + cat = OT_PLACEHOLDER; + else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE; + + + /* + * Re-assign position. + */ + + if ((FLAG_UNSAFE (cat) & CONSONANT_FLAGS)) + { + pos = POS_BASE_C; + if (is_ra (u)) + cat = OT_Ra; + } + else if (cat == OT_M) + { + pos = matra_position_indic (u, pos); + } + else if ((FLAG_UNSAFE (cat) & (FLAG (OT_SM) /* | FLAG (OT_VD) */ | FLAG (OT_A) | FLAG (OT_Symbol)))) + { + pos = POS_SMVD; + } + + if (unlikely (u == 0x0B01u)) pos = POS_BEFORE_SUB; /* Oriya Bindu is BeforeSub in the spec. */ + + + + info.indic_category() = cat; + info.indic_position() = pos; +} + + #endif /* HB_OT_SHAPE_COMPLEX_INDIC_PRIVATE_HH */ diff --git a/src/hb-ot-shape-complex-indic.cc b/src/hb-ot-shape-complex-indic.cc index 9d150e0d3c13fe66304d96f4de26543aabbd9eb4..32ad86a5f32735ae29f27ed1af1a9648c2e0e690 100644 --- a/src/hb-ot-shape-complex-indic.cc +++ b/src/hb-ot-shape-complex-indic.cc @@ -27,226 +27,12 @@ #include "hb-ot-shape-complex-indic-private.hh" #include "hb-ot-layout-private.hh" -/* buffer var allocations */ -#define indic_category() complex_var_u8_0() /* indic_category_t */ -#define indic_position() complex_var_u8_1() /* indic_position_t */ - /* * Indic shaper. */ -#define IN_HALF_BLOCK(u, Base) (((u) & ~0x7Fu) == (Base)) - -#define IS_DEVA(u) (IN_HALF_BLOCK (u, 0x0900u)) -#define IS_BENG(u) (IN_HALF_BLOCK (u, 0x0980u)) -#define IS_GURU(u) (IN_HALF_BLOCK (u, 0x0A00u)) -#define IS_GUJR(u) (IN_HALF_BLOCK (u, 0x0A80u)) -#define IS_ORYA(u) (IN_HALF_BLOCK (u, 0x0B00u)) -#define IS_TAML(u) (IN_HALF_BLOCK (u, 0x0B80u)) -#define IS_TELU(u) (IN_HALF_BLOCK (u, 0x0C00u)) -#define IS_KNDA(u) (IN_HALF_BLOCK (u, 0x0C80u)) -#define IS_MLYM(u) (IN_HALF_BLOCK (u, 0x0D00u)) -#define IS_SINH(u) (IN_HALF_BLOCK (u, 0x0D80u)) - - -#define MATRA_POS_LEFT(u) POS_PRE_M -#define MATRA_POS_RIGHT(u) ( \ - IS_DEVA(u) ? POS_AFTER_SUB : \ - IS_BENG(u) ? POS_AFTER_POST : \ - IS_GURU(u) ? POS_AFTER_POST : \ - IS_GUJR(u) ? POS_AFTER_POST : \ - IS_ORYA(u) ? POS_AFTER_POST : \ - IS_TAML(u) ? POS_AFTER_POST : \ - IS_TELU(u) ? (u <= 0x0C42u ? POS_BEFORE_SUB : POS_AFTER_SUB) : \ - IS_KNDA(u) ? (u < 0x0CC3u || u > 0xCD6u ? POS_BEFORE_SUB : POS_AFTER_SUB) : \ - IS_MLYM(u) ? POS_AFTER_POST : \ - IS_SINH(u) ? POS_AFTER_SUB : \ - /*default*/ POS_AFTER_SUB \ - ) -#define MATRA_POS_TOP(u) ( /* BENG and MLYM don't have top matras. */ \ - IS_DEVA(u) ? POS_AFTER_SUB : \ - IS_GURU(u) ? POS_AFTER_POST : /* Deviate from spec */ \ - IS_GUJR(u) ? POS_AFTER_SUB : \ - IS_ORYA(u) ? POS_AFTER_MAIN : \ - IS_TAML(u) ? POS_AFTER_SUB : \ - IS_TELU(u) ? POS_BEFORE_SUB : \ - IS_KNDA(u) ? POS_BEFORE_SUB : \ - IS_SINH(u) ? POS_AFTER_SUB : \ - /*default*/ POS_AFTER_SUB \ - ) -#define MATRA_POS_BOTTOM(u) ( \ - IS_DEVA(u) ? POS_AFTER_SUB : \ - IS_BENG(u) ? POS_AFTER_SUB : \ - IS_GURU(u) ? POS_AFTER_POST : \ - IS_GUJR(u) ? POS_AFTER_POST : \ - IS_ORYA(u) ? POS_AFTER_SUB : \ - IS_TAML(u) ? POS_AFTER_POST : \ - IS_TELU(u) ? POS_BEFORE_SUB : \ - IS_KNDA(u) ? POS_BEFORE_SUB : \ - IS_MLYM(u) ? POS_AFTER_POST : \ - IS_SINH(u) ? POS_AFTER_SUB : \ - /*default*/ POS_AFTER_SUB \ - ) - -static inline indic_position_t -matra_position (hb_codepoint_t u, indic_position_t side) -{ - switch ((int) side) - { - case POS_PRE_C: return MATRA_POS_LEFT (u); - case POS_POST_C: return MATRA_POS_RIGHT (u); - case POS_ABOVE_C: return MATRA_POS_TOP (u); - case POS_BELOW_C: return MATRA_POS_BOTTOM (u); - }; - return side; -} - -/* XXX - * This is a hack for now. We should move this data into the main Indic table. - * Or completely remove it and just check in the tables. - */ -static const hb_codepoint_t ra_chars[] = { - 0x0930u, /* Devanagari */ - 0x09B0u, /* Bengali */ - 0x09F0u, /* Bengali */ - 0x0A30u, /* Gurmukhi */ /* No Reph */ - 0x0AB0u, /* Gujarati */ - 0x0B30u, /* Oriya */ - 0x0BB0u, /* Tamil */ /* No Reph */ - 0x0C30u, /* Telugu */ /* Reph formed only with ZWJ */ - 0x0CB0u, /* Kannada */ - 0x0D30u, /* Malayalam */ /* No Reph, Logical Repha */ - - 0x0DBBu, /* Sinhala */ /* Reph formed only with ZWJ */ -}; - -static inline bool -is_ra (hb_codepoint_t u) -{ - for (unsigned int i = 0; i < ARRAY_LENGTH (ra_chars); i++) - if (u == ra_chars[i]) - return true; - return false; -} - -static inline bool -is_one_of (const hb_glyph_info_t &info, unsigned int flags) -{ - /* If it ligated, all bets are off. */ - if (_hb_glyph_info_ligated (&info)) return false; - return !!(FLAG_UNSAFE (info.indic_category()) & flags); -} - -static inline bool -is_joiner (const hb_glyph_info_t &info) -{ - return is_one_of (info, JOINER_FLAGS); -} - -static inline bool -is_consonant (const hb_glyph_info_t &info) -{ - return is_one_of (info, CONSONANT_FLAGS); -} - -static inline bool -is_halant (const hb_glyph_info_t &info) -{ - return is_one_of (info, FLAG (OT_H)); -} - -static inline void -set_indic_properties (hb_glyph_info_t &info) -{ - hb_codepoint_t u = info.codepoint; - unsigned int type = hb_indic_get_categories (u); - indic_category_t cat = (indic_category_t) (type & 0x7Fu); - indic_position_t pos = (indic_position_t) (type >> 8); - - - /* - * Re-assign category - */ - - /* The following act more like the Bindus. */ - if (unlikely (hb_in_range (u, 0x0953u, 0x0954u))) - cat = OT_SM; - /* The following act like consonants. */ - else if (unlikely (hb_in_ranges (u, 0x0A72u, 0x0A73u, - 0x1CF5u, 0x1CF6u))) - cat = OT_C; - /* TODO: The following should only be allowed after a Visarga. - * For now, just treat them like regular tone marks. */ - else if (unlikely (hb_in_range (u, 0x1CE2u, 0x1CE8u))) - cat = OT_A; - /* TODO: The following should only be allowed after some of - * the nasalization marks, maybe only for U+1CE9..U+1CF1. - * For now, just treat them like tone marks. */ - else if (unlikely (u == 0x1CEDu)) - cat = OT_A; - /* The following take marks in standalone clusters, similar to Avagraha. */ - else if (unlikely (hb_in_ranges (u, 0xA8F2u, 0xA8F7u, - 0x1CE9u, 0x1CECu, - 0x1CEEu, 0x1CF1u))) - { - cat = OT_Symbol; - static_assert (((int) INDIC_SYLLABIC_CATEGORY_AVAGRAHA == OT_Symbol), ""); - } - else if (unlikely (u == 0x0A51u)) - { - /* https://github.com/harfbuzz/harfbuzz/issues/524 */ - cat = OT_M; - pos = POS_BELOW_C; - } - - /* According to ScriptExtensions.txt, these Grantha marks may also be used in Tamil, - * so the Indic shaper needs to know their categories. */ - else if (unlikely (u == 0x11301u || u == 0x11303u)) cat = OT_SM; - else if (unlikely (u == 0x1133cu)) cat = OT_N; - - else if (unlikely (u == 0x0AFBu)) cat = OT_N; /* https://github.com/harfbuzz/harfbuzz/issues/552 */ - - else if (unlikely (u == 0x0980u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/issues/538 */ - else if (unlikely (u == 0x0C80u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/pull/623 */ - else if (unlikely (hb_in_range (u, 0x2010u, 0x2011u))) - cat = OT_PLACEHOLDER; - else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE; - - - /* - * Re-assign position. - */ - - if ((FLAG_UNSAFE (cat) & CONSONANT_FLAGS)) - { - pos = POS_BASE_C; - if (is_ra (u)) - cat = OT_Ra; - } - else if (cat == OT_M) - { - pos = matra_position (u, pos); - } - else if ((FLAG_UNSAFE (cat) & (FLAG (OT_SM) /* | FLAG (OT_VD) */ | FLAG (OT_A) | FLAG (OT_Symbol)))) - { - pos = POS_SMVD; - } - - if (unlikely (u == 0x0B01u)) pos = POS_BEFORE_SUB; /* Oriya Bindu is BeforeSub in the spec. */ - - - - info.indic_category() = cat; - info.indic_position() = pos; -} - -/* - * Things above this line should ideally be moved to the Indic table itself. - */ - - /* * Indic configurations. Note that we do not want to keep every single script-specific * behavior in these tables necessarily. This should mainly be used for per-script diff --git a/src/hb-ot-shape-complex-khmer-private.hh b/src/hb-ot-shape-complex-khmer-private.hh new file mode 100644 index 0000000000000000000000000000000000000000..f90ef967440605a062231f4e4a0def8f74d70a19 --- /dev/null +++ b/src/hb-ot-shape-complex-khmer-private.hh @@ -0,0 +1,124 @@ +/* + * 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_SHAPE_COMPLEX_KHMER_PRIVATE_HH +#define HB_OT_SHAPE_COMPLEX_KHMER_PRIVATE_HH + +#include "hb-private.hh" + +#include "hb-ot-shape-complex-indic-private.hh" + + +/* buffer var allocations */ +#define khmer_category() indic_category() /* khmer_category_t */ +#define khmer_position() indic_position() /* khmer_position_t */ + + +typedef indic_category_t khmer_category_t; +typedef indic_position_t khmer_position_t; + + +static inline khmer_position_t +matra_position_khmer (khmer_position_t side) +{ + switch ((int) side) + { + case POS_PRE_C: + return POS_PRE_M; + + case POS_POST_C: + case POS_ABOVE_C: + case POS_BELOW_C: + return POS_AFTER_POST; + + default: + return side; + }; +} + +static inline bool +is_consonant_or_vowel (const hb_glyph_info_t &info) +{ + return is_one_of (info, CONSONANT_FLAGS | FLAG (OT_V)); +} + +static inline bool +is_coeng (const hb_glyph_info_t &info) +{ + return is_one_of (info, FLAG (OT_Coeng)); +} + +static inline void +set_khmer_properties (hb_glyph_info_t &info) +{ + hb_codepoint_t u = info.codepoint; + unsigned int type = hb_indic_get_categories (u); + khmer_category_t cat = (khmer_category_t) (type & 0x7Fu); + khmer_position_t pos = (khmer_position_t) (type >> 8); + + + /* + * Re-assign category + */ + + if (unlikely (u == 0x17C6u)) cat = OT_N; /* Khmer Bindu doesn't like to be repositioned. */ + else if (unlikely (hb_in_range (u, 0x17CDu, 0x17D1u) || + u == 0x17CBu || u == 0x17D3u || u == 0x17DDu)) /* Khmer Various signs */ + { + /* These can occur mid-syllable (eg. before matras), even though Unicode marks them as Syllable_Modifier. + * https://github.com/roozbehp/unicode-data/issues/5 */ + cat = OT_M; + pos = POS_ABOVE_C; + } + else if (unlikely (hb_in_range (u, 0x2010u, 0x2011u))) cat = OT_PLACEHOLDER; + else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE; + + + /* + * Re-assign position. + */ + + if ((FLAG_UNSAFE (cat) & CONSONANT_FLAGS)) + { + pos = POS_BASE_C; + if (u == 0x179Au) + cat = OT_Ra; + } + else if (cat == OT_M) + { + pos = matra_position_khmer (pos); + } + else if ((FLAG_UNSAFE (cat) & (FLAG (OT_SM) | FLAG (OT_A) | FLAG (OT_Symbol)))) + { + pos = POS_SMVD; + } + + info.khmer_category() = cat; + info.khmer_position() = pos; +} + + +#endif /* HB_OT_SHAPE_COMPLEX_KHMER_PRIVATE_HH */ diff --git a/src/hb-ot-shape-complex-khmer.cc b/src/hb-ot-shape-complex-khmer.cc index 2db4f6097d81a0730253536f634b200a0f80fc41..304879d8fbbe7d0420faf8dd006ad6acc5afa00c 100644 --- a/src/hb-ot-shape-complex-khmer.cc +++ b/src/hb-ot-shape-complex-khmer.cc @@ -24,119 +24,9 @@ * Google Author(s): Behdad Esfahbod */ -#include "hb-ot-shape-complex-indic-private.hh" +#include "hb-ot-shape-complex-khmer-private.hh" #include "hb-ot-layout-private.hh" -/* buffer var allocations */ -#define khmer_category() complex_var_u8_0() /* khmer_category_t */ -#define khmer_position() complex_var_u8_1() /* khmer_position_t */ - - -/* - * Khmer shaper. - */ - -typedef indic_category_t khmer_category_t; -typedef indic_position_t khmer_position_t; - - -static inline khmer_position_t -matra_position (khmer_position_t side) -{ - switch ((int) side) - { - case POS_PRE_C: - return POS_PRE_M; - - case POS_POST_C: - case POS_ABOVE_C: - case POS_BELOW_C: - return POS_AFTER_POST; - - default: - return side; - }; -} - -static inline bool -is_one_of (const hb_glyph_info_t &info, unsigned int flags) -{ - /* If it ligated, all bets are off. */ - if (_hb_glyph_info_ligated (&info)) return false; - return !!(FLAG_UNSAFE (info.khmer_category()) & flags); -} - -static inline bool -is_joiner (const hb_glyph_info_t &info) -{ - return is_one_of (info, JOINER_FLAGS); -} - -static inline bool -is_consonant (const hb_glyph_info_t &info) -{ - return is_one_of (info, CONSONANT_FLAGS | FLAG (OT_V)); -} - -static inline bool -is_coeng (const hb_glyph_info_t &info) -{ - return is_one_of (info, FLAG (OT_Coeng)); -} - -static inline void -set_khmer_properties (hb_glyph_info_t &info) -{ - hb_codepoint_t u = info.codepoint; - unsigned int type = hb_indic_get_categories (u); - khmer_category_t cat = (khmer_category_t) (type & 0x7Fu); - khmer_position_t pos = (khmer_position_t) (type >> 8); - - - /* - * Re-assign category - */ - - if (unlikely (u == 0x17C6u)) cat = OT_N; /* Khmer Bindu doesn't like to be repositioned. */ - else if (unlikely (hb_in_range (u, 0x17CDu, 0x17D1u) || - u == 0x17CBu || u == 0x17D3u || u == 0x17DDu)) /* Khmer Various signs */ - { - /* These can occur mid-syllable (eg. before matras), even though Unicode marks them as Syllable_Modifier. - * https://github.com/roozbehp/unicode-data/issues/5 */ - cat = OT_M; - pos = POS_ABOVE_C; - } - else if (unlikely (hb_in_range (u, 0x2010u, 0x2011u))) cat = OT_PLACEHOLDER; - else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE; - - - /* - * Re-assign position. - */ - - if ((FLAG_UNSAFE (cat) & CONSONANT_FLAGS)) - { - pos = POS_BASE_C; - if (u == 0x179Au) - cat = OT_Ra; - } - else if (cat == OT_M) - { - pos = matra_position (pos); - } - else if ((FLAG_UNSAFE (cat) & (FLAG (OT_SM) | FLAG (OT_A) | FLAG (OT_Symbol)))) - { - pos = POS_SMVD; - } - - info.khmer_category() = cat; - info.khmer_position() = pos; -} - -/* - * Things above this line should ideally be moved to the Indic table itself. - */ - /* * Khmer shaper. @@ -404,7 +294,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, /* Mark all subsequent consonants as below. */ for (unsigned int i = base + 1; i < end; i++) - if (is_consonant (info[i])) + if (is_consonant_or_vowel (info[i])) info[i].khmer_position() = POS_BELOW_C; /* Mark final consonants. A final consonant is one appearing after a matra, @@ -412,7 +302,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, for (unsigned int i = base + 1; i < end; i++) if (info[i].khmer_category() == OT_M) { for (unsigned int j = i + 1; j < end; j++) - if (is_consonant (info[j])) { + if (is_consonant_or_vowel (info[j])) { info[j].khmer_position() = POS_FINAL_C; break; } @@ -455,7 +345,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, { unsigned int last = base; for (unsigned int i = base + 1; i < end; i++) - if (is_consonant (info[i])) + if (is_consonant_or_vowel (info[i])) { for (unsigned int j = last + 1; j < i; j++) if (info[j].khmer_position() < POS_SMVD) diff --git a/src/hb-ot-shape-complex-myanmar-private.hh b/src/hb-ot-shape-complex-myanmar-private.hh new file mode 100644 index 0000000000000000000000000000000000000000..04f81bd12275abefbaf796add3642b78502fef29 --- /dev/null +++ b/src/hb-ot-shape-complex-myanmar-private.hh @@ -0,0 +1,171 @@ +/* + * 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_SHAPE_COMPLEX_MYANMAR_PRIVATE_HH +#define HB_OT_SHAPE_COMPLEX_MYANMAR_PRIVATE_HH + +#include "hb-private.hh" + +#include "hb-ot-shape-complex-indic-private.hh" + + +/* buffer var allocations */ +#define myanmar_category() indic_category() /* myanmar_category_t */ +#define myanmar_position() indic_position() /* myanmar_position_t */ + + +/* Note: This enum is duplicated in the -machine.rl source file. + * Not sure how to avoid duplication. */ +enum myanmar_category_t { + OT_As = 18, /* Asat */ + OT_D0 = 20, /* Digit zero */ + OT_DB = OT_N, /* Dot below */ + OT_GB = OT_PLACEHOLDER, + OT_MH = 21, /* Various consonant medial types */ + OT_MR = 22, /* Various consonant medial types */ + OT_MW = 23, /* Various consonant medial types */ + OT_MY = 24, /* Various consonant medial types */ + OT_PT = 25, /* Pwo and other tones */ + OT_VAbv = 26, + OT_VBlw = 27, + OT_VPre = 28, + OT_VPst = 29, + OT_VS = 30, /* Variation selectors */ + OT_P = 31, /* Punctuation */ + OT_D = 32, /* Digits except zero */ +}; + + +static inline void +set_myanmar_properties (hb_glyph_info_t &info) +{ + hb_codepoint_t u = info.codepoint; + unsigned int type = hb_indic_get_categories (u); + indic_category_t cat = (indic_category_t) (type & 0x7Fu); + indic_position_t pos = (indic_position_t) (type >> 8); + + /* Myanmar + * http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm#analyze + */ + if (unlikely (hb_in_range (u, 0xFE00u, 0xFE0Fu))) + cat = (indic_category_t) OT_VS; + + switch (u) + { + case 0x104Eu: + cat = (indic_category_t) OT_C; /* The spec says C, IndicSyllableCategory doesn't have. */ + break; + + case 0x002Du: case 0x00A0u: case 0x00D7u: case 0x2012u: + case 0x2013u: case 0x2014u: case 0x2015u: case 0x2022u: + case 0x25CCu: case 0x25FBu: case 0x25FCu: case 0x25FDu: + case 0x25FEu: + cat = (indic_category_t) OT_GB; + break; + + case 0x1004u: case 0x101Bu: case 0x105Au: + cat = (indic_category_t) OT_Ra; + break; + + case 0x1032u: case 0x1036u: + cat = (indic_category_t) OT_A; + break; + + case 0x1039u: + cat = (indic_category_t) OT_H; + break; + + case 0x103Au: + cat = (indic_category_t) OT_As; + break; + + case 0x1041u: case 0x1042u: case 0x1043u: case 0x1044u: + case 0x1045u: case 0x1046u: case 0x1047u: case 0x1048u: + case 0x1049u: case 0x1090u: case 0x1091u: case 0x1092u: + case 0x1093u: case 0x1094u: case 0x1095u: case 0x1096u: + case 0x1097u: case 0x1098u: case 0x1099u: + cat = (indic_category_t) OT_D; + break; + + case 0x1040u: + cat = (indic_category_t) OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */ + break; + + case 0x103Eu: case 0x1060u: + cat = (indic_category_t) OT_MH; + break; + + case 0x103Cu: + cat = (indic_category_t) OT_MR; + break; + + case 0x103Du: case 0x1082u: + cat = (indic_category_t) OT_MW; + break; + + case 0x103Bu: case 0x105Eu: case 0x105Fu: + cat = (indic_category_t) OT_MY; + break; + + case 0x1063u: case 0x1064u: case 0x1069u: case 0x106Au: + case 0x106Bu: case 0x106Cu: case 0x106Du: case 0xAA7Bu: + cat = (indic_category_t) OT_PT; + break; + + case 0x1038u: case 0x1087u: case 0x1088u: case 0x1089u: + case 0x108Au: case 0x108Bu: case 0x108Cu: case 0x108Du: + case 0x108Fu: case 0x109Au: case 0x109Bu: case 0x109Cu: + cat = (indic_category_t) OT_SM; + break; + + case 0x104Au: case 0x104Bu: + cat = (indic_category_t) OT_P; + break; + + case 0xAA74u: case 0xAA75u: case 0xAA76u: + /* https://github.com/roozbehp/unicode-data/issues/3 */ + cat = (indic_category_t) OT_C; + break; + } + + if (cat == OT_M) + { + switch ((int) pos) + { + case POS_PRE_C: cat = (indic_category_t) OT_VPre; + pos = POS_PRE_M; break; + case POS_ABOVE_C: cat = (indic_category_t) OT_VAbv; break; + case POS_BELOW_C: cat = (indic_category_t) OT_VBlw; break; + case POS_POST_C: cat = (indic_category_t) OT_VPst; break; + } + } + + info.myanmar_category() = (myanmar_category_t) cat; + info.myanmar_position() = pos; +} + + +#endif /* HB_OT_SHAPE_COMPLEX_MYANMAR_PRIVATE_HH */ diff --git a/src/hb-ot-shape-complex-myanmar.cc b/src/hb-ot-shape-complex-myanmar.cc index 31bb976b1bbd62f88869d819b68a440c6b7c2911..3c57bc1ff66cf8a502aa38926d5e5d324161668e 100644 --- a/src/hb-ot-shape-complex-myanmar.cc +++ b/src/hb-ot-shape-complex-myanmar.cc @@ -24,11 +24,7 @@ * Google Author(s): Behdad Esfahbod */ -#include "hb-ot-shape-complex-indic-private.hh" - -/* buffer var allocations */ -#define myanmar_category() complex_var_u8_0() /* myanmar_category_t */ -#define myanmar_position() complex_var_u8_1() /* myanmar_position_t */ +#include "hb-ot-shape-complex-myanmar-private.hh" /* @@ -127,153 +123,6 @@ enum syllable_type_t { #include "hb-ot-shape-complex-myanmar-machine.hh" -/* Note: This enum is duplicated in the -machine.rl source file. - * Not sure how to avoid duplication. */ -enum myanmar_category_t { - OT_As = 18, /* Asat */ - OT_D0 = 20, /* Digit zero */ - OT_DB = OT_N, /* Dot below */ - OT_GB = OT_PLACEHOLDER, - OT_MH = 21, /* Various consonant medial types */ - OT_MR = 22, /* Various consonant medial types */ - OT_MW = 23, /* Various consonant medial types */ - OT_MY = 24, /* Various consonant medial types */ - OT_PT = 25, /* Pwo and other tones */ - OT_VAbv = 26, - OT_VBlw = 27, - OT_VPre = 28, - OT_VPst = 29, - OT_VS = 30, /* Variation selectors */ - OT_P = 31, /* Punctuation */ - OT_D = 32, /* Digits except zero */ -}; - - -static inline bool -is_one_of (const hb_glyph_info_t &info, unsigned int flags) -{ - /* If it ligated, all bets are off. */ - if (_hb_glyph_info_ligated (&info)) return false; - return !!(FLAG_UNSAFE (info.myanmar_category()) & flags); -} - -static inline bool -is_consonant (const hb_glyph_info_t &info) -{ - return is_one_of (info, CONSONANT_FLAGS); -} - - -static inline void -set_myanmar_properties (hb_glyph_info_t &info) -{ - hb_codepoint_t u = info.codepoint; - unsigned int type = hb_indic_get_categories (u); - indic_category_t cat = (indic_category_t) (type & 0x7Fu); - indic_position_t pos = (indic_position_t) (type >> 8); - - /* Myanmar - * http://www.microsoft.com/typography/OpenTypeDev/myanmar/intro.htm#analyze - */ - if (unlikely (hb_in_range (u, 0xFE00u, 0xFE0Fu))) - cat = (indic_category_t) OT_VS; - - switch (u) - { - case 0x104Eu: - cat = (indic_category_t) OT_C; /* The spec says C, IndicSyllableCategory doesn't have. */ - break; - - case 0x002Du: case 0x00A0u: case 0x00D7u: case 0x2012u: - case 0x2013u: case 0x2014u: case 0x2015u: case 0x2022u: - case 0x25CCu: case 0x25FBu: case 0x25FCu: case 0x25FDu: - case 0x25FEu: - cat = (indic_category_t) OT_GB; - break; - - case 0x1004u: case 0x101Bu: case 0x105Au: - cat = (indic_category_t) OT_Ra; - break; - - case 0x1032u: case 0x1036u: - cat = (indic_category_t) OT_A; - break; - - case 0x1039u: - cat = (indic_category_t) OT_H; - break; - - case 0x103Au: - cat = (indic_category_t) OT_As; - break; - - case 0x1041u: case 0x1042u: case 0x1043u: case 0x1044u: - case 0x1045u: case 0x1046u: case 0x1047u: case 0x1048u: - case 0x1049u: case 0x1090u: case 0x1091u: case 0x1092u: - case 0x1093u: case 0x1094u: case 0x1095u: case 0x1096u: - case 0x1097u: case 0x1098u: case 0x1099u: - cat = (indic_category_t) OT_D; - break; - - case 0x1040u: - cat = (indic_category_t) OT_D; /* XXX The spec says D0, but Uniscribe doesn't seem to do. */ - break; - - case 0x103Eu: case 0x1060u: - cat = (indic_category_t) OT_MH; - break; - - case 0x103Cu: - cat = (indic_category_t) OT_MR; - break; - - case 0x103Du: case 0x1082u: - cat = (indic_category_t) OT_MW; - break; - - case 0x103Bu: case 0x105Eu: case 0x105Fu: - cat = (indic_category_t) OT_MY; - break; - - case 0x1063u: case 0x1064u: case 0x1069u: case 0x106Au: - case 0x106Bu: case 0x106Cu: case 0x106Du: case 0xAA7Bu: - cat = (indic_category_t) OT_PT; - break; - - case 0x1038u: case 0x1087u: case 0x1088u: case 0x1089u: - case 0x108Au: case 0x108Bu: case 0x108Cu: case 0x108Du: - case 0x108Fu: case 0x109Au: case 0x109Bu: case 0x109Cu: - cat = (indic_category_t) OT_SM; - break; - - case 0x104Au: case 0x104Bu: - cat = (indic_category_t) OT_P; - break; - - case 0xAA74u: case 0xAA75u: case 0xAA76u: - /* https://github.com/roozbehp/unicode-data/issues/3 */ - cat = (indic_category_t) OT_C; - break; - } - - if (cat == OT_M) - { - switch ((int) pos) - { - case POS_PRE_C: cat = (indic_category_t) OT_VPre; - pos = POS_PRE_M; break; - case POS_ABOVE_C: cat = (indic_category_t) OT_VAbv; break; - case POS_BELOW_C: cat = (indic_category_t) OT_VBlw; break; - case POS_POST_C: cat = (indic_category_t) OT_VPst; break; - } - } - - info.myanmar_category() = (myanmar_category_t) cat; - info.myanmar_position() = pos; -} - - - static void setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_buffer_t *buffer, diff --git a/src/hb-ot-shape-complex-use-private.hh b/src/hb-ot-shape-complex-use-private.hh index 3e763ae3936c224c5cec1be448aeb3526f4602d4..f7ded133d6b0d308237359a2cfc005f432e68644 100644 --- a/src/hb-ot-shape-complex-use-private.hh +++ b/src/hb-ot-shape-complex-use-private.hh @@ -92,6 +92,6 @@ enum use_category_t { }; HB_INTERNAL USE_TABLE_ELEMENT_TYPE -hb_use_get_categories (hb_codepoint_t u); +hb_use_get_category (hb_codepoint_t u); #endif /* HB_OT_SHAPE_COMPLEX_USE_PRIVATE_HH */ diff --git a/src/hb-ot-shape-complex-use-table.cc b/src/hb-ot-shape-complex-use-table.cc index a67ef061122b4571027a81cb9fa1db613fa73c3c..6823392f4b4657176eb59792314dcad45367ecc7 100644 --- a/src/hb-ot-shape-complex-use-table.cc +++ b/src/hb-ot-shape-complex-use-table.cc @@ -690,7 +690,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { }; /* Table items: 5424; occupancy: 73% */ USE_TABLE_ELEMENT_TYPE -hb_use_get_categories (hb_codepoint_t u) +hb_use_get_category (hb_codepoint_t u) { switch (u >> 12) { diff --git a/src/hb-ot-shape-complex-use.cc b/src/hb-ot-shape-complex-use.cc index 62acd697bdd294e42633d8516f0c668631c03e9a..ee7653b51ce6eea477b5a5d9e96222169eae5ba4 100644 --- a/src/hb-ot-shape-complex-use.cc +++ b/src/hb-ot-shape-complex-use.cc @@ -262,7 +262,7 @@ setup_masks_use (const hb_ot_shape_plan_t *plan, unsigned int count = buffer->len; hb_glyph_info_t *info = buffer->info; for (unsigned int i = 0; i < count; i++) - info[i].use_category() = hb_use_get_categories (info[i].codepoint); + info[i].use_category() = hb_use_get_category (info[i].codepoint); } static void @@ -505,7 +505,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, hb_glyph_info_t dottedcircle = {0}; if (!font->get_nominal_glyph (0x25CCu, &dottedcircle.codepoint)) return; - dottedcircle.use_category() = hb_use_get_categories (0x25CC); + dottedcircle.use_category() = hb_use_get_category (0x25CC); buffer->clear_output (); diff --git a/src/hb-set-private.hh b/src/hb-set-private.hh index d71d41224be7e0baed8771eb0bddab8dc026ed74..7282b07991ef03e45be9b8b6de590f963ed4fe46 100644 --- a/src/hb-set-private.hh +++ b/src/hb-set-private.hh @@ -121,6 +121,33 @@ struct hb_set_t *codepoint = INVALID; return false; + found: + *codepoint = i * ELT_BITS + j; + return true; + } + inline bool previous (hb_codepoint_t *codepoint) const + { + unsigned int m = (*codepoint - 1) & MASK; + if (m == MASK) + { + *codepoint = INVALID; + return false; + } + unsigned int i = m / ELT_BITS; + unsigned int j = m & ELT_MASK; + + for (; (int) j >= 0; j--) + if (v[i] & (elt_t (1) << j)) + goto found; + for (i--; (int) i >= 0; i--) + if (v[i]) + for (j = ELT_BITS - 1; (int) j >= 0; j--) + if (v[i] & (elt_t (1) << j)) + goto found; + + *codepoint = INVALID; + return false; + found: *codepoint = i * ELT_BITS + j; return true; @@ -471,12 +498,12 @@ struct hb_set_t page_map_t map = {get_major (*codepoint), 0}; unsigned int i; page_map.bfind (map, &i); - if (i < page_map.len) + if (i < page_map.len && page_map[i].major == map.major) { if (pages[page_map[i].index].next (codepoint)) { *codepoint += page_map[i].major * page_t::PAGE_BITS; - return true; + return true; } i++; } @@ -492,6 +519,37 @@ struct hb_set_t *codepoint = INVALID; return false; } + inline bool previous (hb_codepoint_t *codepoint) const + { + if (unlikely (*codepoint == INVALID)) { + *codepoint = get_max (); + return *codepoint != INVALID; + } + + page_map_t map = {get_major (*codepoint), 0}; + unsigned int i; + page_map.bfind (map, &i); + if (i < page_map.len && page_map[i].major == map.major) + { + if (pages[page_map[i].index].previous (codepoint)) + { + *codepoint += page_map[i].major * page_t::PAGE_BITS; + return true; + } + } + i--; + for (; (int) i >= 0; i--) + { + hb_codepoint_t m = pages[page_map[i].index].get_max (); + if (m != INVALID) + { + *codepoint = page_map[i].major * page_t::PAGE_BITS + m; + return true; + } + } + *codepoint = INVALID; + return false; + } inline bool next_range (hb_codepoint_t *first, hb_codepoint_t *last) const { hb_codepoint_t i; @@ -503,12 +561,31 @@ struct hb_set_t return false; } + /* TODO Speed up. */ *last = *first = i; while (next (&i) && i == *last + 1) (*last)++; return true; } + inline bool previous_range (hb_codepoint_t *first, hb_codepoint_t *last) const + { + hb_codepoint_t i; + + i = *first; + if (!previous (&i)) + { + *last = *first = INVALID; + return false; + } + + /* TODO Speed up. */ + *last = *first = i; + while (previous (&i) && i == *first - 1) + (*first)--; + + return true; + } inline unsigned int get_population (void) const { diff --git a/src/hb-set.cc b/src/hb-set.cc index 0b4f871e852fda9bb9ff18bcf69c8725db9045b7..07cf9d09b55bc08dcb20bd9e3a7e432358bbcb10 100644 --- a/src/hb-set.cc +++ b/src/hb-set.cc @@ -50,6 +50,13 @@ hb_set_create (void) return set; } +static const hb_set_t _hb_set_nil = { + HB_OBJECT_HEADER_STATIC, + true, /* in_error */ + + {0} /* elts */ +}; + /** * hb_set_get_empty: * @@ -60,13 +67,6 @@ hb_set_create (void) hb_set_t * hb_set_get_empty (void) { - static const hb_set_t _hb_set_nil = { - HB_OBJECT_HEADER_STATIC, - true, /* in_error */ - - {0} /* elts */ - }; - return const_cast (&_hb_set_nil); } @@ -437,7 +437,9 @@ hb_set_get_max (const hb_set_t *set) * @set: a set. * @codepoint: (inout): * - * + * Gets the next number in @set that is greater than current value of @codepoint. + * + * Set @codepoint to %HB_SET_VALUE_INVALID to get started. * * Return value: whether there was a next value. * @@ -450,6 +452,26 @@ hb_set_next (const hb_set_t *set, return set->next (codepoint); } +/** + * hb_set_previous: + * @set: a set. + * @codepoint: (inout): + * + * Gets the previous number in @set that is slower than current value of @codepoint. + * + * Set @codepoint to %HB_SET_VALUE_INVALID to get started. + * + * Return value: whether there was a previous value. + * + * Since: 1.8.0 + **/ +hb_bool_t +hb_set_previous (const hb_set_t *set, + hb_codepoint_t *codepoint) +{ + return set->previous (codepoint); +} + /** * hb_set_next_range: * @set: a set. @@ -459,6 +481,8 @@ hb_set_next (const hb_set_t *set, * Gets the next consecutive range of numbers in @set that * are greater than current value of @last. * + * Set @last to %HB_SET_VALUE_INVALID to get started. + * * Return value: whether there was a next range. * * Since: 0.9.7 @@ -470,3 +494,26 @@ hb_set_next_range (const hb_set_t *set, { return set->next_range (first, last); } + +/** + * hb_set_previous_range: + * @set: a set. + * @first: (inout): input current first and output first codepoint in the range. + * @last: (out): output last codepoint in the range. + * + * Gets the previous consecutive range of numbers in @set that + * are greater than current value of @last. + * + * Set @first to %HB_SET_VALUE_INVALID to get started. + * + * Return value: whether there was a previous range. + * + * Since: 1.8.0 + **/ +hb_bool_t +hb_set_previous_range (const hb_set_t *set, + hb_codepoint_t *first, + hb_codepoint_t *last) +{ + return set->previous_range (first, last); +} diff --git a/src/hb-set.h b/src/hb-set.h index 2ce406073ce473a913eeb12f66ea59ce6c2718e0..b0f82f82208c78aea83344c1c999808db21a3ab1 100644 --- a/src/hb-set.h +++ b/src/hb-set.h @@ -129,25 +129,36 @@ hb_set_symmetric_difference (hb_set_t *set, HB_EXTERN unsigned int hb_set_get_population (const hb_set_t *set); -/* Returns -1 if set empty. */ +/* Returns HB_SET_VALUE_INVALID if set empty. */ HB_EXTERN hb_codepoint_t hb_set_get_min (const hb_set_t *set); -/* Returns -1 if set empty. */ +/* Returns HB_SET_VALUE_INVALID if set empty. */ HB_EXTERN hb_codepoint_t hb_set_get_max (const hb_set_t *set); -/* Pass -1 in to get started. */ +/* Pass HB_SET_VALUE_INVALID in to get started. */ HB_EXTERN hb_bool_t hb_set_next (const hb_set_t *set, hb_codepoint_t *codepoint); -/* Pass -1 for first and last to get started. */ +/* Pass HB_SET_VALUE_INVALID in to get started. */ +HB_EXTERN hb_bool_t +hb_set_previous (const hb_set_t *set, + hb_codepoint_t *codepoint); + +/* Pass HB_SET_VALUE_INVALID for first and last to get started. */ HB_EXTERN hb_bool_t hb_set_next_range (const hb_set_t *set, hb_codepoint_t *first, hb_codepoint_t *last); +/* Pass HB_SET_VALUE_INVALID for first and last to get started. */ +HB_EXTERN hb_bool_t +hb_set_previous_range (const hb_set_t *set, + hb_codepoint_t *first, + hb_codepoint_t *last); + HB_END_DECLS diff --git a/src/hb-subset-glyf.cc b/src/hb-subset-glyf.cc index 28f5f0c5777a2a18121959fce00091f97b58ebe1..36789f9bfb096a6ed3cfdcb1c2186cafe0406943 100644 --- a/src/hb-subset-glyf.cc +++ b/src/hb-subset-glyf.cc @@ -38,14 +38,12 @@ _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf, { unsigned int total = 0; unsigned int count = 0; - for (unsigned int i = 0; i < glyph_ids.len; i++) { + for (unsigned int i = 0; i < glyph_ids.len; i++) + { hb_codepoint_t next_glyph = glyph_ids[i]; unsigned int start_offset, end_offset; - if (unlikely (!glyf.get_offsets (next_glyph, &start_offset, &end_offset))) { - *glyf_size = 0; - *loca_size = sizeof(OT::HBUINT32); - return false; - } + if (unlikely (!glyf.get_offsets (next_glyph, &start_offset, &end_offset))) + end_offset = start_offset = 0; total += end_offset - start_offset; count++; @@ -84,29 +82,21 @@ _write_glyf_and_loca_prime (const OT::glyf::accelerator_t &glyf, { char *glyf_prime_data_next = glyf_prime_data; - hb_codepoint_t new_glyph_id = 0; - - unsigned int current_offset = 0; - unsigned int end_offset = 0; - for (unsigned int i = 0; i < glyph_ids.len; i++) { - unsigned int start_offset; - if (unlikely (!glyf.get_offsets (glyph_ids[i], &start_offset, &end_offset))) { - return false; - } + for (unsigned int i = 0; i < glyph_ids.len; i++) + { + unsigned int start_offset, end_offset; + if (unlikely (!glyf.get_offsets (glyph_ids[i], &start_offset, &end_offset))) + end_offset = start_offset = 0; int length = end_offset - start_offset; memcpy (glyf_prime_data_next, glyf_data + start_offset, length); - _write_loca_entry (i, current_offset, use_short_loca, loca_prime_data); + _write_loca_entry (i, glyf_prime_data_next - glyf_prime_data, use_short_loca, loca_prime_data); glyf_prime_data_next += length; - current_offset += length; - new_glyph_id++; } - // Add the last loca entry which doesn't correspond to a specific glyph - // but identifies the end of the last glyphs data. - _write_loca_entry (new_glyph_id, current_offset, use_short_loca, loca_prime_data); + _write_loca_entry (glyph_ids.len, glyf_prime_data_next - glyf_prime_data, use_short_loca, loca_prime_data); return true; } @@ -134,8 +124,8 @@ _hb_subset_glyf_and_loca (const OT::glyf::accelerator_t &glyf, return false; } - char *glyf_prime_data = (char *) calloc (glyf_prime_size, 1); - char *loca_prime_data = (char *) calloc (loca_prime_size, 1); + char *glyf_prime_data = (char *) malloc (glyf_prime_size); + char *loca_prime_data = (char *) malloc (loca_prime_size); if (unlikely (!_write_glyf_and_loca_prime (glyf, glyf_data, glyphs_to_retain, *use_short_loca, glyf_prime_size, glyf_prime_data, diff --git a/src/hb-subset-input.cc b/src/hb-subset-input.cc new file mode 100644 index 0000000000000000000000000000000000000000..d41cff6019a5f59e992c4f8336888c0a68996d12 --- /dev/null +++ b/src/hb-subset-input.cc @@ -0,0 +1,107 @@ +/* + * 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, Rod Sheeter, Behdad Esfahbod + */ + +#include "hb-object-private.hh" +#include "hb-subset-private.hh" +#include "hb-set-private.hh" + +/** + * hb_subset_input_create_or_fail: + * + * Return value: New subset input. + * + * Since: 1.8.0 + **/ +hb_subset_input_t * +hb_subset_input_create_or_fail (void) +{ + hb_subset_input_t *input = hb_object_create(); + + if (unlikely (!input)) + return nullptr; + + input->unicodes = hb_set_create (); + input->glyphs = hb_set_create (); + + return input; +} + +/** + * hb_subset_input_reference: (skip) + * @subset_input: a subset_input. + * + * + * + * Return value: + * + * Since: 1.8.0 + **/ +hb_subset_input_t * +hb_subset_input_reference (hb_subset_input_t *subset_input) +{ + return hb_object_reference (subset_input); +} + +/** + * hb_subset_input_destroy: + * @subset_input: a subset_input. + * + * Since: 1.8.0 + **/ +void +hb_subset_input_destroy(hb_subset_input_t *subset_input) +{ + if (!hb_object_destroy (subset_input)) return; + + hb_set_destroy (subset_input->unicodes); + hb_set_destroy (subset_input->glyphs); + + free (subset_input); +} + +/** + * hb_subset_input_unicode_set: + * @subset_input: a subset_input. + * + * Since: 1.8.0 + **/ +HB_EXTERN hb_set_t * +hb_subset_input_unicode_set (hb_subset_input_t *subset_input) +{ + return subset_input->unicodes; +} + +/** + * hb_subset_input_glyph_set: + * @subset_input: a subset_input. + * + * Since: 1.8.0 + **/ +HB_EXTERN hb_set_t * +hb_subset_input_glyph_set (hb_subset_input_t *subset_input) +{ + return subset_input->glyphs; +} diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc index 286f7e15853e3e21b7e2e22e54eaad973d04e70e..6f4b003b3ea7bb875d27c0468f4cf212817b5876 100644 --- a/src/hb-subset-plan.cc +++ b/src/hb-subset-plan.cc @@ -155,7 +155,7 @@ hb_subset_plan_create (hb_face_t *face, plan->gids_to_retain.init(); plan->gids_to_retain_sorted.init(); - _populate_codepoints (input->codepoints, plan->codepoints); + _populate_codepoints (input->unicodes, plan->codepoints); _populate_gids_to_retain (face, plan->codepoints, plan->gids_to_retain, diff --git a/src/hb-subset-private.hh b/src/hb-subset-private.hh index 9689da808c5449a740a46dae32db528343f63f7b..4ef1b9540575ca69fc6f0e40e36b595192ecd258 100644 --- a/src/hb-subset-private.hh +++ b/src/hb-subset-private.hh @@ -38,7 +38,16 @@ struct hb_subset_input_t { hb_object_header_t header; ASSERT_POD (); - hb_set_t *codepoints; + hb_set_t *unicodes; + hb_set_t *glyphs; + + /* TODO + * + * features + * lookups + * nameIDs + * ... + */ }; #endif /* HB_SUBSET_PRIVATE_HH */ diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 3851977e1013c31ce15f26272e85d4343aafef97..e7f2d912c730a57db28106552e3331bfa83cb08f 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -21,14 +21,12 @@ * 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, Rod Sheeter + * Google Author(s): Garret Rieger, Rod Sheeter, Behdad Esfahbod */ #include "hb-object-private.hh" #include "hb-open-type-private.hh" -#include "hb-private.hh" - #include "hb-subset-glyf.hh" #include "hb-subset-private.hh" #include "hb-subset-plan.hh" @@ -56,7 +54,7 @@ struct hb_subset_profile_t { * * Return value: New profile with default settings. * - * Since: 1.7.5 + * Since: 1.8.0 **/ hb_subset_profile_t * hb_subset_profile_create () @@ -67,7 +65,7 @@ hb_subset_profile_create () /** * hb_subset_profile_destroy: * - * Since: 1.7.5 + * Since: 1.8.0 **/ void hb_subset_profile_destroy (hb_subset_profile_t *profile) @@ -77,48 +75,12 @@ hb_subset_profile_destroy (hb_subset_profile_t *profile) free (profile); } -/** - * hb_subset_input_create: - * - * Return value: New subset input. - * - * Since: 1.7.5 - **/ -hb_subset_input_t * -hb_subset_input_create (hb_set_t *codepoints) -{ - if (unlikely (!codepoints)) - codepoints = hb_set_get_empty(); - - hb_subset_input_t *input = hb_object_create(); - input->codepoints = hb_set_reference(codepoints); - return input; -} - -/** - * hb_subset_input_destroy: - * - * Since: 1.7.5 - **/ -void -hb_subset_input_destroy(hb_subset_input_t *subset_input) -{ - if (!hb_object_destroy (subset_input)) return; - - hb_set_destroy (subset_input->codepoints); - free (subset_input); -} - template static hb_blob_t * _subset (hb_subset_plan_t *plan, hb_face_t *source) { OT::Sanitizer sanitizer; hb_blob_t *source_blob = sanitizer.sanitize (source->reference_table (TableType::tableTag)); - if (unlikely(!source_blob)) { - DEBUG_MSG(SUBSET, nullptr, "Failed to reference table for tag %d", TableType::tableTag); - return nullptr; - } const TableType *table = OT::Sanitizer::lock_instance (source_blob); hb_blob_t *result = table->subset(plan, source); diff --git a/src/hb-subset.h b/src/hb-subset.h index 3eb41de848b2a23a6a25923e7556b5b36e73ea77..de7759b22f9fb4f06ba0cfe206b4e5db709671a6 100644 --- a/src/hb-subset.h +++ b/src/hb-subset.h @@ -47,17 +47,27 @@ hb_subset_profile_destroy (hb_subset_profile_t *profile); /* * hb_subset_input_t + * * Things that change based on the input. Characters to keep, etc. */ typedef struct hb_subset_input_t hb_subset_input_t; HB_EXTERN hb_subset_input_t * -hb_subset_input_create (hb_set_t *codepoints); +hb_subset_input_create_or_fail (void); + +HB_EXTERN hb_subset_input_t * +hb_subset_input_reference (hb_subset_input_t *subset_input); HB_EXTERN void hb_subset_input_destroy (hb_subset_input_t *subset_input); +HB_EXTERN hb_set_t * +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_subset() */ diff --git a/test/api/test-set.c b/test/api/test-set.c index bbea2cf5a39fe8c775f4d8031aefea63cc63937c..60e11d98185e70896298abf543ce1145d8187af3 100644 --- a/test/api/test-set.c +++ b/test/api/test-set.c @@ -32,25 +32,33 @@ static void test_empty (hb_set_t *s) { - hb_codepoint_t next = HB_SET_VALUE_INVALID; + hb_codepoint_t next; g_assert_cmpint (hb_set_get_population (s), ==, 0); g_assert_cmpint (hb_set_get_min (s), ==, HB_SET_VALUE_INVALID); g_assert_cmpint (hb_set_get_max (s), ==, HB_SET_VALUE_INVALID); g_assert (!hb_set_has (s, 13)); + next = 53043; g_assert (!hb_set_next (s, &next)); g_assert_cmpint (next, ==, HB_SET_VALUE_INVALID); + next = 07734; + g_assert (!hb_set_previous (s, &next)); + g_assert_cmpint (next, ==, HB_SET_VALUE_INVALID); g_assert (hb_set_is_empty (s)); } static void test_not_empty (hb_set_t *s) { - hb_codepoint_t next = HB_SET_VALUE_INVALID; + hb_codepoint_t next; g_assert_cmpint (hb_set_get_population (s), !=, 0); g_assert_cmpint (hb_set_get_min (s), !=, HB_SET_VALUE_INVALID); g_assert_cmpint (hb_set_get_max (s), !=, HB_SET_VALUE_INVALID); + next = HB_SET_VALUE_INVALID; g_assert (hb_set_next (s, &next)); g_assert_cmpint (next, !=, HB_SET_VALUE_INVALID); + next = HB_SET_VALUE_INVALID; + g_assert (hb_set_previous (s, &next)); + g_assert_cmpint (next, !=, HB_SET_VALUE_INVALID); } static void @@ -271,6 +279,27 @@ test_set_iter (void) g_assert (!hb_set_next (s, &next)); g_assert_cmpint (next, ==, HB_SET_VALUE_INVALID); + next = HB_SET_VALUE_INVALID; + g_assert (hb_set_previous (s, &next)); + g_assert_cmpint (next, ==, 20005); + g_assert (hb_set_previous (s, &next)); + g_assert_cmpint (next, ==, 1200); + g_assert (hb_set_previous (s, &next)); + g_assert_cmpint (next, ==, 1100); + g_assert (hb_set_previous (s, &next)); + g_assert_cmpint (next, ==, 15); + g_assert (hb_set_previous (s, &next)); + g_assert (hb_set_previous (s, &next)); + g_assert_cmpint (next, ==, 13); + g_assert (hb_set_previous (s, &next)); + g_assert (hb_set_previous (s, &next)); + g_assert (hb_set_previous (s, &next)); + g_assert_cmpint (next, ==, 10); + g_assert (hb_set_previous (s, &next)); + g_assert_cmpint (next, ==, 6); + g_assert (!hb_set_previous (s, &next)); + g_assert_cmpint (next, ==, HB_SET_VALUE_INVALID); + first = last = HB_SET_VALUE_INVALID; g_assert (hb_set_next_range (s, &first, &last)); g_assert_cmpint (first, ==, 6); @@ -291,6 +320,26 @@ test_set_iter (void) g_assert_cmpint (first, ==, HB_SET_VALUE_INVALID); g_assert_cmpint (last, ==, HB_SET_VALUE_INVALID); + first = last = HB_SET_VALUE_INVALID; + g_assert (hb_set_previous_range (s, &first, &last)); + g_assert_cmpint (first, ==, 20005); + g_assert_cmpint (last, ==, 20005); + g_assert (hb_set_previous_range (s, &first, &last)); + g_assert_cmpint (first, ==, 1200); + g_assert_cmpint (last, ==, 1200); + g_assert (hb_set_previous_range (s, &first, &last)); + g_assert_cmpint (first, ==, 1100); + g_assert_cmpint (last, ==, 1100); + g_assert (hb_set_previous_range (s, &first, &last)); + g_assert_cmpint (first, ==, 10); + g_assert_cmpint (last, ==, 15); + g_assert (hb_set_previous_range (s, &first, &last)); + g_assert_cmpint (first, ==, 6); + g_assert_cmpint (last, ==, 6); + g_assert (!hb_set_previous_range (s, &first, &last)); + g_assert_cmpint (first, ==, HB_SET_VALUE_INVALID); + g_assert_cmpint (last, ==, HB_SET_VALUE_INVALID); + hb_set_destroy (s); } diff --git a/util/hb-subset.cc b/util/hb-subset.cc index a3505a8143d3f00f9511b50263031ff7a0d13870..ea657affe32bd52b18664d40725f4685775387b8 100644 --- a/util/hb-subset.cc +++ b/util/hb-subset.cc @@ -37,13 +37,13 @@ struct subset_consumer_t { subset_consumer_t (option_parser_t *parser) - : failed (false), options (parser), font (nullptr), codepoints (nullptr) {} + : failed (false), options (parser), font (nullptr), input (nullptr) {} void init (hb_buffer_t *buffer_, const font_options_t *font_opts) { font = hb_font_reference (font_opts->get_font ()); - codepoints = hb_set_create(); + input = hb_subset_input_create_or_fail (); } void consume_line (const char *text, @@ -51,14 +51,13 @@ struct subset_consumer_t const char *text_before, const char *text_after) { - // text appears to be a g_string when set by --unicodes - // TODO(Q1) are gunichar and hbcodepoint_t interchangeable? // TODO(Q1) does this only get called with at least 1 codepoint? + hb_set_t *codepoints = hb_subset_input_unicode_set (input); gchar *c = (gchar *)text; do { gunichar cp = g_utf8_get_char(c); - hb_codepoint_t hb_cp = cp; // TODO(Q1) is this safe? - hb_set_add(codepoints, hb_cp); + hb_codepoint_t hb_cp = cp; + hb_set_add (codepoints, hb_cp); } while ((c = g_utf8_find_next_char(c, text + text_len)) != nullptr); } @@ -90,12 +89,10 @@ struct subset_consumer_t void finish (const font_options_t *font_opts) { - // TODO(Q1) check for errors from creates and such hb_subset_profile_t *subset_profile = hb_subset_profile_create(); - hb_subset_input_t *subset_input = hb_subset_input_create (codepoints); hb_face_t *face = hb_font_get_face (font); - hb_face_t *new_face = hb_subset(face, subset_profile, subset_input); + hb_face_t *new_face = hb_subset(face, subset_profile, input); hb_blob_t *result = hb_face_reference_blob (new_face); failed = !hb_blob_get_length (result); @@ -103,8 +100,7 @@ struct subset_consumer_t write_file (options.output_file, result); hb_subset_profile_destroy (subset_profile); - hb_subset_input_destroy (subset_input); - hb_set_destroy (codepoints); + hb_subset_input_destroy (input); hb_blob_destroy (result); hb_face_destroy (new_face); hb_font_destroy (font); @@ -116,7 +112,7 @@ struct subset_consumer_t private: output_options_t options; hb_font_t *font; - hb_set_t *codepoints; + hb_subset_input_t *input; }; int