Merge remote-tracking branch 'upstream/master' into fixed
This commit is contained in:
commit
d008b62887
@ -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:
|
||||
|
11
configure.ac
11
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
|
||||
|
@ -9,6 +9,7 @@ HB_EXTERN
|
||||
<FILE>hb-blob</FILE>
|
||||
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
|
||||
|
@ -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)
|
||||
|
||||
check_PROGRAMS = \
|
||||
test-ot-tag \
|
||||
if !WITH_LIBSTDCXX
|
||||
dist_check_SCRIPTS += \
|
||||
check-libstdc++.sh \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
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)" \
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
43
src/dump-indic-data.cc
Normal file
43
src/dump-indic-data.cc
Normal file
@ -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());
|
||||
}
|
||||
}
|
43
src/dump-khmer-data.cc
Normal file
43
src/dump-khmer-data.cc
Normal file
@ -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());
|
||||
}
|
||||
}
|
43
src/dump-myanmar-data.cc
Normal file
43
src/dump-myanmar-data.cc
Normal file
@ -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());
|
||||
}
|
||||
}
|
38
src/dump-use-data.cc
Normal file
38
src/dump-use-data.cc
Normal file
@ -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);
|
||||
}
|
||||
}
|
@ -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 " {"
|
||||
|
@ -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<void> *driver,
|
||||
const Entry<void> *entry)
|
||||
inline bool is_actionable (StateTableDriver<EntryData> *driver,
|
||||
const Entry<EntryData> *entry)
|
||||
{
|
||||
return (entry->flags & Verb) && start < end;
|
||||
}
|
||||
inline bool transition (StateTableDriver<void> *driver,
|
||||
const Entry<void> *entry)
|
||||
inline bool transition (StateTableDriver<EntryData> *driver,
|
||||
const Entry<EntryData> *entry)
|
||||
{
|
||||
hb_buffer_t *buffer = driver->buffer;
|
||||
unsigned int flags = entry->flags;
|
||||
@ -169,7 +171,7 @@ struct RearrangementSubtable
|
||||
}
|
||||
|
||||
protected:
|
||||
StateTable<void> machine;
|
||||
StateTable<EntryData> machine;
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (16);
|
||||
};
|
||||
|
@ -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:
|
||||
*
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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<CBLC>().sanitize (face->reference_table (HB_OT_TAG_CBLC));
|
||||
cbdt_blob = Sanitizer<CBDT>().sanitize (face->reference_table (HB_OT_TAG_CBDT));
|
||||
|
@ -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)
|
||||
|
@ -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<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 */
|
||||
|
@ -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<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
|
||||
* behavior in these tables necessarily. This should mainly be used for per-script
|
||||
|
124
src/hb-ot-shape-complex-khmer-private.hh
Normal file
124
src/hb-ot-shape-complex-khmer-private.hh
Normal file
@ -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<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 @@
|
||||
* 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<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.
|
||||
@ -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)
|
||||
|
171
src/hb-ot-shape-complex-myanmar-private.hh
Normal file
171
src/hb-ot-shape-complex-myanmar-private.hh
Normal file
@ -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<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 @@
|
||||
* 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<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
|
||||
setup_masks_myanmar (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
||||
hb_buffer_t *buffer,
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 ();
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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_t *> (&_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);
|
||||
}
|
||||
|
19
src/hb-set.h
19
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
|
||||
|
||||
|
@ -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,
|
||||
|
107
src/hb-subset-input.cc
Normal file
107
src/hb-subset-input.cc
Normal file
@ -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<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,
|
||||
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,
|
||||
|
@ -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 */
|
||||
|
@ -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<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>
|
||||
static hb_blob_t *
|
||||
_subset (hb_subset_plan_t *plan, hb_face_t *source)
|
||||
{
|
||||
OT::Sanitizer<TableType> 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<TableType>::lock_instance (source_blob);
|
||||
hb_blob_t *result = table->subset(plan, source);
|
||||
|
||||
|
@ -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() */
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user