提交 d008b628 编写于 作者: G Garret Rieger

Merge remote-tracking branch 'upstream/master' into fixed

...@@ -13,6 +13,7 @@ env: ...@@ -13,6 +13,7 @@ env:
- NOCONFIGURE=1 - NOCONFIGURE=1
# COVERITY_SCAN_TOKEN # COVERITY_SCAN_TOKEN
- secure: "MRJtVu/fQoWNwMAamvIJBCX/1SMvEuEUk/ljAif/y2/3syyWgxFGp17UGnDILdoZYyCqTM+jQciY2P0nVqbjjOAUlML4QOAalqw8kPp8iTsnHUe+KOMVrOVP6p6qAQxk1im1O41cCMkmVKvk+NXe/on5euz6LGF2laHZaOAMoes=" - secure: "MRJtVu/fQoWNwMAamvIJBCX/1SMvEuEUk/ljAif/y2/3syyWgxFGp17UGnDILdoZYyCqTM+jQciY2P0nVqbjjOAUlML4QOAalqw8kPp8iTsnHUe+KOMVrOVP6p6qAQxk1im1O41cCMkmVKvk+NXe/on5euz6LGF2laHZaOAMoes="
- PROJECT_NAME="behdad/harfbuzz" # the project name on coverity
matrix: matrix:
include: include:
......
...@@ -57,11 +57,12 @@ m4_define([hb_libtool_current], ...@@ -57,11 +57,12 @@ m4_define([hb_libtool_current],
HB_LIBTOOL_VERSION_INFO=hb_libtool_current:hb_libtool_revision:hb_libtool_age HB_LIBTOOL_VERSION_INFO=hb_libtool_current:hb_libtool_revision:hb_libtool_age
AC_SUBST(HB_LIBTOOL_VERSION_INFO) AC_SUBST(HB_LIBTOOL_VERSION_INFO)
AC_ARG_WITH([stdcpp], AC_ARG_WITH([libstdc++],
[AS_HELP_STRING([--with-stdcpp], [AS_HELP_STRING([--with-libstdc++=@<:@yes/no@:>@],
[Do not try suppressing linkage to libstdcpp])],, [Allow linking with libstdc++ @<:@default=no@:>@])],
[with_stdcpp=no]) [with_libstdcxx=$withval],
AM_CONDITIONAL(WITHSTDCPP, [test "x$with_stdcpp" = "xyes"]) [with_libstdcxx=no])
AM_CONDITIONAL(WITH_LIBSTDCXX, [test "x$with_libstdcxx" = "xyes"])
# Documentation # Documentation
have_gtk_doc=false have_gtk_doc=false
......
...@@ -9,6 +9,7 @@ HB_EXTERN ...@@ -9,6 +9,7 @@ HB_EXTERN
<FILE>hb-blob</FILE> <FILE>hb-blob</FILE>
hb_blob_create hb_blob_create
hb_blob_create_sub_blob hb_blob_create_sub_blob
hb_blob_copy_writable_or_fail
hb_blob_destroy hb_blob_destroy
hb_blob_get_data hb_blob_get_data
hb_blob_get_data_writable hb_blob_get_data_writable
...@@ -527,7 +528,9 @@ hb_set_intersect ...@@ -527,7 +528,9 @@ hb_set_intersect
hb_set_is_empty hb_set_is_empty
hb_set_is_equal hb_set_is_equal
hb_set_next hb_set_next
hb_set_previous
hb_set_next_range hb_set_next_range
hb_set_previous_range
hb_set_reference hb_set_reference
hb_set_set hb_set_set
hb_set_set_user_data hb_set_set_user_data
......
...@@ -9,6 +9,8 @@ CLEANFILES = ...@@ -9,6 +9,8 @@ CLEANFILES =
DISTCLEANFILES = DISTCLEANFILES =
MAINTAINERCLEANFILES = MAINTAINERCLEANFILES =
DISTCHECK_CONFIGURE_FLAGS = --enable-introspection DISTCHECK_CONFIGURE_FLAGS = --enable-introspection
TESTS =
check_PROGRAMS =
# The following warning options are useful for debugging: -Wpadded # The following warning options are useful for debugging: -Wpadded
#AM_CXXFLAGS = #AM_CXXFLAGS =
...@@ -30,12 +32,13 @@ HBSOURCES += $(HB_BASE_RAGEL_GENERATED_sources) ...@@ -30,12 +32,13 @@ HBSOURCES += $(HB_BASE_RAGEL_GENERATED_sources)
HBHEADERS = $(HB_BASE_headers) HBHEADERS = $(HB_BASE_headers)
HBNODISTHEADERS = $(HB_NODIST_headers) HBNODISTHEADERS = $(HB_NODIST_headers)
if !WITHSTDCPP if WITH_LIBSTDCXX
HBNOLIBCXXCFLAGS =
else
# Make sure we don't link to libstdc++ # Make sure we don't link to libstdc++
HBCFLAGS += -fno-rtti -fno-exceptions # No threadsafe statics in C++ as we do it ourselves
HBNOLIBCXXFLAGS = -fno-threadsafe-statics -fno-rtti -fno-exceptions
# No threadsafe statics and C++ as we do it ourselves HBLIBCXXFLAGS = -fno-threadsafe-statics
HBCFLAGS += -fno-threadsafe-statics
endif endif
if HAVE_OT if HAVE_OT
...@@ -126,27 +129,24 @@ export_symbols_icu = -export-symbols harfbuzz-icu.def ...@@ -126,27 +129,24 @@ export_symbols_icu = -export-symbols harfbuzz-icu.def
harfbuzz_icu_def_dependency = harfbuzz-icu.def harfbuzz_icu_def_dependency = harfbuzz-icu.def
export_symbols_subset = -export-symbols harfbuzz-subset.def export_symbols_subset = -export-symbols harfbuzz-subset.def
harfbuzz_subset_def_dependency = harfbuzz-subset.def harfbuzz_subset_def_dependency = harfbuzz-subset.def
choosed_linker = $(CXXLINK) chosen_linker = $(CXXLINK)
else else
if WITHSTDCPP if WITH_LIBSTDCXX
choosed_linker = $(CXXLINK) chosen_linker = $(CXXLINK)
else else
if HAVE_GCC if HAVE_GCC
# Use a C linker for GCC, not C++; Don't link to libstdc++ # Use a C linker for GCC, not C++; Don't link to libstdc++
choosed_linker = $(LINK) chosen_linker = $(LINK)
else else
choosed_linker = $(CXXLINK) chosen_linker = $(CXXLINK)
endif endif
endif 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 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_SOURCES = $(HBSOURCES) $(HBHEADERS) $(HBNODISTHEADERS)
libharfbuzz_la_CPPFLAGS = $(HBCFLAGS) libharfbuzz_la_CPPFLAGS = $(HBCFLAGS) $(HBNOLIBCXXFLAGS)
libharfbuzz_la_LDFLAGS = $(base_link_flags) $(export_symbols) libharfbuzz_la_LDFLAGS = $(base_link_flags) $(export_symbols)
libharfbuzz_la_LIBADD = $(HBLIBS) libharfbuzz_la_LIBADD = $(HBLIBS)
EXTRA_libharfbuzz_la_DEPENDENCIES = $(harfbuzz_def_dependency) EXTRA_libharfbuzz_la_DEPENDENCIES = $(harfbuzz_def_dependency)
...@@ -158,7 +158,7 @@ EXTRA_DIST += harfbuzz.pc.in ...@@ -158,7 +158,7 @@ EXTRA_DIST += harfbuzz.pc.in
lib_LTLIBRARIES += libharfbuzz-subset.la lib_LTLIBRARIES += libharfbuzz-subset.la
libharfbuzz_subset_la_SOURCES = $(HB_SUBSET_sources) 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_LDFLAGS = $(base_link_flags) $(export_symbols_subset)
libharfbuzz_subset_la_LIBADD = libharfbuzz.la libharfbuzz_subset_la_LIBADD = libharfbuzz.la
EXTRA_libharfbuzz_subset_la_DEPENDENCIES = $(harfbuzz_subset_def_dependency) EXTRA_libharfbuzz_subset_la_DEPENDENCIES = $(harfbuzz_subset_def_dependency)
...@@ -178,9 +178,9 @@ FUZZING_CPPFLAGS = \ ...@@ -178,9 +178,9 @@ FUZZING_CPPFLAGS = \
-DHB_BUFFER_MAX_OPS_DEFAULT=1024 \ -DHB_BUFFER_MAX_OPS_DEFAULT=1024 \
$(NULL) $(NULL)
EXTRA_LTLIBRARIES = libharfbuzz-fuzzing.la 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_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_LDFLAGS = $(AM_LDFLAGS)
libharfbuzz_fuzzing_la_LIBADD = $(libharfbuzz_la_LIBADD) libharfbuzz_fuzzing_la_LIBADD = $(libharfbuzz_la_LIBADD)
EXTRA_libharfbuzz_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_la_DEPENDENCIES) EXTRA_libharfbuzz_fuzzing_la_DEPENDENCIES = $(EXTRA_libharfbuzz_la_DEPENDENCIES)
...@@ -195,7 +195,7 @@ HBHEADERS += $(HB_ICU_headers) ...@@ -195,7 +195,7 @@ HBHEADERS += $(HB_ICU_headers)
else else
lib_LTLIBRARIES += libharfbuzz-icu.la lib_LTLIBRARIES += libharfbuzz-icu.la
libharfbuzz_icu_la_SOURCES = $(HB_ICU_sources) 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_LDFLAGS = $(base_link_flags) $(export_symbols_icu)
libharfbuzz_icu_la_LIBADD = $(ICU_LIBS) libharfbuzz.la libharfbuzz_icu_la_LIBADD = $(ICU_LIBS) libharfbuzz.la
EXTRA_libharfbuzz_icu_la_DEPENDENCIES = $(harfbuzz_icu_def_dependency) EXTRA_libharfbuzz_icu_la_DEPENDENCIES = $(harfbuzz_icu_def_dependency)
...@@ -207,11 +207,11 @@ EXTRA_DIST += harfbuzz-icu.pc.in ...@@ -207,11 +207,11 @@ EXTRA_DIST += harfbuzz-icu.pc.in
if HAVE_GOBJECT if HAVE_GOBJECT
lib_LTLIBRARIES += libharfbuzz-gobject.la 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) libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_sources)
nodist_libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_ENUM_sources) nodist_libharfbuzz_gobject_la_SOURCES = $(HB_GOBJECT_ENUM_sources)
libharfbuzz_gobject_la_CPPFLAGS = $(libharfbuzz_la_CPPFLAGS) $(GOBJECT_CFLAGS) libharfbuzz_gobject_la_CPPFLAGS = $(HBCFLAGS) $(HBNOLIBCXXFLAGS) $(GOBJECT_CFLAGS)
libharfbuzz_gobject_la_LDFLAGS = $(libharfbuzz_la_LDFLAGS) libharfbuzz_gobject_la_LDFLAGS = $(base_link_flags)
libharfbuzz_gobject_la_LIBADD = $(GOBJECT_LIBS) libharfbuzz.la libharfbuzz_gobject_la_LIBADD = $(GOBJECT_LIBS) libharfbuzz.la
pkginclude_HEADERS += $(HB_GOBJECT_headers) pkginclude_HEADERS += $(HB_GOBJECT_headers)
nodist_pkginclude_HEADERS += $(HB_GOBJECT_ENUM_headers) nodist_pkginclude_HEADERS += $(HB_GOBJECT_ENUM_headers)
...@@ -340,19 +340,42 @@ dist_check_SCRIPTS = \ ...@@ -340,19 +340,42 @@ dist_check_SCRIPTS = \
check-externs.sh \ check-externs.sh \
check-header-guards.sh \ check-header-guards.sh \
check-includes.sh \ check-includes.sh \
check-libstdc++.sh \
check-static-inits.sh \ check-static-inits.sh \
check-symbols.sh \ check-symbols.sh \
$(NULL) $(NULL)
TESTS += $(dist_check_SCRIPTS)
if !WITH_LIBSTDCXX
dist_check_SCRIPTS += \
check-libstdc++.sh \
$(NULL)
endif
check_PROGRAMS = \ check_PROGRAMS += \
test-ot-tag \ dump-indic-data \
dump-khmer-data \
dump-myanmar-data \
dump-use-data \
$(NULL) $(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_SOURCES = hb-ot-tag.cc
test_ot_tag_CPPFLAGS = $(HBCFLAGS) -DMAIN test_ot_tag_CPPFLAGS = $(HBCFLAGS) -DMAIN
test_ot_tag_LDADD = libharfbuzz.la $(HBLIBS) test_ot_tag_LDADD = libharfbuzz.la $(HBLIBS)
TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS)
TESTS_ENVIRONMENT = \ TESTS_ENVIRONMENT = \
srcdir="$(srcdir)" \ srcdir="$(srcdir)" \
MAKE="$(MAKE) $(AM_MAKEFLAGS)" \ MAKE="$(MAKE) $(AM_MAKEFLAGS)" \
......
...@@ -109,7 +109,9 @@ HB_OT_sources = \ ...@@ -109,7 +109,9 @@ HB_OT_sources = \
hb-ot-shape-complex-indic.cc \ hb-ot-shape-complex-indic.cc \
hb-ot-shape-complex-indic-private.hh \ hb-ot-shape-complex-indic-private.hh \
hb-ot-shape-complex-indic-table.cc \ hb-ot-shape-complex-indic-table.cc \
hb-ot-shape-complex-khmer-private.hh \
hb-ot-shape-complex-khmer.cc \ hb-ot-shape-complex-khmer.cc \
hb-ot-shape-complex-myanmar-private.hh \
hb-ot-shape-complex-myanmar.cc \ hb-ot-shape-complex-myanmar.cc \
hb-ot-shape-complex-thai.cc \ hb-ot-shape-complex-thai.cc \
hb-ot-shape-complex-tibetan.cc \ hb-ot-shape-complex-tibetan.cc \
...@@ -185,6 +187,7 @@ HB_ICU_headers = hb-icu.h ...@@ -185,6 +187,7 @@ HB_ICU_headers = hb-icu.h
HB_SUBSET_sources = \ HB_SUBSET_sources = \
hb-subset.cc \ hb-subset.cc \
hb-subset-glyf.cc \ hb-subset-glyf.cc \
hb-subset-input.cc \
hb-subset-plan.cc \ hb-subset-plan.cc \
$(NULL) $(NULL)
......
...@@ -22,7 +22,8 @@ fi ...@@ -22,7 +22,8 @@ fi
tested=false tested=false
# harfbuzz-icu links to libstdc++ because icu does. # 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 for suffix in so dylib; do
so=$libs/lib$soname.$suffix so=$libs/lib$soname.$suffix
if ! test -f "$so"; then continue; fi if ! test -f "$so"; then continue; fi
......
/*
* 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());
}
}
/*
* 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());
}
}
/*
* 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());
}
}
/*
* 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);
}
}
...@@ -449,7 +449,7 @@ page_bits = 12 ...@@ -449,7 +449,7 @@ page_bits = 12
print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy) print "}; /* Table items: %d; occupancy: %d%% */" % (offset, occupancy)
print print
print "USE_TABLE_ELEMENT_TYPE" 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 "{"
print " switch (u >> %d)" % page_bits print " switch (u >> %d)" % page_bits
print " {" print " {"
......
...@@ -40,6 +40,8 @@ using namespace OT; ...@@ -40,6 +40,8 @@ using namespace OT;
struct RearrangementSubtable struct RearrangementSubtable
{ {
typedef void EntryData;
struct driver_context_t struct driver_context_t
{ {
static const bool in_place = true; static const bool in_place = true;
...@@ -60,13 +62,13 @@ struct RearrangementSubtable ...@@ -60,13 +62,13 @@ struct RearrangementSubtable
ret (false), ret (false),
start (0), end (0) {} start (0), end (0) {}
inline bool is_actionable (StateTableDriver<void> *driver, inline bool is_actionable (StateTableDriver<EntryData> *driver,
const Entry<void> *entry) const Entry<EntryData> *entry)
{ {
return (entry->flags & Verb) && start < end; return (entry->flags & Verb) && start < end;
} }
inline bool transition (StateTableDriver<void> *driver, inline bool transition (StateTableDriver<EntryData> *driver,
const Entry<void> *entry) const Entry<EntryData> *entry)
{ {
hb_buffer_t *buffer = driver->buffer; hb_buffer_t *buffer = driver->buffer;
unsigned int flags = entry->flags; unsigned int flags = entry->flags;
...@@ -169,7 +171,7 @@ struct RearrangementSubtable ...@@ -169,7 +171,7 @@ struct RearrangementSubtable
} }
protected: protected:
StateTable<void> machine; StateTable<EntryData> machine;
public: public:
DEFINE_SIZE_STATIC (16); DEFINE_SIZE_STATIC (16);
}; };
......
...@@ -170,6 +170,31 @@ hb_blob_create_sub_blob (hb_blob_t *parent, ...@@ -170,6 +170,31 @@ hb_blob_create_sub_blob (hb_blob_t *parent,
return blob; 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: * hb_blob_get_empty:
* *
......
...@@ -82,6 +82,9 @@ hb_blob_create_sub_blob (hb_blob_t *parent, ...@@ -82,6 +82,9 @@ hb_blob_create_sub_blob (hb_blob_t *parent,
unsigned int offset, unsigned int offset,
unsigned int length); unsigned int length);
HB_EXTERN hb_blob_t *
hb_blob_copy_writable_or_fail (hb_blob_t *blob);
HB_EXTERN hb_blob_t * HB_EXTERN hb_blob_t *
hb_blob_get_empty (void); hb_blob_get_empty (void);
......
...@@ -71,7 +71,6 @@ hb_face_set_user_data (hb_face_t *face, ...@@ -71,7 +71,6 @@ hb_face_set_user_data (hb_face_t *face,
hb_destroy_func_t destroy, hb_destroy_func_t destroy,
hb_bool_t replace); hb_bool_t replace);
HB_EXTERN void * HB_EXTERN void *
hb_face_get_user_data (hb_face_t *face, hb_face_get_user_data (hb_face_t *face,
hb_user_data_key_t *key); hb_user_data_key_t *key);
......
...@@ -377,7 +377,7 @@ struct CBDT ...@@ -377,7 +377,7 @@ struct CBDT
{ {
inline void init (hb_face_t *face) inline void init (hb_face_t *face)
{ {
upem = face->get_upem(); upem = hb_face_get_upem (face);
cblc_blob = Sanitizer<CBLC>().sanitize (face->reference_table (HB_OT_TAG_CBLC)); cblc_blob = Sanitizer<CBLC>().sanitize (face->reference_table (HB_OT_TAG_CBLC));
cbdt_blob = Sanitizer<CBDT>().sanitize (face->reference_table (HB_OT_TAG_CBDT)); cbdt_blob = Sanitizer<CBDT>().sanitize (face->reference_table (HB_OT_TAG_CBDT));
......
...@@ -69,7 +69,7 @@ struct hmtxvmtx ...@@ -69,7 +69,7 @@ struct hmtxvmtx
inline void init (hb_face_t *face, inline void init (hb_face_t *face,
unsigned int default_advance_ = 0) 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; bool got_font_extents = false;
if (T::os2Tag) if (T::os2Tag)
......
...@@ -34,6 +34,11 @@ ...@@ -34,6 +34,11 @@
#include "hb-ot-shape-private.hh" /* XXX Remove */ #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 #define INDIC_TABLE_ELEMENT_TYPE uint16_t
/* Cateories used in the OpenType spec: /* Cateories used in the OpenType spec:
...@@ -77,29 +82,29 @@ enum indic_category_t { ...@@ -77,29 +82,29 @@ enum indic_category_t {
/* Visual positions in a syllable from left to right. */ /* Visual positions in a syllable from left to right. */
enum indic_position_t { enum indic_position_t {
POS_START, POS_START = 0,
POS_RA_TO_BECOME_REPH, POS_RA_TO_BECOME_REPH = 1,
POS_PRE_M, POS_PRE_M = 2,
POS_PRE_C, POS_PRE_C = 3,
POS_BASE_C, POS_BASE_C = 4,
POS_AFTER_MAIN, POS_AFTER_MAIN = 5,
POS_ABOVE_C, POS_ABOVE_C = 6,
POS_BEFORE_SUB, POS_BEFORE_SUB = 7,
POS_BELOW_C, POS_BELOW_C = 8,
POS_AFTER_SUB, POS_AFTER_SUB = 9,
POS_BEFORE_POST, POS_BEFORE_POST = 10,
POS_POST_C, POS_POST_C = 11,
POS_AFTER_POST, POS_AFTER_POST = 12,
POS_FINAL_C, POS_FINAL_C = 13,
POS_SMVD, POS_SMVD = 14,
POS_END POS_END = 15
}; };
/* Categories used in IndicSyllabicCategory.txt from UCD. */ /* Categories used in IndicSyllabicCategory.txt from UCD. */
...@@ -186,4 +191,211 @@ enum indic_matra_category_t { ...@@ -186,4 +191,211 @@ enum indic_matra_category_t {
HB_INTERNAL INDIC_TABLE_ELEMENT_TYPE HB_INTERNAL INDIC_TABLE_ELEMENT_TYPE
hb_indic_get_categories (hb_codepoint_t u); 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<hb_codepoint_t> (u, 0x0953u, 0x0954u)))
cat = OT_SM;
/* The following act like consonants. */
else if (unlikely (hb_in_ranges<hb_codepoint_t> (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<hb_codepoint_t> (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<hb_codepoint_t> (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<hb_codepoint_t> (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 */ #endif /* HB_OT_SHAPE_COMPLEX_INDIC_PRIVATE_HH */
...@@ -27,226 +27,12 @@ ...@@ -27,226 +27,12 @@
#include "hb-ot-shape-complex-indic-private.hh" #include "hb-ot-shape-complex-indic-private.hh"
#include "hb-ot-layout-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. * 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<hb_codepoint_t> (u, 0x0953u, 0x0954u)))
cat = OT_SM;
/* The following act like consonants. */
else if (unlikely (hb_in_ranges<hb_codepoint_t> (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<hb_codepoint_t> (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<hb_codepoint_t> (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<hb_codepoint_t> (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 * 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 * behavior in these tables necessarily. This should mainly be used for per-script
......
/*
* 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<hb_codepoint_t> (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<hb_codepoint_t> (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 */
...@@ -24,119 +24,9 @@ ...@@ -24,119 +24,9 @@
* Google Author(s): Behdad Esfahbod * 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" #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<hb_codepoint_t> (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<hb_codepoint_t> (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. * Khmer shaper.
...@@ -404,7 +294,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, ...@@ -404,7 +294,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
/* Mark all subsequent consonants as below. */ /* Mark all subsequent consonants as below. */
for (unsigned int i = base + 1; i < end; i++) 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; info[i].khmer_position() = POS_BELOW_C;
/* Mark final consonants. A final consonant is one appearing after a matra, /* 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, ...@@ -412,7 +302,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
for (unsigned int i = base + 1; i < end; i++) for (unsigned int i = base + 1; i < end; i++)
if (info[i].khmer_category() == OT_M) { if (info[i].khmer_category() == OT_M) {
for (unsigned int j = i + 1; j < end; j++) 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; info[j].khmer_position() = POS_FINAL_C;
break; break;
} }
...@@ -455,7 +345,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan, ...@@ -455,7 +345,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
{ {
unsigned int last = base; unsigned int last = base;
for (unsigned int i = base + 1; i < end; i++) 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++) for (unsigned int j = last + 1; j < i; j++)
if (info[j].khmer_position() < POS_SMVD) if (info[j].khmer_position() < POS_SMVD)
......
/*
* 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<hb_codepoint_t> (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 */
...@@ -24,11 +24,7 @@ ...@@ -24,11 +24,7 @@
* Google Author(s): Behdad Esfahbod * Google Author(s): Behdad Esfahbod
*/ */
#include "hb-ot-shape-complex-indic-private.hh" #include "hb-ot-shape-complex-myanmar-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 */
/* /*
...@@ -127,153 +123,6 @@ enum syllable_type_t { ...@@ -127,153 +123,6 @@ enum syllable_type_t {
#include "hb-ot-shape-complex-myanmar-machine.hh" #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<hb_codepoint_t> (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 static void
setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED, setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer, hb_buffer_t *buffer,
......
...@@ -92,6 +92,6 @@ enum use_category_t { ...@@ -92,6 +92,6 @@ enum use_category_t {
}; };
HB_INTERNAL USE_TABLE_ELEMENT_TYPE 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 */ #endif /* HB_OT_SHAPE_COMPLEX_USE_PRIVATE_HH */
...@@ -690,7 +690,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = { ...@@ -690,7 +690,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
}; /* Table items: 5424; occupancy: 73% */ }; /* Table items: 5424; occupancy: 73% */
USE_TABLE_ELEMENT_TYPE USE_TABLE_ELEMENT_TYPE
hb_use_get_categories (hb_codepoint_t u) hb_use_get_category (hb_codepoint_t u)
{ {
switch (u >> 12) switch (u >> 12)
{ {
......
...@@ -262,7 +262,7 @@ setup_masks_use (const hb_ot_shape_plan_t *plan, ...@@ -262,7 +262,7 @@ setup_masks_use (const hb_ot_shape_plan_t *plan,
unsigned int count = buffer->len; unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info; hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++) 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 static void
...@@ -505,7 +505,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED, ...@@ -505,7 +505,7 @@ insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_glyph_info_t dottedcircle = {0}; hb_glyph_info_t dottedcircle = {0};
if (!font->get_nominal_glyph (0x25CCu, &dottedcircle.codepoint)) if (!font->get_nominal_glyph (0x25CCu, &dottedcircle.codepoint))
return; return;
dottedcircle.use_category() = hb_use_get_categories (0x25CC); dottedcircle.use_category() = hb_use_get_category (0x25CC);
buffer->clear_output (); buffer->clear_output ();
......
...@@ -121,6 +121,33 @@ struct hb_set_t ...@@ -121,6 +121,33 @@ struct hb_set_t
*codepoint = INVALID; *codepoint = INVALID;
return false; 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: found:
*codepoint = i * ELT_BITS + j; *codepoint = i * ELT_BITS + j;
return true; return true;
...@@ -471,12 +498,12 @@ struct hb_set_t ...@@ -471,12 +498,12 @@ struct hb_set_t
page_map_t map = {get_major (*codepoint), 0}; page_map_t map = {get_major (*codepoint), 0};
unsigned int i; unsigned int i;
page_map.bfind (map, &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)) if (pages[page_map[i].index].next (codepoint))
{ {
*codepoint += page_map[i].major * page_t::PAGE_BITS; *codepoint += page_map[i].major * page_t::PAGE_BITS;
return true; return true;
} }
i++; i++;
} }
...@@ -492,6 +519,37 @@ struct hb_set_t ...@@ -492,6 +519,37 @@ struct hb_set_t
*codepoint = INVALID; *codepoint = INVALID;
return false; 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 inline bool next_range (hb_codepoint_t *first, hb_codepoint_t *last) const
{ {
hb_codepoint_t i; hb_codepoint_t i;
...@@ -503,12 +561,31 @@ struct hb_set_t ...@@ -503,12 +561,31 @@ struct hb_set_t
return false; return false;
} }
/* TODO Speed up. */
*last = *first = i; *last = *first = i;
while (next (&i) && i == *last + 1) while (next (&i) && i == *last + 1)
(*last)++; (*last)++;
return true; 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 inline unsigned int get_population (void) const
{ {
......
...@@ -50,6 +50,13 @@ hb_set_create (void) ...@@ -50,6 +50,13 @@ hb_set_create (void)
return set; return set;
} }
static const hb_set_t _hb_set_nil = {
HB_OBJECT_HEADER_STATIC,
true, /* in_error */
{0} /* elts */
};
/** /**
* hb_set_get_empty: * hb_set_get_empty:
* *
...@@ -60,13 +67,6 @@ hb_set_create (void) ...@@ -60,13 +67,6 @@ hb_set_create (void)
hb_set_t * hb_set_t *
hb_set_get_empty (void) 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_t *> (&_hb_set_nil); return const_cast<hb_set_t *> (&_hb_set_nil);
} }
...@@ -437,7 +437,9 @@ hb_set_get_max (const hb_set_t *set) ...@@ -437,7 +437,9 @@ hb_set_get_max (const hb_set_t *set)
* @set: a set. * @set: a set.
* @codepoint: (inout): * @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. * Return value: whether there was a next value.
* *
...@@ -450,6 +452,26 @@ hb_set_next (const hb_set_t *set, ...@@ -450,6 +452,26 @@ hb_set_next (const hb_set_t *set,
return set->next (codepoint); 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: * hb_set_next_range:
* @set: a set. * @set: a set.
...@@ -459,6 +481,8 @@ hb_set_next (const hb_set_t *set, ...@@ -459,6 +481,8 @@ hb_set_next (const hb_set_t *set,
* Gets the next consecutive range of numbers in @set that * Gets the next consecutive range of numbers in @set that
* are greater than current value of @last. * 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. * Return value: whether there was a next range.
* *
* Since: 0.9.7 * Since: 0.9.7
...@@ -470,3 +494,26 @@ hb_set_next_range (const hb_set_t *set, ...@@ -470,3 +494,26 @@ hb_set_next_range (const hb_set_t *set,
{ {
return set->next_range (first, last); 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);
}
...@@ -129,25 +129,36 @@ hb_set_symmetric_difference (hb_set_t *set, ...@@ -129,25 +129,36 @@ hb_set_symmetric_difference (hb_set_t *set,
HB_EXTERN unsigned int HB_EXTERN unsigned int
hb_set_get_population (const hb_set_t *set); 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_EXTERN hb_codepoint_t
hb_set_get_min (const hb_set_t *set); 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_EXTERN hb_codepoint_t
hb_set_get_max (const hb_set_t *set); 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_EXTERN hb_bool_t
hb_set_next (const hb_set_t *set, hb_set_next (const hb_set_t *set,
hb_codepoint_t *codepoint); 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_EXTERN hb_bool_t
hb_set_next_range (const hb_set_t *set, hb_set_next_range (const hb_set_t *set,
hb_codepoint_t *first, hb_codepoint_t *first,
hb_codepoint_t *last); 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 HB_END_DECLS
......
...@@ -38,14 +38,12 @@ _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf, ...@@ -38,14 +38,12 @@ _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf,
{ {
unsigned int total = 0; unsigned int total = 0;
unsigned int count = 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]; hb_codepoint_t next_glyph = glyph_ids[i];
unsigned int start_offset, end_offset; unsigned int start_offset, end_offset;
if (unlikely (!glyf.get_offsets (next_glyph, &start_offset, &end_offset))) { if (unlikely (!glyf.get_offsets (next_glyph, &start_offset, &end_offset)))
*glyf_size = 0; end_offset = start_offset = 0;
*loca_size = sizeof(OT::HBUINT32);
return false;
}
total += end_offset - start_offset; total += end_offset - start_offset;
count++; count++;
...@@ -84,29 +82,21 @@ _write_glyf_and_loca_prime (const OT::glyf::accelerator_t &glyf, ...@@ -84,29 +82,21 @@ _write_glyf_and_loca_prime (const OT::glyf::accelerator_t &glyf,
{ {
char *glyf_prime_data_next = glyf_prime_data; char *glyf_prime_data_next = glyf_prime_data;
hb_codepoint_t new_glyph_id = 0; for (unsigned int i = 0; i < glyph_ids.len; i++)
{
unsigned int current_offset = 0; unsigned int start_offset, end_offset;
unsigned int end_offset = 0; if (unlikely (!glyf.get_offsets (glyph_ids[i], &start_offset, &end_offset)))
for (unsigned int i = 0; i < glyph_ids.len; i++) { end_offset = start_offset = 0;
unsigned int start_offset;
if (unlikely (!glyf.get_offsets (glyph_ids[i], &start_offset, &end_offset))) {
return false;
}
int length = end_offset - start_offset; int length = end_offset - start_offset;
memcpy (glyf_prime_data_next, glyf_data + start_offset, length); 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; glyf_prime_data_next += length;
current_offset += length;
new_glyph_id++;
} }
// Add the last loca entry which doesn't correspond to a specific glyph _write_loca_entry (glyph_ids.len, glyf_prime_data_next - glyf_prime_data, use_short_loca, loca_prime_data);
// but identifies the end of the last glyphs data.
_write_loca_entry (new_glyph_id, current_offset, use_short_loca, loca_prime_data);
return true; return true;
} }
...@@ -134,8 +124,8 @@ _hb_subset_glyf_and_loca (const OT::glyf::accelerator_t &glyf, ...@@ -134,8 +124,8 @@ _hb_subset_glyf_and_loca (const OT::glyf::accelerator_t &glyf,
return false; return false;
} }
char *glyf_prime_data = (char *) calloc (glyf_prime_size, 1); char *glyf_prime_data = (char *) malloc (glyf_prime_size);
char *loca_prime_data = (char *) calloc (loca_prime_size, 1); char *loca_prime_data = (char *) malloc (loca_prime_size);
if (unlikely (!_write_glyf_and_loca_prime (glyf, glyf_data, glyphs_to_retain, if (unlikely (!_write_glyf_and_loca_prime (glyf, glyf_data, glyphs_to_retain,
*use_short_loca, *use_short_loca,
glyf_prime_size, glyf_prime_data, glyf_prime_size, glyf_prime_data,
......
/*
* 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<hb_subset_input_t>();
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;
}
...@@ -155,7 +155,7 @@ hb_subset_plan_create (hb_face_t *face, ...@@ -155,7 +155,7 @@ hb_subset_plan_create (hb_face_t *face,
plan->gids_to_retain.init(); plan->gids_to_retain.init();
plan->gids_to_retain_sorted.init(); plan->gids_to_retain_sorted.init();
_populate_codepoints (input->codepoints, plan->codepoints); _populate_codepoints (input->unicodes, plan->codepoints);
_populate_gids_to_retain (face, _populate_gids_to_retain (face,
plan->codepoints, plan->codepoints,
plan->gids_to_retain, plan->gids_to_retain,
......
...@@ -38,7 +38,16 @@ struct hb_subset_input_t { ...@@ -38,7 +38,16 @@ struct hb_subset_input_t {
hb_object_header_t header; hb_object_header_t header;
ASSERT_POD (); ASSERT_POD ();
hb_set_t *codepoints; hb_set_t *unicodes;
hb_set_t *glyphs;
/* TODO
*
* features
* lookups
* nameIDs
* ...
*/
}; };
#endif /* HB_SUBSET_PRIVATE_HH */ #endif /* HB_SUBSET_PRIVATE_HH */
...@@ -21,14 +21,12 @@ ...@@ -21,14 +21,12 @@
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. * 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-object-private.hh"
#include "hb-open-type-private.hh" #include "hb-open-type-private.hh"
#include "hb-private.hh"
#include "hb-subset-glyf.hh" #include "hb-subset-glyf.hh"
#include "hb-subset-private.hh" #include "hb-subset-private.hh"
#include "hb-subset-plan.hh" #include "hb-subset-plan.hh"
...@@ -56,7 +54,7 @@ struct hb_subset_profile_t { ...@@ -56,7 +54,7 @@ struct hb_subset_profile_t {
* *
* Return value: New profile with default settings. * Return value: New profile with default settings.
* *
* Since: 1.7.5 * Since: 1.8.0
**/ **/
hb_subset_profile_t * hb_subset_profile_t *
hb_subset_profile_create () hb_subset_profile_create ()
...@@ -67,7 +65,7 @@ hb_subset_profile_create () ...@@ -67,7 +65,7 @@ hb_subset_profile_create ()
/** /**
* hb_subset_profile_destroy: * hb_subset_profile_destroy:
* *
* Since: 1.7.5 * Since: 1.8.0
**/ **/
void void
hb_subset_profile_destroy (hb_subset_profile_t *profile) hb_subset_profile_destroy (hb_subset_profile_t *profile)
...@@ -77,48 +75,12 @@ hb_subset_profile_destroy (hb_subset_profile_t *profile) ...@@ -77,48 +75,12 @@ hb_subset_profile_destroy (hb_subset_profile_t *profile)
free (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<hb_subset_input_t>();
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<typename TableType> template<typename TableType>
static hb_blob_t * static hb_blob_t *
_subset (hb_subset_plan_t *plan, hb_face_t *source) _subset (hb_subset_plan_t *plan, hb_face_t *source)
{ {
OT::Sanitizer<TableType> sanitizer; OT::Sanitizer<TableType> sanitizer;
hb_blob_t *source_blob = sanitizer.sanitize (source->reference_table (TableType::tableTag)); 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<TableType>::lock_instance (source_blob); const TableType *table = OT::Sanitizer<TableType>::lock_instance (source_blob);
hb_blob_t *result = table->subset(plan, source); hb_blob_t *result = table->subset(plan, source);
......
...@@ -47,17 +47,27 @@ hb_subset_profile_destroy (hb_subset_profile_t *profile); ...@@ -47,17 +47,27 @@ hb_subset_profile_destroy (hb_subset_profile_t *profile);
/* /*
* hb_subset_input_t * hb_subset_input_t
*
* Things that change based on the input. Characters to keep, etc. * Things that change based on the input. Characters to keep, etc.
*/ */
typedef struct hb_subset_input_t hb_subset_input_t; typedef struct hb_subset_input_t hb_subset_input_t;
HB_EXTERN 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_EXTERN void
hb_subset_input_destroy (hb_subset_input_t *subset_input); 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() */ /* hb_subset() */
......
...@@ -32,25 +32,33 @@ ...@@ -32,25 +32,33 @@
static void static void
test_empty (hb_set_t *s) 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_population (s), ==, 0);
g_assert_cmpint (hb_set_get_min (s), ==, HB_SET_VALUE_INVALID); 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_cmpint (hb_set_get_max (s), ==, HB_SET_VALUE_INVALID);
g_assert (!hb_set_has (s, 13)); g_assert (!hb_set_has (s, 13));
next = 53043;
g_assert (!hb_set_next (s, &next)); g_assert (!hb_set_next (s, &next));
g_assert_cmpint (next, ==, HB_SET_VALUE_INVALID); 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)); g_assert (hb_set_is_empty (s));
} }
static void static void
test_not_empty (hb_set_t *s) 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_population (s), !=, 0);
g_assert_cmpint (hb_set_get_min (s), !=, HB_SET_VALUE_INVALID); 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_cmpint (hb_set_get_max (s), !=, HB_SET_VALUE_INVALID);
next = HB_SET_VALUE_INVALID;
g_assert (hb_set_next (s, &next)); g_assert (hb_set_next (s, &next));
g_assert_cmpint (next, !=, HB_SET_VALUE_INVALID); 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 static void
...@@ -271,6 +279,27 @@ test_set_iter (void) ...@@ -271,6 +279,27 @@ test_set_iter (void)
g_assert (!hb_set_next (s, &next)); g_assert (!hb_set_next (s, &next));
g_assert_cmpint (next, ==, HB_SET_VALUE_INVALID); 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; first = last = HB_SET_VALUE_INVALID;
g_assert (hb_set_next_range (s, &first, &last)); g_assert (hb_set_next_range (s, &first, &last));
g_assert_cmpint (first, ==, 6); g_assert_cmpint (first, ==, 6);
...@@ -291,6 +320,26 @@ test_set_iter (void) ...@@ -291,6 +320,26 @@ test_set_iter (void)
g_assert_cmpint (first, ==, HB_SET_VALUE_INVALID); g_assert_cmpint (first, ==, HB_SET_VALUE_INVALID);
g_assert_cmpint (last, ==, 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); hb_set_destroy (s);
} }
......
...@@ -37,13 +37,13 @@ ...@@ -37,13 +37,13 @@
struct subset_consumer_t struct subset_consumer_t
{ {
subset_consumer_t (option_parser_t *parser) 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_, void init (hb_buffer_t *buffer_,
const font_options_t *font_opts) const font_options_t *font_opts)
{ {
font = hb_font_reference (font_opts->get_font ()); 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, void consume_line (const char *text,
...@@ -51,14 +51,13 @@ struct subset_consumer_t ...@@ -51,14 +51,13 @@ struct subset_consumer_t
const char *text_before, const char *text_before,
const char *text_after) 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? // 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; gchar *c = (gchar *)text;
do { do {
gunichar cp = g_utf8_get_char(c); gunichar cp = g_utf8_get_char(c);
hb_codepoint_t hb_cp = cp; // TODO(Q1) is this safe? hb_codepoint_t hb_cp = cp;
hb_set_add(codepoints, hb_cp); hb_set_add (codepoints, hb_cp);
} while ((c = g_utf8_find_next_char(c, text + text_len)) != nullptr); } while ((c = g_utf8_find_next_char(c, text + text_len)) != nullptr);
} }
...@@ -90,12 +89,10 @@ struct subset_consumer_t ...@@ -90,12 +89,10 @@ struct subset_consumer_t
void finish (const font_options_t *font_opts) 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_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 *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); hb_blob_t *result = hb_face_reference_blob (new_face);
failed = !hb_blob_get_length (result); failed = !hb_blob_get_length (result);
...@@ -103,8 +100,7 @@ struct subset_consumer_t ...@@ -103,8 +100,7 @@ struct subset_consumer_t
write_file (options.output_file, result); write_file (options.output_file, result);
hb_subset_profile_destroy (subset_profile); hb_subset_profile_destroy (subset_profile);
hb_subset_input_destroy (subset_input); hb_subset_input_destroy (input);
hb_set_destroy (codepoints);
hb_blob_destroy (result); hb_blob_destroy (result);
hb_face_destroy (new_face); hb_face_destroy (new_face);
hb_font_destroy (font); hb_font_destroy (font);
...@@ -116,7 +112,7 @@ struct subset_consumer_t ...@@ -116,7 +112,7 @@ struct subset_consumer_t
private: private:
output_options_t options; output_options_t options;
hb_font_t *font; hb_font_t *font;
hb_set_t *codepoints; hb_subset_input_t *input;
}; };
int int
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册