Merge branch 'master' of https://github.com/harfbuzz/harfbuzz into glyf

This commit is contained in:
Rod Sheeter 2019-05-16 15:14:01 -07:00
commit 82bbec3063
105 changed files with 4706 additions and 4790 deletions

View File

@ -213,17 +213,17 @@ jobs:
- run: CTEST_OUTPUT_ON_FAILURE=1 ninja -Cbuild test
- run: ninja -Cbuild install
cmake-oracledeveloperstudio:
docker:
- image: fedora
steps:
- checkout
- run: dnf install -y gcc ragel cmake make which glib2-devel freetype-devel cairo-devel libicu-devel graphite2-devel wget tar bzip2 python libnsl || true
- run: wget http://$ODSUSER:$ODSPASS@behdad.org/harfbuzz-private/OracleDeveloperStudio12.6-linux-x86-bin.tar.bz2 && tar xf OracleDeveloperStudio12.6-linux-x86-bin.tar.bz2 --owner root --group root --no-same-owner
- run: CC=/root/project/OracleDeveloperStudio12.6-linux-x86-bin/developerstudio12.6/bin/suncc CXX=/root/project/OracleDeveloperStudio12.6-linux-x86-bin/developerstudio12.6/bin/sunCC cmake -DHB_HAVE_GRAPHITE2=ON -DHB_BUILTIN_UCDN=ON -DHB_HAVE_GLIB=ON -DHB_HAVE_FREETYPE=ON -Bbuild -H.
- run: make -Cbuild -j32
- run: CTEST_OUTPUT_ON_FAILURE=1 make -Cbuild test
- run: make -Cbuild install
#cmake-oracledeveloperstudio:
# docker:
# - image: fedora
# steps:
# - checkout
# - run: dnf install -y gcc ragel cmake make which glib2-devel freetype-devel cairo-devel libicu-devel graphite2-devel wget tar bzip2 python libnsl || true
# - run: wget http://$ODSUSER:$ODSPASS@behdad.org/harfbuzz-private/OracleDeveloperStudio12.6-linux-x86-bin.tar.bz2 && tar xf OracleDeveloperStudio12.6-linux-x86-bin.tar.bz2 --owner root --group root --no-same-owner
# - run: CC=/root/project/OracleDeveloperStudio12.6-linux-x86-bin/developerstudio12.6/bin/suncc CXX=/root/project/OracleDeveloperStudio12.6-linux-x86-bin/developerstudio12.6/bin/sunCC cmake -DHB_HAVE_GRAPHITE2=ON -DHB_BUILTIN_UCDN=ON -DHB_HAVE_GLIB=ON -DHB_HAVE_FREETYPE=ON -Bbuild -H.
# - run: make -Cbuild -j32
# - run: CTEST_OUTPUT_ON_FAILURE=1 make -Cbuild test
# - run: make -Cbuild install
crosscompile-notest-djgpp:
docker:
@ -253,12 +253,12 @@ jobs:
- run: cmake -Bbuild -H. -GNinja
- run: ninja -Cbuild
crosscompile-cmake-notest-browser-asmjs:
crosscompile-cmake-notest-browser-asmjs-hb_tiny:
docker:
- image: dockcross/browser-asmjs
steps:
- checkout
- run: cmake -Bbuild -H. -GNinja
- run: cmake -Bbuild -H. -GNinja -DCMAKE_CXX_FLAGS="-DHB_TINY"
- run: ninja -Cbuild
crosscompile-cmake-notest-linux-arm64:
@ -322,7 +322,7 @@ workflows:
## cmake
- crosscompile-cmake-notest-android-arm
- crosscompile-cmake-notest-browser-asmjs
- crosscompile-cmake-notest-browser-asmjs-hb_tiny
- crosscompile-cmake-notest-linux-arm64
- crosscompile-cmake-notest-linux-mips
#- crosscompile-cmake-notest-windows-x64

View File

@ -1,5 +1,5 @@
# Build Configuration for Travis
dist: trusty
dist: xenial
language: cpp

View File

@ -5,23 +5,30 @@ Values defined in `hb-debug.hh`.
```shell
# quick sanity check
time (make CPPFLAGS='-DHB_DEBUG_SUBSET=100' \
&& make -C test/api check || cat test/api/test-suite.log)
time (make -j4 CPPFLAGS='-DHB_DEBUG_SUBSET=100' \
&& (make -j4 -C test/api check || cat test/api/test-suite.log))
# slower santiy check
time (make CPPFLAGS='-DHB_DEBUG_SUBSET=100' \
&& make -C src check \
&& make -C test/api check \
&& make -C test/subset check)
# slower sanity check
time (make -j4 CPPFLAGS='-DHB_DEBUG_SUBSET=100' \
&& make -j4 -C src check \
&& make -j4 -C test/api check \
&& make -j4 -C test/subset check)
# confirm you didn't break anything else
time (make CPPFLAGS='-DHB_DEBUG_SUBSET=100' \
&& make check)
time (make -j4 CPPFLAGS='-DHB_DEBUG_SUBSET=100' \
&& make -j4 check)
# often catches files you didn't add, e.g. test fonts to EXTRA_DIST
make distcheck
```
### Run tests with asan
```shell
./configure CC=clang CXX=clang++ CPPFLAGS=-fsanitize=address LDFLAGS=-fsanitize=address
# make/run tests as usual
```
### Debug with GDB
```

View File

@ -9,7 +9,7 @@ AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([src/harfbuzz.pc.in])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([1.13.0 gnits tar-ustar dist-bzip2 no-dist-gzip -Wall no-define color-tests -Wno-portability])
AM_INIT_AUTOMAKE([1.13.0 gnits tar-ustar dist-xz no-dist-gzip -Wall no-define color-tests -Wno-portability])
AM_SILENT_RULES([yes])
AX_CODE_COVERAGE

View File

@ -31,6 +31,7 @@ HB_BASE_sources = \
hb-cff1-interp-cs.hh \
hb-cff2-interp-cs.hh \
hb-common.cc \
hb-config.hh \
hb-debug.hh \
hb-dispatch.hh \
hb-face.cc \

View File

@ -7,7 +7,7 @@ test -z "$srcdir" && srcdir=.
test -z "$libs" && libs=.libs
stat=0
IGNORED_SYMBOLS='_fini\|_init\|_fdata\|_ftext\|_fbss\|__bss_start\|__bss_start__\|__bss_end__\|_edata\|_end\|_bss_end__\|__end__\|__gcov_flush\|llvm_.*'
IGNORED_SYMBOLS='_fini\|_init\|_fdata\|_ftext\|_fbss\|__bss_start\|__bss_start__\|__bss_end__\|_edata\|_end\|_bss_end__\|__end__\|__gcov_.*\|llvm_.*'
if which nm 2>/dev/null >/dev/null; then
:

2
src/gen-os2-unicode-ranges.py Normal file → Executable file
View File

@ -1,3 +1,5 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Generates the code for a sorted unicode range array as used in hb-ot-os2-unicode-ranges.hh

46
src/gen-ucd.py Executable file
View File

@ -0,0 +1,46 @@
#!/usr/bin/env python
from __future__ import print_function, division, absolute_import
import io, os.path, sys
if len (sys.argv) != 2:
print ("usage: ./gen-ucd ucdxml-file", file=sys.stderr)
sys.exit (1)
import youseedy, packTab
ucd = youseedy.load_ucdxml (sys.argv[1])
gc = [u['gc'] for u in ucd]
ccc = [int(u['ccc']) for u in ucd]
sc = [u['sc'] for u in ucd]
bmg = [int(v, 16) - int(u) if v else 0 for u,v in enumerate(u['bmg'] for u in ucd)]
dm = {i:tuple(int(v, 16) for v in u['dm'].split()) for i,u in enumerate(ucd)
if u['dm'] != '#' and u['dt'] == 'can' and not (0xAC00 <= i < 0xAC00+11172)}
gc_set = set(gc)
gc_ccc_non0 = set((cat,klass) for cat,klass in zip(gc,ccc) if klass)
gc_bmg_non0 = set((cat,mirr) for cat,mirr in zip(gc, bmg) if mirr)
sc_set = set(sc)
dm2 = set(v for v in dm.values() if len(v) == 2)
dm2diff = set(v[1] - v[0] for v in dm2)
dm1 = set(v[0] for i,v in dm.items() if len(v) == 1)
dmx = set(v for v in dm.values() if len(v) not in (1,2))
assert not dmx
print(len(sorted(gc_set)))
print(len(sorted(gc_ccc_non0)))
print(len(sorted(gc_bmg_non0)))
print("GC, CCC, and BMG fit in one byte. Compress together.")
print()
print(len(sorted(sc_set)))
print("SC fits in one byte. Compress separately.")
print()
print(len(dm))
print(len(dm1), min(dm1), max(dm1))
print(len(dm2))
#print(sorted(dm2diff))
print(len(sorted(set(v // 512 for v in dm1))))

View File

@ -197,15 +197,15 @@ def is_BASE_OTHER(U, UISC, UGC):
def is_CGJ(U, UISC, UGC):
return U == 0x034F
def is_CONS_FINAL(U, UISC, UGC):
# Consonant_Initial_Postfixed is new in Unicode 11; not in the spec.
return ((UISC == Consonant_Final and UGC != Lo) or
UISC == Consonant_Initial_Postfixed or
UISC == Consonant_Succeeding_Repha)
def is_CONS_FINAL_MOD(U, UISC, UGC):
#SPEC-DRAFT return UISC in [Consonant_Final_Modifier, Syllable_Modifier]
return UISC == Syllable_Modifier
def is_CONS_MED(U, UISC, UGC):
return UISC == Consonant_Medial and UGC != Lo
# Consonant_Initial_Postfixed is new in Unicode 11; not in the spec.
return (UISC == Consonant_Medial and UGC != Lo or
UISC == Consonant_Initial_Postfixed)
def is_CONS_MOD(U, UISC, UGC):
return UISC in [Nukta, Gemination_Mark, Consonant_Killer]
def is_CONS_SUB(U, UISC, UGC):

View File

@ -135,6 +135,10 @@ static const hb_aat_feature_mapping_t feature_mappings[] =
const hb_aat_feature_mapping_t *
hb_aat_layout_find_feature_mapping (hb_tag_t tag)
{
#ifdef HB_NO_SHAPE_AAT
return nullptr;
#endif
return (const hb_aat_feature_mapping_t *) bsearch (&tag,
feature_mappings,
ARRAY_LENGTH (feature_mappings),
@ -147,6 +151,8 @@ hb_aat_layout_find_feature_mapping (hb_tag_t tag)
* hb_aat_apply_context_t
*/
/* Note: This context is used for kerning, even without AAT. */
AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_,
hb_font_t *font_,
hb_buffer_t *buffer_,
@ -183,6 +189,10 @@ void
hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper,
hb_aat_map_t *map)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
const AAT::morx& morx = *mapper->face->table.morx;
if (morx.has_data ())
{
@ -209,6 +219,10 @@ hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper,
hb_bool_t
hb_aat_layout_has_substitution (hb_face_t *face)
{
#ifdef HB_NO_SHAPE_AAT
return false;
#endif
return face->table.morx->has_data () ||
face->table.mort->has_data ();
}
@ -218,6 +232,10 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
hb_blob_t *morx_blob = font->face->table.morx.get_blob ();
const AAT::morx& morx = *morx_blob->as<AAT::morx> ();
if (morx.has_data ())
@ -240,6 +258,10 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan,
void
hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
hb_glyph_position_t *pos = buffer->pos;
@ -257,6 +279,10 @@ is_deleted_glyph (const hb_glyph_info_t *info)
void
hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
hb_ot_layout_delete_glyphs_inplace (buffer, is_deleted_glyph);
}
@ -270,6 +296,10 @@ hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer)
hb_bool_t
hb_aat_layout_has_positioning (hb_face_t *face)
{
#ifdef HB_NO_SHAPE_AAT
return false;
#endif
return face->table.kerx->has_data ();
}
@ -278,6 +308,10 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
hb_blob_t *kerx_blob = font->face->table.kerx.get_blob ();
const AAT::kerx& kerx = *kerx_blob->as<AAT::kerx> ();
@ -297,6 +331,10 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan,
hb_bool_t
hb_aat_layout_has_tracking (hb_face_t *face)
{
#ifdef HB_NO_SHAPE_AAT
return false;
#endif
return face->table.trak->has_data ();
}
@ -305,6 +343,10 @@ hb_aat_layout_track (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
const AAT::trak& trak = *font->face->table.trak;
AAT::hb_aat_apply_context_t c (plan, font, buffer);
@ -328,6 +370,12 @@ hb_aat_layout_get_feature_types (hb_face_t *face,
unsigned int *feature_count, /* IN/OUT. May be NULL. */
hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */)
{
#ifdef HB_NO_SHAPE_AAT
if (feature_count)
*feature_count = 0;
return 0;
#endif
return face->table.feat->get_feature_types (start_offset, feature_count, features);
}
@ -344,6 +392,10 @@ hb_ot_name_id_t
hb_aat_layout_feature_type_get_name_id (hb_face_t *face,
hb_aat_layout_feature_type_t feature_type)
{
#ifdef HB_NO_SHAPE_AAT
return HB_OT_NAME_ID_INVALID;
#endif
return face->table.feat->get_feature_name_id (feature_type);
}
@ -372,5 +424,11 @@ hb_aat_layout_feature_type_get_selector_infos (hb_face_t
hb_aat_layout_feature_selector_info_t *selectors, /* OUT. May be NULL. */
unsigned int *default_index /* OUT. May be NULL. */)
{
#ifdef HB_NO_SHAPE_AAT
if (selector_count)
*selector_count = 0;
return 0;
#endif
return face->table.feat->get_selector_infos (feature_type, start_offset, selector_count, selectors, default_index);
}

View File

@ -34,6 +34,10 @@
void hb_aat_map_builder_t::add_feature (hb_tag_t tag,
unsigned int value)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
if (tag == HB_TAG ('a','a','l','t'))
{
feature_info_t *info = features.push();
@ -53,6 +57,10 @@ void hb_aat_map_builder_t::add_feature (hb_tag_t tag,
void
hb_aat_map_builder_t::compile (hb_aat_map_t &m)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
/* Sort features and merge duplicates */
if (features.length)
{

View File

@ -73,7 +73,7 @@ struct
impl (const T& v, hb_priority<1>) const HB_RETURN (uint32_t, hb_deref (v).hash ())
template <typename T,
hb_enable_if (hb_is_integer (T))> auto
hb_enable_if (hb_is_integral (T))> auto
impl (const T& v, hb_priority<0>) const HB_AUTO_RETURN
(
/* Knuth's multiplicative method: */
@ -119,6 +119,52 @@ struct
}
HB_FUNCOBJ (hb_invoke);
template <unsigned Pos, typename Appl, typename V>
struct hb_partial_t
{
hb_partial_t (Appl a, V v) : a (a), v (v) {}
static_assert (Pos > 0, "");
template <typename ...Ts,
unsigned P = Pos,
hb_enable_if (P == 1)> auto
operator () (Ts&& ...ds) -> decltype (hb_invoke (hb_declval (Appl),
hb_declval (V),
hb_declval (Ts)...))
{
return hb_invoke (hb_forward<Appl> (a),
hb_forward<V> (v),
hb_forward<Ts> (ds)...);
}
template <typename T0, typename ...Ts,
unsigned P = Pos,
hb_enable_if (P == 2)> auto
operator () (T0&& d0, Ts&& ...ds) -> decltype (hb_invoke (hb_declval (Appl),
hb_declval (T0),
hb_declval (V),
hb_declval (Ts)...))
{
return hb_invoke (hb_forward<Appl> (a),
hb_forward<T0> (d0),
hb_forward<V> (v),
hb_forward<Ts> (ds)...);
}
private:
hb_reference_wrapper<Appl> a;
V v;
};
template <unsigned Pos=1, typename Appl, typename V>
auto hb_partial (Appl&& a, V&& v) HB_AUTO_RETURN
(( hb_partial_t<Pos, Appl, V> (a, v) ))
#define HB_PARTIALIZE(Pos) \
template <typename _T> \
auto operator () (_T&& _v) const HB_AUTO_RETURN (hb_partial<Pos> (this, hb_forward<_T> (_v))) \
static_assert (true, "")
struct
{
private:
@ -215,7 +261,6 @@ struct hb_pair_t
typedef hb_pair_t<T1, T2> pair_t;
hb_pair_t (T1 a, T2 b) : first (a), second (b) {}
hb_pair_t (const pair_t& o) : first (o.first), second (o.second) {}
template <typename Q1, typename Q2,
hb_enable_if (hb_is_convertible (T1, Q1) &&
@ -226,6 +271,11 @@ struct hb_pair_t
{ return hb_pair_t<T1, T2> (second, first); }
bool operator == (const pair_t& o) const { return first == o.first && second == o.second; }
bool operator != (const pair_t& o) const { return !(*this == o); }
bool operator < (const pair_t& o) const { return first < o.first || (first == o.first && second < o.second); }
bool operator >= (const pair_t& o) const { return !(*this < o); }
bool operator > (const pair_t& o) const { return first > o.first || (first == o.first && second > o.second); }
bool operator <= (const pair_t& o) const { return !(*this > o); }
T1 first;
T2 second;
@ -236,15 +286,15 @@ hb_pair (T1&& a, T2&& b) { return hb_pair_t<T1, T2> (a, b); }
struct
{
template <typename Pair> auto
operator () (const Pair& pair) const HB_AUTO_RETURN (pair.first)
template <typename Pair> typename Pair::first_t
operator () (const Pair& pair) const { return pair.first; }
}
HB_FUNCOBJ (hb_first);
struct
{
template <typename Pair> auto
operator () (const Pair& pair) const HB_AUTO_RETURN (pair.second)
template <typename Pair> typename Pair::second_t
operator () (const Pair& pair) const { return pair.second; }
}
HB_FUNCOBJ (hb_second);
@ -254,34 +304,16 @@ HB_FUNCOBJ (hb_second);
* comparing integers of different signedness. */
struct
{
private:
template <typename T, typename T2> auto
impl (T&& a, T2&& b) const HB_AUTO_RETURN
operator () (T&& a, T2&& b) const HB_AUTO_RETURN
(hb_forward<T> (a) <= hb_forward<T2> (b) ? hb_forward<T> (a) : hb_forward<T2> (b))
public:
template <typename T> auto
operator () (T&& a) const HB_AUTO_RETURN (hb_forward<T> (a))
template <typename T, typename... Ts> auto
operator () (T&& a, Ts&& ...ds) const HB_AUTO_RETURN
(impl (hb_forward<T> (a), (*this) (hb_forward<Ts> (ds)...)))
}
HB_FUNCOBJ (hb_min);
struct
{
private:
template <typename T, typename T2> auto
impl (T&& a, T2&& b) const HB_AUTO_RETURN
operator () (T&& a, T2&& b) const HB_AUTO_RETURN
(hb_forward<T> (a) >= hb_forward<T2> (b) ? hb_forward<T> (a) : hb_forward<T2> (b))
public:
template <typename T> auto
operator () (T&& a) const HB_AUTO_RETURN (hb_forward<T> (a))
template <typename T, typename... Ts> auto
operator () (T&& a, Ts&& ...ds) const HB_AUTO_RETURN
(impl (hb_forward<T> (a), (*this) (hb_forward<Ts> (ds)...)))
}
HB_FUNCOBJ (hb_max);
@ -760,30 +792,83 @@ hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *o
}
struct HbOpOr
{
static constexpr bool passthru_left = true;
static constexpr bool passthru_right = true;
template <typename T> static void process (T &o, const T &a, const T &b) { o = a | b; }
};
struct HbOpAnd
{
/* Operators. */
struct hb_bitwise_and
{ HB_PARTIALIZE(2);
static constexpr bool passthru_left = false;
static constexpr bool passthru_right = false;
template <typename T> static void process (T &o, const T &a, const T &b) { o = a & b; }
};
struct HbOpMinus
{
static constexpr bool passthru_left = true;
static constexpr bool passthru_right = false;
template <typename T> static void process (T &o, const T &a, const T &b) { o = a & ~b; }
};
struct HbOpXor
{
template <typename T> auto
operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & b)
}
HB_FUNCOBJ (hb_bitwise_and);
struct hb_bitwise_or
{ HB_PARTIALIZE(2);
static constexpr bool passthru_left = true;
static constexpr bool passthru_right = true;
template <typename T> static void process (T &o, const T &a, const T &b) { o = a ^ b; }
};
template <typename T> auto
operator () (const T &a, const T &b) const HB_AUTO_RETURN (a | b)
}
HB_FUNCOBJ (hb_bitwise_or);
struct hb_bitwise_xor
{ HB_PARTIALIZE(2);
static constexpr bool passthru_left = true;
static constexpr bool passthru_right = true;
template <typename T> auto
operator () (const T &a, const T &b) const HB_AUTO_RETURN (a ^ b)
}
HB_FUNCOBJ (hb_bitwise_xor);
struct hb_bitwise_sub
{ HB_PARTIALIZE(2);
static constexpr bool passthru_left = true;
static constexpr bool passthru_right = false;
template <typename T> auto
operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & ~b)
}
HB_FUNCOBJ (hb_bitwise_sub);
struct
{ HB_PARTIALIZE(2);
template <typename T, typename T2> auto
operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a + b)
}
HB_FUNCOBJ (hb_add);
struct
{ HB_PARTIALIZE(2);
template <typename T, typename T2> auto
operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a - b)
}
HB_FUNCOBJ (hb_sub);
struct
{ HB_PARTIALIZE(2);
template <typename T, typename T2> auto
operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a * b)
}
HB_FUNCOBJ (hb_mul);
struct
{ HB_PARTIALIZE(2);
template <typename T, typename T2> auto
operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a / b)
}
HB_FUNCOBJ (hb_div);
struct
{ HB_PARTIALIZE(2);
template <typename T, typename T2> auto
operator () (const T &a, const T2 &b) const HB_AUTO_RETURN (a % b)
}
HB_FUNCOBJ (hb_mod);
struct
{
template <typename T> auto
operator () (const T &a) const HB_AUTO_RETURN (+a)
}
HB_FUNCOBJ (hb_pos);
struct
{
template <typename T> auto
operator () (const T &a) const HB_AUTO_RETURN (-a)
}
HB_FUNCOBJ (hb_neg);
/* Compiler-assisted vectorization. */
@ -799,26 +884,26 @@ struct hb_vector_size_t
void clear (unsigned char v = 0) { memset (this, v, sizeof (*this)); }
template <class Op>
hb_vector_size_t process (const hb_vector_size_t &o) const
template <typename Op>
hb_vector_size_t process (const Op& op, const hb_vector_size_t &o) const
{
hb_vector_size_t r;
#if HB_VECTOR_SIZE
if (HB_VECTOR_SIZE && 0 == (byte_size * 8) % HB_VECTOR_SIZE)
for (unsigned int i = 0; i < ARRAY_LENGTH (u.vec); i++)
Op::process (r.u.vec[i], u.vec[i], o.u.vec[i]);
r.u.vec[i] = op (u.vec[i], o.u.vec[i]);
else
#endif
for (unsigned int i = 0; i < ARRAY_LENGTH (u.v); i++)
Op::process (r.u.v[i], u.v[i], o.u.v[i]);
r.u.v[i] = op (u.v[i], o.u.v[i]);
return r;
}
hb_vector_size_t operator | (const hb_vector_size_t &o) const
{ return process<HbOpOr> (o); }
{ return process (hb_bitwise_or, o); }
hb_vector_size_t operator & (const hb_vector_size_t &o) const
{ return process<HbOpAnd> (o); }
{ return process (hb_bitwise_and, o); }
hb_vector_size_t operator ^ (const hb_vector_size_t &o) const
{ return process<HbOpXor> (o); }
{ return process (hb_bitwise_xor, o); }
hb_vector_size_t operator ~ () const
{
hb_vector_size_t r;

View File

@ -42,20 +42,20 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
/*
* Constructors.
*/
hb_array_t () : arrayZ (nullptr), length (0) {}
hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_) {}
hb_array_t () : arrayZ (nullptr), length (0), backwards_length (0) {}
hb_array_t (Type *array_, unsigned int length_) : arrayZ (array_), length (length_), backwards_length (0) {}
template <unsigned int length_>
hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_) {}
hb_array_t (Type (&array_)[length_]) : arrayZ (array_), length (length_), backwards_length (0) {}
template <typename U,
hb_enable_if (hb_is_cr_convertible(U, Type))>
hb_array_t (const hb_array_t<U> &o) :
hb_iter_with_fallback_t<hb_array_t<Type>, Type&> (),
arrayZ (o.arrayZ), length (o.length) {}
arrayZ (o.arrayZ), length (o.length), backwards_length (o.backwards_length) {}
template <typename U,
hb_enable_if (hb_is_cr_convertible(U, Type))>
hb_array_t& operator = (const hb_array_t<U> &o)
{ arrayZ = o.arrayZ; length = o.length; return *this; }
{ arrayZ = o.arrayZ; length = o.length; backwards_length = o.backwards_length; return *this; }
/*
* Iterator implementation.
@ -72,17 +72,25 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
if (unlikely (n > length))
n = length;
length -= n;
backwards_length += n;
arrayZ += n;
}
void __rewind__ (unsigned n)
{
if (unlikely (n > length))
n = length;
length -= n;
if (unlikely (n > backwards_length))
n = backwards_length;
length += n;
backwards_length -= n;
arrayZ -= n;
}
unsigned __len__ () const { return length; }
/* Ouch. The operator== compares the contents of the array. For range-based for loops,
* it's best if we can just compare arrayZ, though comparing contents is still fast,
* but also would require that Type has operator==. As such, we optimize this operator
* for range-based for loop and just compare arrayZ. No need to compare length, as we
* assume we're only compared to .end(). */
bool operator != (const hb_array_t& o) const
{ return arrayZ != o.arrayZ || length != o.length; }
{ return arrayZ != o.arrayZ; }
/* Extra operators.
*/
@ -199,6 +207,7 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
public:
Type *arrayZ;
unsigned int length;
unsigned int backwards_length;
};
template <typename T> inline hb_array_t<T>
hb_array (T *array, unsigned int length)
@ -315,7 +324,7 @@ bool hb_array_t<T>::operator == (const hb_array_t<T> &o) const
{
return length == o.length &&
+ hb_zip (*this, o)
| hb_map ([] (hb_pair_t<T&, T&> &&_) -> bool { return _.first == _.second; })
| hb_map ([] (hb_pair_t<T&, T&> &&_) { return _.first == _.second; })
| hb_all
;
}
@ -325,7 +334,7 @@ uint32_t hb_array_t<T>::hash () const
return
+ hb_iter (*this)
| hb_map (hb_hash)
| hb_reduce ([] (uint32_t a, uint32_t b) -> uint32_t { return a * 31 + b; }, 0)
| hb_reduce ([] (uint32_t a, uint32_t b) { return a * 31 + b; }, 0)
;
}

View File

@ -107,7 +107,7 @@ _hb_atomic_ptr_impl_cmplexch (const void **P, const void *O_, const void *N)
static inline void _hb_memory_barrier ()
{
#if !defined(MemoryBarrier)
#ifndef MemoryBarrier
/* MinGW has a convoluted history of supporting MemoryBarrier. */
LONG dummy = 0;
InterlockedExchange (&dummy, 1);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -28,8 +28,10 @@
static const char *serialize_formats[] = {
#ifndef HB_NO_BUFFER_SERIALIZE
"text",
"json",
#endif
nullptr
};
@ -85,10 +87,12 @@ hb_buffer_serialize_format_from_string (const char *str, int len)
const char *
hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format)
{
switch (format)
switch ((unsigned) format)
{
#ifndef HB_NO_BUFFER_SERIALIZE
case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0];
case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1];
#endif
default:
case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return nullptr;
}
@ -344,6 +348,10 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
if (buf_size)
*buf = '\0';
#ifdef HB_NO_BUFFER_SERIALIZE
return 0;
#endif
assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
@ -449,6 +457,10 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
end_ptr = &end;
*end_ptr = buf;
#ifdef HB_NO_BUFFER_SERIALIZE
return false;
#endif
assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);

View File

@ -67,7 +67,7 @@ _hb_options_init ()
p = c + strlen (c);
#define OPTION(name, symbol) \
if (0 == strncmp (c, name, p - c) && strlen (name) == p - c) u.opts.symbol = true;
if (0 == strncmp (c, name, p - c) && strlen (name) == p - c) do { u.opts.symbol = true; } while (0)
OPTION ("uniscribe-bug-compatible", uniscribe_bug_compatible);
OPTION ("aat", aat);

122
src/hb-config.hh Normal file
View File

@ -0,0 +1,122 @@
/*
* Copyright © 2019 Facebook, 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.
*
* Facebook Author(s): Behdad Esfahbod
*/
#ifndef HB_CONFIG_HH
#define HB_CONFIG_HH
#if 0 /* Make test happy. */
#include "hb.hh"
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef HB_TINY
#define HB_LEAN
#define HB_MINI
#define HB_NO_MT
#ifndef NDEBUG
#define NDEBUG
#endif
#endif
#ifdef HB_LEAN
#define HB_DISABLE_DEPRECATED
#define HB_NDEBUG
#define HB_NO_ATEXIT
#define HB_NO_BUFFER_SERIALIZE
#define HB_NO_BITMAP
#define HB_NO_CFF
#define HB_NO_COLOR
#define HB_NO_GETENV
#define HB_NO_LAYOUT_UNUSED
#define HB_NO_MATH
#define HB_NO_NAME
#define HB_NO_SUBSET_LAYOUT
#endif
#ifdef HB_MINI
#define HB_NO_AAT
#define HB_NO_LEGACY
#endif
/* Closure. */
#ifdef HB_DISABLE_DEPRECATED
#define HB_IF_NOT_DEPRECATED(x)
#else
#define HB_IF_NOT_DEPRECATED(x) x
#endif
#ifdef HB_NO_AAT
#define HB_NO_OT_NAME_LANGUAGE_AAT
#define HB_NO_SHAPE_AAT
#endif
#ifdef HB_NO_BITMAP
#define HB_NO_OT_FONT_BITMAP
#endif
#ifdef HB_NO_CFF
#define HB_NO_OT_FONT_CFF
#define HB_NO_SUBSET_CFF
#endif
#ifdef HB_NO_GETENV
#define HB_NO_UNISCRIBE_BUG_COMPATIBLE
#endif
#ifdef HB_NO_LEGACY
#define HB_NO_OT_LAYOUT_BLACKLIST
#define HB_NO_OT_SHAPE_FALLBACK
#endif
#ifdef HB_NO_NAME
#define HB_NO_OT_NAME_LANGUAGE
#endif
#ifdef HB_NO_OT_SHAPE_FALLBACK
#define HB_NO_OT_SHAPE_COMPLEX_ARABIC_FALLBACK
#define HB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK
#define HB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK
#define HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS
#endif
#ifdef NDEBUG
#ifndef HB_NDEBUG
#define HB_NDEBUG
#endif
#endif
#ifdef HAVE_CONFIG_OVERRIDE_H
#include "config-override.h"
#endif
#endif /* HB_CONFIG_HH */

View File

@ -598,7 +598,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
} else {
active_feature_t *feature = active_features.find (&event->feature);
if (feature)
active_features.remove (feature - active_features.arrayZ ());
active_features.remove (feature - active_features.arrayZ);
}
}
}
@ -608,7 +608,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
#define ALLOCATE_ARRAY(Type, name, len, on_no_room) \
Type *name = (Type *) scratch; \
{ \
do { \
unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
if (unlikely (_consumed > scratch_size)) \
{ \
@ -617,7 +617,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
} \
scratch += _consumed; \
scratch_size -= _consumed; \
}
} while (0)
ALLOCATE_ARRAY (UniChar, pchars, buffer->len * 2, /*nothing*/);
unsigned int chars_len = 0;

View File

@ -63,7 +63,7 @@ extern HB_INTERNAL hb_atomic_int_t _hb_options;
static inline hb_options_t
hb_options ()
{
#if defined(HB_NO_GETENV)
#ifdef HB_NO_GETENV
return hb_options_t ();
#endif
/* Make a local copy, so we can access bitfield threadsafely. */
@ -249,8 +249,8 @@ struct hb_printer_t<bool> {
};
template <>
struct hb_printer_t<hb_void_t> {
const char *print (hb_void_t) { return ""; }
struct hb_printer_t<hb_empty_t> {
const char *print (hb_empty_t) { return ""; }
};
@ -266,7 +266,7 @@ static inline void _hb_warn_no_return (bool returned)
}
}
template <>
/*static*/ inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED)
/*static*/ inline void _hb_warn_no_return<hb_empty_t> (bool returned HB_UNUSED)
{}
template <int max_level, typename ret_t>

View File

@ -530,12 +530,12 @@ _hb_directwrite_shape_full (hb_shape_plan_t *shape_plan,
hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
#define ALLOCATE_ARRAY(Type, name, len) \
Type *name = (Type *) scratch; \
{ \
do { \
unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
assert (_consumed <= scratch_size); \
scratch += _consumed; \
scratch_size -= _consumed; \
}
} while (0)
#define utf16_index() var1.u32

View File

@ -336,6 +336,7 @@ hb_font_get_glyph_v_origin_default (hb_font_t *font,
return ret;
}
#ifndef HB_DISABLE_DEPRECATED
static hb_position_t
hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
@ -373,6 +374,7 @@ hb_font_get_glyph_v_kerning_default (hb_font_t *font,
{
return font->parent_scale_y_distance (font->parent->get_glyph_v_kerning (top_glyph, bottom_glyph));
}
#endif
static hb_bool_t
hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
@ -925,6 +927,7 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
return font->get_glyph_v_origin (glyph, x, y);
}
#ifndef HB_DISABLE_DEPRECATED
/**
* hb_font_get_glyph_h_kerning:
* @font: a font.
@ -964,6 +967,7 @@ hb_font_get_glyph_v_kerning (hb_font_t *font,
{
return font->get_glyph_v_kerning (top_glyph, bottom_glyph);
}
#endif
/**
* hb_font_get_glyph_extents:
@ -1173,6 +1177,7 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
}
#ifndef HB_DISABLE_DEPRECATED
/**
* hb_font_get_glyph_kerning_for_direction:
* @font: a font.
@ -1195,6 +1200,7 @@ hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
{
return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
}
#endif
/**
* hb_font_get_glyph_extents_for_origin:
@ -1347,7 +1353,7 @@ hb_font_create (hb_face_t *face)
{
hb_font_t *font = _hb_font_create (face);
#if !defined(HB_NO_OT_FONT)
#ifndef HB_NO_OT_FONT
/* Install our in-house, very lightweight, funcs. */
hb_ot_font_set_funcs (font);
#endif
@ -1916,6 +1922,7 @@ hb_font_get_var_coords_normalized (hb_font_t *font,
}
#ifndef HB_DISABLE_DEPRECATED
/*
* Deprecated get_glyph_func():
*/
@ -2038,3 +2045,4 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
trampoline,
trampoline_destroy);
}
#endif

View File

@ -51,8 +51,8 @@
HB_FONT_FUNC_IMPLEMENT (glyph_v_advances) \
HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \
HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \
HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \
HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning) \
HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning)) \
HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning)) \
HB_FONT_FUNC_IMPLEMENT (glyph_extents) \
HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \
HB_FONT_FUNC_IMPLEMENT (glyph_name) \
@ -304,17 +304,25 @@ struct hb_font_t
hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph,
hb_codepoint_t right_glyph)
{
#ifdef HB_DISABLE_DEPRECATED
return 0;
#else
return klass->get.f.glyph_h_kerning (this, user_data,
left_glyph, right_glyph,
klass->user_data.glyph_h_kerning);
#endif
}
hb_position_t get_glyph_v_kerning (hb_codepoint_t top_glyph,
hb_codepoint_t bottom_glyph)
{
#ifdef HB_DISABLE_DEPRECATED
return 0;
#else
return klass->get.f.glyph_v_kerning (this, user_data,
top_glyph, bottom_glyph,
klass->user_data.glyph_v_kerning);
#endif
}
hb_bool_t get_glyph_extents (hb_codepoint_t glyph,

View File

@ -202,6 +202,7 @@ _hb_graphite2_shaper_font_data_destroy (hb_graphite2_font_data_t *data HB_UNUSED
{
}
#ifndef HB_DISABLE_DEPRECATED
/**
* hb_graphite2_font_get_gr_font:
*
@ -213,6 +214,7 @@ hb_graphite2_font_get_gr_font (hb_font_t *font HB_UNUSED)
{
return nullptr;
}
#endif
/*
@ -308,12 +310,12 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
#define ALLOCATE_ARRAY(Type, name, len) \
Type *name = (Type *) scratch; \
{ \
do { \
unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
assert (_consumed <= scratch_size); \
scratch += _consumed; \
scratch_size -= _consumed; \
}
} while (0)
ALLOCATE_ARRAY (hb_graphite2_cluster_t, clusters, buffer->len);
ALLOCATE_ARRAY (hb_codepoint_t, gids, glyph_count);

View File

@ -49,6 +49,9 @@
* Functions for using HarfBuzz with the ICU library to provide Unicode data.
**/
/* ICU doesn't do-while(0) around their statements. Ugh!
* https://unicode-org.atlassian.net/browse/CLDR-13027 */
#define HB_ICU_STMT(S) do { S } while (0)
hb_script_t
hb_icu_script_to_script (UScriptCode script)
@ -183,9 +186,9 @@ hb_icu_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
len = 0;
err = false;
U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), a, err);
HB_ICU_STMT (U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), a, err));
if (err) return false;
U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), b, err);
HB_ICU_STMT (U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), b, err));
if (err) return false;
icu_err = U_ZERO_ERROR;
@ -193,7 +196,7 @@ hb_icu_unicode_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
if (U_FAILURE (icu_err))
return false;
if (u_countChar32 (normalized, len) == 1) {
U16_GET_UNSAFE (normalized, 0, *ab);
HB_ICU_STMT (U16_GET_UNSAFE (normalized, 0, *ab));
ret = true;
} else {
ret = false;
@ -221,13 +224,13 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
len = u_countChar32 (decomposed, len);
if (len == 1) {
U16_GET_UNSAFE (decomposed, 0, *a);
HB_ICU_STMT (U16_GET_UNSAFE (decomposed, 0, *a));
*b = 0;
return *a != ab;
} else if (len == 2) {
len =0;
U16_NEXT_UNSAFE (decomposed, len, *a);
U16_NEXT_UNSAFE (decomposed, len, *b);
HB_ICU_STMT (U16_NEXT_UNSAFE (decomposed, len, *a));
HB_ICU_STMT (U16_NEXT_UNSAFE (decomposed, len, *b));
}
return true;
}
@ -236,7 +239,7 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
/* We don't ifdef-out the fallback code such that compiler always
* sees it and makes sure it's compilable. */
UChar utf16[2], normalized[2 * HB_UNICODE_MAX_DECOMPOSITION_LEN + 1];
UChar utf16[2], normalized[2 * 19/*HB_UNICODE_MAX_DECOMPOSITION_LEN*/ + 1];
unsigned int len;
hb_bool_t ret, err;
UErrorCode icu_err;
@ -247,7 +250,7 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
len = 0;
err = false;
U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), ab, err);
HB_ICU_STMT (U16_APPEND (utf16, len, ARRAY_LENGTH (utf16), ab, err));
if (err) return false;
icu_err = U_ZERO_ERROR;
@ -258,13 +261,13 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
len = u_countChar32 (normalized, len);
if (len == 1) {
U16_GET_UNSAFE (normalized, 0, *a);
HB_ICU_STMT (U16_GET_UNSAFE (normalized, 0, *a));
*b = 0;
ret = *a != ab;
} else if (len == 2) {
len =0;
U16_NEXT_UNSAFE (normalized, len, *a);
U16_NEXT_UNSAFE (normalized, len, *b);
HB_ICU_STMT (U16_NEXT_UNSAFE (normalized, len, *a));
HB_ICU_STMT (U16_NEXT_UNSAFE (normalized, len, *b));
/* Here's the ugly part: if ab decomposes to a single character and
* that character decomposes again, we have to detect that and undo
@ -275,7 +278,7 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
if (U_FAILURE (icu_err))
return false;
hb_codepoint_t c;
U16_GET_UNSAFE (recomposed, 0, c);
HB_ICU_STMT (U16_GET_UNSAFE (recomposed, 0, c));
if (c != *a && c != ab) {
*a = c;
*b = 0;
@ -284,7 +287,7 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
} else {
/* If decomposed to more than two characters, take the last one,
* and recompose the rest to get the first component. */
U16_PREV_UNSAFE (normalized, len, *b); /* Changes len in-place. */
HB_ICU_STMT (U16_PREV_UNSAFE (normalized, len, *b)); /* Changes len in-place. */
UChar recomposed[18 * 2];
icu_err = U_ZERO_ERROR;
len = unorm2_normalize (unorm2_getNFCInstance (&icu_err), normalized, len, recomposed, ARRAY_LENGTH (recomposed), &icu_err);
@ -293,7 +296,7 @@ hb_icu_unicode_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
/* We expect that recomposed has exactly one character now. */
if (unlikely (u_countChar32 (recomposed, len) != 1))
return false;
U16_GET_UNSAFE (recomposed, 0, *a);
HB_ICU_STMT (U16_GET_UNSAFE (recomposed, 0, *a));
ret = true;
}

View File

@ -55,7 +55,6 @@
* type of .end()?
*/
/*
* Base classes for iterators.
*/
@ -120,9 +119,11 @@ struct hb_iter_t
iter_t operator << (const T v) && { **thiz() = v; ++*thiz(); return *thiz(); }
protected:
hb_iter_t () {}
hb_iter_t (const hb_iter_t &o HB_UNUSED) {}
void operator = (const hb_iter_t &o HB_UNUSED) {}
hb_iter_t () = default;
hb_iter_t (const hb_iter_t &o HB_UNUSED) = default;
hb_iter_t (hb_iter_t &&o HB_UNUSED) = default;
hb_iter_t& operator = (const hb_iter_t &o HB_UNUSED) = default;
hb_iter_t& operator = (hb_iter_t &&o HB_UNUSED) = default;
};
#define HB_ITER_USING(Name) \
@ -192,15 +193,15 @@ struct hb_iter_fallback_mixin_t
/* Termination: Implement __more__(), or __len__() if random-access. */
bool __more__ () const { return bool (thiz()->len ()); }
unsigned __len__ () const
{ iter_t c (*thiz()); unsigned l = 0; while (c) { c++; l++; }; return l; }
{ iter_t c (*thiz()); unsigned l = 0; while (c) { c++; l++; } return l; }
/* Advancing: Implement __next__(), or __forward__() if random-access. */
void __next__ () { *thiz() += 1; }
void __forward__ (unsigned n) { while (n--) ++*thiz(); }
void __forward__ (unsigned n) { while (*thiz() && n--) ++*thiz(); }
/* Rewinding: Implement __prev__() or __rewind__() if bidirectional. */
void __prev__ () { *thiz() -= 1; }
void __rewind__ (unsigned n) { while (n--) --*thiz(); }
void __rewind__ (unsigned n) { while (*thiz() && n--) --*thiz(); }
/* Range-based for: Implement __end__() if can be done faster,
* and operator!=. */
@ -215,9 +216,11 @@ struct hb_iter_fallback_mixin_t
}
protected:
hb_iter_fallback_mixin_t () {}
hb_iter_fallback_mixin_t (const hb_iter_fallback_mixin_t &o HB_UNUSED) {}
void operator = (const hb_iter_fallback_mixin_t &o HB_UNUSED) {}
hb_iter_fallback_mixin_t () = default;
hb_iter_fallback_mixin_t (const hb_iter_fallback_mixin_t &o HB_UNUSED) = default;
hb_iter_fallback_mixin_t (hb_iter_fallback_mixin_t &&o HB_UNUSED) = default;
hb_iter_fallback_mixin_t& operator = (const hb_iter_fallback_mixin_t &o HB_UNUSED) = default;
hb_iter_fallback_mixin_t& operator = (hb_iter_fallback_mixin_t &&o HB_UNUSED) = default;
};
template <typename iter_t, typename item_t = typename iter_t::__item_t__>
@ -226,11 +229,11 @@ struct hb_iter_with_fallback_t :
hb_iter_fallback_mixin_t<iter_t, item_t>
{
protected:
hb_iter_with_fallback_t () {}
hb_iter_with_fallback_t (const hb_iter_with_fallback_t &o HB_UNUSED) :
hb_iter_t<iter_t, item_t> (o),
hb_iter_fallback_mixin_t<iter_t, item_t> (o) {}
void operator = (const hb_iter_with_fallback_t &o HB_UNUSED) {}
hb_iter_with_fallback_t () = default;
hb_iter_with_fallback_t (const hb_iter_with_fallback_t &o HB_UNUSED) = default;
hb_iter_with_fallback_t (hb_iter_with_fallback_t &&o HB_UNUSED) = default;
hb_iter_with_fallback_t& operator = (const hb_iter_with_fallback_t &o HB_UNUSED) = default;
hb_iter_with_fallback_t& operator = (hb_iter_with_fallback_t &&o HB_UNUSED) = default;
};
/*
@ -243,8 +246,8 @@ template<typename Iter, typename Item>
struct hb_is_iterator_of
{
template <typename Item2 = Item>
static hb_true_t impl (hb_priority<2>, hb_iter_t<Iter, hb_type_identity<Item2>> *);
static hb_false_t impl (hb_priority<0>, const void *);
static hb_true_type impl (hb_priority<2>, hb_iter_t<Iter, hb_type_identity<Item2>> *);
static hb_false_type impl (hb_priority<0>, const void *);
public:
static constexpr bool value = decltype (impl (hb_prioritize, hb_declval (Iter*)))::value;
@ -260,10 +263,10 @@ struct hb_is_iterable
private:
template <typename U>
static auto impl (hb_priority<1>) -> decltype (hb_declval (U).iter (), hb_true_t ());
static auto impl (hb_priority<1>) -> decltype (hb_declval (U).iter (), hb_true_type ());
template <typename>
static hb_false_t impl (hb_priority<0>);
static hb_false_type impl (hb_priority<0>);
public:
static constexpr bool value = decltype (impl<T> (hb_prioritize))::value;
@ -277,9 +280,11 @@ struct hb_is_source_of
{
private:
template <typename Iter2 = Iter,
hb_enable_if (hb_is_convertible (typename Iter2::item_t, const Item &))>
static hb_true_t impl (hb_priority<2>);
static hb_false_t impl (hb_priority<0>);
hb_enable_if (hb_is_convertible (typename Iter2::item_t, hb_add_lvalue_reference<hb_add_const<Item>>))>
static hb_true_type impl (hb_priority<2>);
template <typename Iter2 = Iter>
static auto impl (hb_priority<1>) -> decltype (hb_declval (Iter2) >> hb_declval (Item &), hb_true_type ());
static hb_false_type impl (hb_priority<0>);
public:
static constexpr bool value = decltype (impl (hb_prioritize))::value;
@ -290,8 +295,12 @@ template<typename Iter, typename Item>
struct hb_is_sink_of
{
private:
static auto impl (hb_priority<2>) -> decltype (hb_declval (Iter) << hb_declval (Item), hb_true_t ());
static hb_false_t impl (hb_priority<0>);
template <typename Iter2 = Iter,
hb_enable_if (hb_is_convertible (typename Iter2::item_t, hb_add_lvalue_reference<Item>))>
static hb_true_type impl (hb_priority<2>);
template <typename Iter2 = Iter>
static auto impl (hb_priority<1>) -> decltype (hb_declval (Iter2) << hb_declval (Item), hb_true_type ());
static hb_false_type impl (hb_priority<0>);
public:
static constexpr bool value = decltype (impl (hb_prioritize))::value;
@ -339,16 +348,26 @@ operator | (Lhs&& lhs, Rhs&& rhs) HB_AUTO_RETURN (hb_forward<Rhs> (rhs) (hb_forw
/* hb_map(), hb_filter(), hb_reduce() */
template <typename Iter, typename Proj,
enum class hb_function_sortedness_t {
NOT_SORTED,
RETAINS_SORTING,
SORTED,
};
template <typename Iter, typename Proj, hb_function_sortedness_t Sorted,
hb_requires (hb_is_iterator (Iter))>
struct hb_map_iter_t :
hb_iter_t<hb_map_iter_t<Iter, Proj>,
hb_iter_t<hb_map_iter_t<Iter, Proj, Sorted>,
decltype (hb_get (hb_declval (Proj), *hb_declval (Iter)))>
{
hb_map_iter_t (const Iter& it, Proj f_) : it (it), f (f_) {}
typedef decltype (hb_get (hb_declval (Proj), *hb_declval (Iter))) __item_t__;
static constexpr bool is_random_access_iterator = Iter::is_random_access_iterator;
static constexpr bool is_sorted_iterator =
Sorted == hb_function_sortedness_t::SORTED ? true :
Sorted == hb_function_sortedness_t::RETAINS_SORTING ? Iter::is_sorted_iterator :
false;
__item_t__ __item__ () const { return hb_get (f.get (), *it); }
__item_t__ __item_at__ (unsigned i) const { return hb_get (f.get (), it[i]); }
bool __more__ () const { return bool (it); }
@ -359,23 +378,23 @@ struct hb_map_iter_t :
void __rewind__ (unsigned n) { it -= n; }
hb_map_iter_t __end__ () const { return hb_map_iter_t (it.end (), f); }
bool operator != (const hb_map_iter_t& o) const
{ return it != o.it || f != o.f; }
{ return it != o.it; }
private:
Iter it;
hb_reference_wrapper<Proj> f;
};
template <typename Proj>
template <typename Proj, hb_function_sortedness_t Sorted>
struct hb_map_iter_factory_t
{
hb_map_iter_factory_t (Proj f) : f (f) {}
template <typename Iter,
hb_requires (hb_is_iterator (Iter))>
hb_map_iter_t<Iter, Proj>
hb_map_iter_t<Iter, Proj, Sorted>
operator () (Iter it)
{ return hb_map_iter_t<Iter, Proj> (it, f); }
{ return hb_map_iter_t<Iter, Proj, Sorted> (it, f); }
private:
Proj f;
@ -383,11 +402,27 @@ struct hb_map_iter_factory_t
struct
{
template <typename Proj>
hb_map_iter_factory_t<Proj>
hb_map_iter_factory_t<Proj, hb_function_sortedness_t::NOT_SORTED>
operator () (Proj&& f) const
{ return hb_map_iter_factory_t<Proj> (f); }
{ return hb_map_iter_factory_t<Proj, hb_function_sortedness_t::NOT_SORTED> (f); }
}
HB_FUNCOBJ (hb_map);
struct
{
template <typename Proj>
hb_map_iter_factory_t<Proj, hb_function_sortedness_t::RETAINS_SORTING>
operator () (Proj&& f) const
{ return hb_map_iter_factory_t<Proj, hb_function_sortedness_t::RETAINS_SORTING> (f); }
}
HB_FUNCOBJ (hb_map_retains_sorting);
struct
{
template <typename Proj>
hb_map_iter_factory_t<Proj, hb_function_sortedness_t::SORTED>
operator () (Proj&& f) const
{ return hb_map_iter_factory_t<Proj, hb_function_sortedness_t::SORTED> (f); }
}
HB_FUNCOBJ (hb_map_sorted);
template <typename Iter, typename Pred, typename Proj,
hb_requires (hb_is_iterator (Iter))>
@ -403,10 +438,10 @@ struct hb_filter_iter_t :
__item_t__ __item__ () const { return *it; }
bool __more__ () const { return bool (it); }
void __next__ () { do ++it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); }
void __prev__ () { --it; }
void __prev__ () { do --it; while (it && !hb_has (p.get (), hb_get (f.get (), *it))); }
hb_filter_iter_t __end__ () const { return hb_filter_iter_t (it.end (), p, f); }
bool operator != (const hb_filter_iter_t& o) const
{ return it != o.it || p != o.p || f != o.f; }
{ return it != o.it; }
private:
Iter it;
@ -483,9 +518,32 @@ struct hb_zip_iter_t :
static constexpr bool is_random_access_iterator =
A::is_random_access_iterator &&
B::is_random_access_iterator;
static constexpr bool is_sorted_iterator =
A::is_sorted_iterator &&
B::is_sorted_iterator;
/* Note. The following categorization is only valid if A is strictly sorted,
* ie. does NOT have duplicates. Previously I tried to categorize sortedness
* more granularly, see commits:
*
* 513762849a683914fc266a17ddf38f133cccf072
* 4d3cf2adb669c345cc43832d11689271995e160a
*
* However, that was not enough, since hb_sorted_array_t, hb_sorted_vector_t,
* SortedArrayOf, etc all needed to be updated to add more variants. At that
* point I saw it not worth the effort, and instead we now deem all sorted
* collections as essentially strictly-sorted for the purposes of zip.
*
* The above assumption is not as bad as it sounds. Our "sorted" comes with
* no guarantees. It's just a contract, put in place to help you remember,
* and think about, whether an iterator you receive is expected to be
* sorted or not. As such, it's not perfect by definition, and should not
* be treated so. The inaccuracy here just errs in the direction of being
* more permissive, so your code compiles instead of erring on the side of
* marking your zipped iterator unsorted in which case your code won't
* compile.
*
* This semantical limitation does NOT affect logic in any other place I
* know of as of this writing.
*/
static constexpr bool is_sorted_iterator = A::is_sorted_iterator;
__item_t__ __item__ () const { return __item_t__ (*a, *b); }
__item_t__ __item_at__ (unsigned i) const { return __item_t__ (a[i], b[i]); }
bool __more__ () const { return bool (a) && bool (b); }
@ -495,6 +553,8 @@ struct hb_zip_iter_t :
void __prev__ () { --a; --b; }
void __rewind__ (unsigned n) { a -= n; b -= n; }
hb_zip_iter_t __end__ () const { return hb_zip_iter_t (a.end (), b.end ()); }
/* Note, we should stop if ANY of the iters reaches end. As such two compare
* unequal if both items are unequal, NOT if either is unequal. */
bool operator != (const hb_zip_iter_t& o) const
{ return a != o.a && b != o.b; }
@ -563,7 +623,7 @@ struct hb_counter_iter_t :
void __rewind__ (unsigned n) { v -= n * step; }
hb_counter_iter_t __end__ () const { return hb_counter_iter_t (end_, end_, step); }
bool operator != (const hb_counter_iter_t& o) const
{ return v != o.v || end_ != o.end_ || step != o.step; }
{ return v != o.v; }
private:
static inline T end_for (T start, T end_, S step)

View File

@ -43,8 +43,8 @@ struct hb_hashmap_t
hb_hashmap_t () { init (); }
~hb_hashmap_t () { fini (); }
static_assert (hb_is_integer (K) || hb_is_pointer (K), "");
static_assert (hb_is_integer (V) || hb_is_pointer (V), "");
static_assert (hb_is_integral (K) || hb_is_pointer (K), "");
static_assert (hb_is_integral (V) || hb_is_pointer (V), "");
/* TODO If key type is a pointer, keep hash in item_t and use to:
* 1. avoid rehashing when resizing table, and

View File

@ -35,21 +35,19 @@
*/
/* Void! For when we need a expression-type of void. */
struct hb_void_t { typedef void value; };
struct hb_empty_t {};
/* Void meta-function ala std::void_t
* https://en.cppreference.com/w/cpp/types/void_t */
template<typename... Ts> struct _hb_void_tt { typedef void type; };
template<typename... Ts> using hb_void_tt = typename _hb_void_tt<Ts...>::type;
/* https://en.cppreference.com/w/cpp/types/void_t */
template<typename... Ts> struct _hb_void_t { typedef void type; };
template<typename... Ts> using hb_void_t = typename _hb_void_t<Ts...>::type;
template<typename Head, typename... Ts> struct _hb_head_tt { typedef Head type; };
template<typename... Ts> using hb_head_tt = typename _hb_head_tt<Ts...>::type;
template<typename Head, typename... Ts> struct _hb_head_t { typedef Head type; };
template<typename... Ts> using hb_head_t = typename _hb_head_t<Ts...>::type;
/* Bool! For when we need to evaluate type-dependent expressions
* in a template argument. */
template <bool b> struct hb_bool_tt { static constexpr bool value = b; };
typedef hb_bool_tt<true> hb_true_t;
typedef hb_bool_tt<false> hb_false_t;
template <typename T, T v> struct hb_integral_constant { static constexpr T value = v; };
template <bool b> using hb_bool_constant = hb_integral_constant<bool, b>;
using hb_true_type = hb_bool_constant<true>;
using hb_false_type = hb_bool_constant<false>;
/* Basic type SFINAE. */
@ -60,15 +58,15 @@ template <typename T> struct hb_enable_if<true, T> { typedef T ty
/* Concepts/Requires alias: */
#define hb_requires(Cond) hb_enable_if((Cond))
template <typename T, typename T2> struct hb_is_same : hb_false_t {};
template <typename T> struct hb_is_same<T, T> : hb_true_t {};
template <typename T, typename T2> struct hb_is_same : hb_false_type {};
template <typename T> struct hb_is_same<T, T> : hb_true_type {};
#define hb_is_same(T, T2) hb_is_same<T, T2>::value
/* Function overloading SFINAE and priority. */
#define HB_RETURN(Ret, E) -> hb_head_tt<Ret, decltype ((E))> { return (E); }
#define HB_RETURN(Ret, E) -> hb_head_t<Ret, decltype ((E))> { return (E); }
#define HB_AUTO_RETURN(E) -> decltype ((E)) { return (E); }
#define HB_VOID_RETURN(E) -> hb_void_tt<decltype ((E))> { (E); }
#define HB_VOID_RETURN(E) -> hb_void_t<decltype ((E))> { (E); }
template <unsigned Pri> struct hb_priority : hb_priority<Pri - 1> {};
template <> struct hb_priority<0> {};
@ -77,8 +75,8 @@ template <> struct hb_priority<0> {};
#define HB_FUNCOBJ(x) static_const x HB_UNUSED
template <typename T> struct hb_match_identity { typedef T type; };
template <typename T> using hb_type_identity = typename hb_match_identity<T>::type;
template <typename T> struct hb_type_identity_t { typedef T type; };
template <typename T> using hb_type_identity = typename hb_type_identity_t<T>::type;
struct
{
@ -99,20 +97,31 @@ HB_FUNCOBJ (hb_addressof);
template <typename T> static inline T hb_declval ();
#define hb_declval(T) (hb_declval<T> ())
template <typename T> struct hb_match_const { typedef T type; static constexpr bool value = false; };
template <typename T> struct hb_match_const<const T> { typedef T type; static constexpr bool value = true; };
template <typename T> struct hb_match_const : hb_type_identity_t<T>, hb_bool_constant<false>{};
template <typename T> struct hb_match_const<const T> : hb_type_identity_t<T>, hb_bool_constant<true> {};
template <typename T> using hb_remove_const = typename hb_match_const<T>::type;
template <typename T> using hb_add_const = const T;
#define hb_is_const(T) hb_match_const<T>::value
template <typename T> struct hb_match_reference { typedef T type; static constexpr bool value = false; };
template <typename T> struct hb_match_reference<T &> { typedef T type; static constexpr bool value = true; };
template <typename T> struct hb_match_reference<T &&> { typedef T type; static constexpr bool value = true; };
template <typename T> struct hb_match_reference : hb_type_identity_t<T>, hb_bool_constant<false>{};
template <typename T> struct hb_match_reference<T &> : hb_type_identity_t<T>, hb_bool_constant<true> {};
template <typename T> struct hb_match_reference<T &&> : hb_type_identity_t<T>, hb_bool_constant<true> {};
template <typename T> using hb_remove_reference = typename hb_match_reference<T>::type;
template <typename T> auto _hb_try_add_lvalue_reference (hb_priority<1>) -> hb_type_identity<T&>;
template <typename T> auto _hb_try_add_lvalue_reference (hb_priority<0>) -> hb_type_identity<T>;
template <typename T> using hb_add_lvalue_reference = decltype (_hb_try_add_lvalue_reference<T> (hb_prioritize));
template <typename T> auto _hb_try_add_rvalue_reference (hb_priority<1>) -> hb_type_identity<T&&>;
template <typename T> auto _hb_try_add_rvalue_reference (hb_priority<0>) -> hb_type_identity<T>;
template <typename T> using hb_add_rvalue_reference = decltype (_hb_try_add_rvalue_reference<T> (hb_prioritize));
#define hb_is_reference(T) hb_match_reference<T>::value
template <typename T> struct hb_match_pointer { typedef T type; static constexpr bool value = false; };
template <typename T> struct hb_match_pointer<T *> { typedef T type; static constexpr bool value = true; };
template <typename T> struct hb_match_pointer : hb_type_identity_t<T>, hb_bool_constant<false>{};
template <typename T> struct hb_match_pointer<T *> : hb_type_identity_t<T>, hb_bool_constant<true> {};
template <typename T> using hb_remove_pointer = typename hb_match_pointer<T>::type;
template <typename T> auto _hb_try_add_pointer (hb_priority<1>) -> hb_type_identity<hb_remove_reference<T>*>;
template <typename T> auto _hb_try_add_pointer (hb_priority<1>) -> hb_type_identity<T>;
template <typename T> using hb_add_pointer = decltype (_hb_try_add_pointer<T> (hb_prioritize));
#define hb_is_pointer(T) hb_match_pointer<T>::value
/* TODO Add feature-parity to std::decay. */
template <typename T> using hb_decay = hb_remove_const<hb_remove_reference<T>>;
@ -134,12 +143,12 @@ struct hb_is_convertible
static constexpr bool either_void = from_void || to_void;
static constexpr bool both_void = from_void && to_void;
static hb_true_t impl2 (hb_conditional<to_void, int, To>);
static hb_true_type impl2 (hb_conditional<to_void, int, To>);
template <typename T>
static auto impl (hb_priority<1>) -> decltype (impl2 (hb_declval (T)));
template <typename T>
static hb_false_t impl (hb_priority<0>);
static hb_false_type impl (hb_priority<0>);
public:
static constexpr bool value = both_void ||
(!either_void &&
@ -147,15 +156,16 @@ struct hb_is_convertible
};
#define hb_is_convertible(From,To) hb_is_convertible<From, To>::value
template <typename Base, typename Derived>
using hb_is_base_of = hb_is_convertible<hb_decay<Derived> *, hb_decay<Base> *>;
#define hb_is_base_of(Base,Derived) hb_is_base_of<Base, Derived>::value
template <typename From, typename To>
struct hb_is_cr_convertible
{
public:
static constexpr bool value =
hb_is_same (hb_decay<From>, hb_decay<To>) &&
(!hb_is_const (From) || hb_is_const (To)) &&
(!hb_is_reference (To) || hb_is_const (To) || hb_is_reference (To));
};
using hb_is_cr_convertible = hb_bool_constant<
hb_is_same (hb_decay<From>, hb_decay<To>) &&
(!hb_is_const (From) || hb_is_const (To)) &&
(!hb_is_reference (To) || hb_is_const (To) || hb_is_reference (To))
>;
#define hb_is_cr_convertible(From,To) hb_is_cr_convertible<From, To>::value
/* std::move and std::forward */
@ -210,65 +220,181 @@ struct hb_reference_wrapper<T&>
};
template <typename T> struct hb_is_signed;
template <> struct hb_is_signed<char> { static constexpr bool value = CHAR_MIN < 0; };
template <> struct hb_is_signed<signed char> { static constexpr bool value = true; };
template <> struct hb_is_signed<unsigned char> { static constexpr bool value = false; };
template <> struct hb_is_signed<signed short> { static constexpr bool value = true; };
template <> struct hb_is_signed<unsigned short> { static constexpr bool value = false; };
template <> struct hb_is_signed<signed int> { static constexpr bool value = true; };
template <> struct hb_is_signed<unsigned int> { static constexpr bool value = false; };
template <> struct hb_is_signed<signed long> { static constexpr bool value = true; };
template <> struct hb_is_signed<unsigned long> { static constexpr bool value = false; };
template <> struct hb_is_signed<signed long long> { static constexpr bool value = true; };
template <> struct hb_is_signed<unsigned long long> { static constexpr bool value = false; };
template <typename T>
using hb_is_integral = hb_bool_constant<
hb_is_same (hb_decay<T>, char) ||
hb_is_same (hb_decay<T>, signed char) ||
hb_is_same (hb_decay<T>, unsigned char) ||
hb_is_same (hb_decay<T>, signed int) ||
hb_is_same (hb_decay<T>, unsigned int) ||
hb_is_same (hb_decay<T>, signed short) ||
hb_is_same (hb_decay<T>, unsigned short) ||
hb_is_same (hb_decay<T>, signed long) ||
hb_is_same (hb_decay<T>, unsigned long) ||
hb_is_same (hb_decay<T>, signed long long) ||
hb_is_same (hb_decay<T>, unsigned long long) ||
false
>;
#define hb_is_integral(T) hb_is_integral<T>::value
template <typename T>
using hb_is_floating_point = hb_bool_constant<
hb_is_same (hb_decay<T>, float) ||
hb_is_same (hb_decay<T>, double) ||
hb_is_same (hb_decay<T>, long double) ||
false
>;
#define hb_is_floating_point(T) hb_is_floating_point<T>::value
template <typename T>
using hb_is_arithmetic = hb_bool_constant<
hb_is_integral (T) ||
hb_is_floating_point (T) ||
false
>;
#define hb_is_arithmetic(T) hb_is_arithmetic<T>::value
template <typename T>
using hb_is_signed = hb_conditional<hb_is_arithmetic (T),
hb_bool_constant<(T) -1 < (T) 0>,
hb_false_type>;
#define hb_is_signed(T) hb_is_signed<T>::value
template <typename T>
using hb_is_unsigned = hb_conditional<hb_is_arithmetic (T),
hb_bool_constant<(T) 0 < (T) -1>,
hb_false_type>;
#define hb_is_unsigned(T) hb_is_unsigned<T>::value
template <typename T> struct hb_int_min;
template <> struct hb_int_min<char> { static constexpr char value = CHAR_MIN; };
template <> struct hb_int_min<signed char> { static constexpr signed char value = SCHAR_MIN; };
template <> struct hb_int_min<unsigned char> { static constexpr unsigned char value = 0; };
template <> struct hb_int_min<signed short> { static constexpr signed short value = SHRT_MIN; };
template <> struct hb_int_min<unsigned short> { static constexpr unsigned short value = 0; };
template <> struct hb_int_min<signed int> { static constexpr signed int value = INT_MIN; };
template <> struct hb_int_min<unsigned int> { static constexpr unsigned int value = 0; };
template <> struct hb_int_min<signed long> { static constexpr signed long value = LONG_MIN; };
template <> struct hb_int_min<unsigned long> { static constexpr unsigned long value = 0; };
template <> struct hb_int_min<signed long long> { static constexpr signed long long value = LLONG_MIN; };
template <> struct hb_int_min<unsigned long long> { static constexpr unsigned long long value = 0; };
template <> struct hb_int_min<char> : hb_integral_constant<char, CHAR_MIN> {};
template <> struct hb_int_min<signed char> : hb_integral_constant<signed char, SCHAR_MIN> {};
template <> struct hb_int_min<unsigned char> : hb_integral_constant<unsigned char, 0> {};
template <> struct hb_int_min<signed short> : hb_integral_constant<signed short, SHRT_MIN> {};
template <> struct hb_int_min<unsigned short> : hb_integral_constant<unsigned short, 0> {};
template <> struct hb_int_min<signed int> : hb_integral_constant<signed int, INT_MIN> {};
template <> struct hb_int_min<unsigned int> : hb_integral_constant<unsigned int, 0> {};
template <> struct hb_int_min<signed long> : hb_integral_constant<signed long, LONG_MIN> {};
template <> struct hb_int_min<unsigned long> : hb_integral_constant<unsigned long, 0> {};
template <> struct hb_int_min<signed long long> : hb_integral_constant<signed long long, LLONG_MIN> {};
template <> struct hb_int_min<unsigned long long> : hb_integral_constant<unsigned long long, 0> {};
#define hb_int_min(T) hb_int_min<T>::value
template <typename T> struct hb_int_max;
template <> struct hb_int_max<char> { static constexpr char value = CHAR_MAX; };
template <> struct hb_int_max<signed char> { static constexpr signed char value = SCHAR_MAX; };
template <> struct hb_int_max<unsigned char> { static constexpr unsigned char value = UCHAR_MAX; };
template <> struct hb_int_max<signed short> { static constexpr signed short value = SHRT_MAX; };
template <> struct hb_int_max<unsigned short> { static constexpr unsigned short value = USHRT_MAX; };
template <> struct hb_int_max<signed int> { static constexpr signed int value = INT_MAX; };
template <> struct hb_int_max<unsigned int> { static constexpr unsigned int value = UINT_MAX; };
template <> struct hb_int_max<signed long> { static constexpr signed long value = LONG_MAX; };
template <> struct hb_int_max<unsigned long> { static constexpr unsigned long value = ULONG_MAX; };
template <> struct hb_int_max<signed long long> { static constexpr signed long long value = LLONG_MAX; };
template <> struct hb_int_max<unsigned long long> { static constexpr unsigned long long value = ULLONG_MAX; };
template <> struct hb_int_max<char> : hb_integral_constant<char, CHAR_MAX> {};
template <> struct hb_int_max<signed char> : hb_integral_constant<signed char, SCHAR_MAX> {};
template <> struct hb_int_max<unsigned char> : hb_integral_constant<unsigned char, UCHAR_MAX> {};
template <> struct hb_int_max<signed short> : hb_integral_constant<signed short, SHRT_MAX> {};
template <> struct hb_int_max<unsigned short> : hb_integral_constant<unsigned short, USHRT_MAX> {};
template <> struct hb_int_max<signed int> : hb_integral_constant<signed int, INT_MAX> {};
template <> struct hb_int_max<unsigned int> : hb_integral_constant<unsigned int, UINT_MAX> {};
template <> struct hb_int_max<signed long> : hb_integral_constant<signed long, LONG_MAX> {};
template <> struct hb_int_max<unsigned long> : hb_integral_constant<unsigned long, ULONG_MAX> {};
template <> struct hb_int_max<signed long long> : hb_integral_constant<signed long long, LLONG_MAX> {};
template <> struct hb_int_max<unsigned long long> : hb_integral_constant<unsigned long long, ULLONG_MAX> {};
#define hb_int_max(T) hb_int_max<T>::value
template <bool is_signed> struct hb_signedness_int;
template <> struct hb_signedness_int<false> { typedef unsigned int value; };
template <> struct hb_signedness_int<true> { typedef signed int value; };
#define hb_signedness_int(T) hb_signedness_int<T>::value
template <typename T> struct hb_is_integer { static constexpr bool value = false;};
template <> struct hb_is_integer<char> { static constexpr bool value = true; };
template <> struct hb_is_integer<signed char> { static constexpr bool value = true; };
template <> struct hb_is_integer<unsigned char> { static constexpr bool value = true; };
template <> struct hb_is_integer<signed short> { static constexpr bool value = true; };
template <> struct hb_is_integer<unsigned short> { static constexpr bool value = true; };
template <> struct hb_is_integer<signed int> { static constexpr bool value = true; };
template <> struct hb_is_integer<unsigned int> { static constexpr bool value = true; };
template <> struct hb_is_integer<signed long> { static constexpr bool value = true; };
template <> struct hb_is_integer<unsigned long> { static constexpr bool value = true; };
template <> struct hb_is_integer<signed long long> { static constexpr bool value = true; };
template <> struct hb_is_integer<unsigned long long> { static constexpr bool value = true; };
#define hb_is_integer(T) hb_is_integer<T>::value
template <typename T, typename>
struct _hb_is_destructible : hb_false_type {};
template <typename T>
struct _hb_is_destructible<T, hb_void_t<decltype (hb_declval (T).~T ())>> : hb_true_type {};
template <typename T>
using hb_is_destructible = _hb_is_destructible<T, void>;
#define hb_is_destructible(T) hb_is_destructible<T>::value
template <typename T, typename, typename ...Ts>
struct _hb_is_constructible : hb_false_type {};
template <typename T, typename ...Ts>
struct _hb_is_constructible<T, hb_void_t<decltype (T (hb_declval (Ts)...))>, Ts...> : hb_true_type {};
template <typename T, typename ...Ts>
using hb_is_constructible = _hb_is_constructible<T, void, Ts...>;
#define hb_is_constructible(...) hb_is_constructible<__VA_ARGS__>::value
template <typename T>
using hb_is_default_constructible = hb_is_constructible<T>;
#define hb_is_default_constructible(T) hb_is_default_constructible<T>::value
template <typename T>
using hb_is_copy_constructible = hb_is_constructible<T, hb_add_lvalue_reference<hb_add_const<T>>>;
#define hb_is_copy_constructible(T) hb_is_copy_constructible<T>::value
template <typename T>
using hb_is_move_constructible = hb_is_constructible<T, hb_add_rvalue_reference<hb_add_const<T>>>;
#define hb_is_move_constructible(T) hb_is_move_constructible<T>::value
template <typename T, typename U, typename>
struct _hb_is_assignable : hb_false_type {};
template <typename T, typename U>
struct _hb_is_assignable<T, U, hb_void_t<decltype (hb_declval (T) = hb_declval (U))>> : hb_true_type {};
template <typename T, typename U>
using hb_is_assignable = _hb_is_assignable<T, U, void>;
#define hb_is_assignable(T,U) hb_is_assignable<T, U>::value
template <typename T>
using hb_is_copy_assignable = hb_is_assignable<hb_add_lvalue_reference<T>,
hb_add_lvalue_reference<hb_add_const<T>>>;
#define hb_is_copy_assignable(T) hb_is_copy_assignable<T>::value
template <typename T>
using hb_is_move_assignable = hb_is_assignable<hb_add_lvalue_reference<T>,
hb_add_rvalue_reference<T>>;
#define hb_is_move_assignable(T) hb_is_move_assignable<T>::value
/* Trivial versions. */
template <typename T> union hb_trivial { T value; };
/* Don't know how to do the following. */
template <typename T>
using hb_is_trivially_destructible= hb_is_destructible<hb_trivial<T>>;
#define hb_is_trivially_destructible(T) hb_is_trivially_destructible<T>::value
/* Don't know how to do the following. */
//template <typename T, typename ...Ts>
//using hb_is_trivially_constructible= hb_is_constructible<hb_trivial<T>, hb_trivial<Ts>...>;
//#define hb_is_trivially_constructible(...) hb_is_trivially_constructible<__VA_ARGS__>::value
template <typename T>
using hb_is_trivially_default_constructible= hb_is_default_constructible<hb_trivial<T>>;
#define hb_is_trivially_default_constructible(T) hb_is_trivially_default_constructible<T>::value
template <typename T>
using hb_is_trivially_copy_constructible= hb_is_copy_constructible<hb_trivial<T>>;
#define hb_is_trivially_copy_constructible(T) hb_is_trivially_copy_constructible<T>::value
template <typename T>
using hb_is_trivially_move_constructible= hb_is_move_constructible<hb_trivial<T>>;
#define hb_is_trivially_move_constructible(T) hb_is_trivially_move_constructible<T>::value
/* Don't know how to do the following. */
//template <typename T, typename U>
//using hb_is_trivially_assignable= hb_is_assignable<hb_trivial<T>, hb_trivial<U>>;
//#define hb_is_trivially_assignable(T,U) hb_is_trivially_assignable<T, U>::value
template <typename T>
using hb_is_trivially_copy_assignable= hb_is_copy_assignable<hb_trivial<T>>;
#define hb_is_trivially_copy_assignable(T) hb_is_trivially_copy_assignable<T>::value
template <typename T>
using hb_is_trivially_move_assignable= hb_is_move_assignable<hb_trivial<T>>;
#define hb_is_trivially_move_assignable(T) hb_is_trivially_move_assignable<T>::value
template <typename T>
using hb_is_trivially_copyable= hb_bool_constant<
hb_is_trivially_destructible (T) &&
(!hb_is_move_assignable (T) || hb_is_trivially_move_assignable (T)) &&
(!hb_is_move_constructible (T) || hb_is_trivially_move_constructible (T)) &&
(!hb_is_copy_assignable (T) || hb_is_trivially_copy_assignable (T)) &&
(!hb_is_copy_constructible (T) || hb_is_trivially_copy_constructible (T)) &&
true
>;
#define hb_is_trivially_copyable(T) hb_is_trivially_copyable<T>::value
template <typename T>
using hb_is_trivial= hb_bool_constant<
hb_is_trivially_copyable (T) &&
hb_is_trivially_default_constructible (T)
>;
#define hb_is_trivial(T) hb_is_trivial<T>::value
#endif /* HB_META_HH */

View File

@ -46,16 +46,13 @@
* https://stackoverflow.com/questions/7776448/sfinae-tried-with-bool-gives-compiler-error-template-argument-tvalue-invol
*/
template <typename T, typename B>
struct _hb_null_size
{ enum { value = sizeof (T) }; };
template <typename T, typename>
struct _hb_null_size : hb_integral_constant<unsigned, sizeof (T)> {};
template <typename T>
struct _hb_null_size<T, hb_bool_tt<true || sizeof (T::min_size)>>
{ enum { value = T::null_size }; };
struct _hb_null_size<T, hb_void_t<decltype (T::min_size)>> : hb_integral_constant<unsigned, T::null_size> {};
template <typename T>
struct hb_null_size
{ enum { value = _hb_null_size<T, hb_true_t>::value }; };
using hb_null_size = _hb_null_size<T, void>;
#define hb_null_size(T) hb_null_size<T>::value
/* These doesn't belong here, but since is copy/paste from above, put it here. */
@ -63,16 +60,12 @@ struct hb_null_size
/* hb_static_size (T)
* Returns T::static_size if T::min_size is defined, or sizeof (T) otherwise. */
template <typename T, typename B>
struct _hb_static_size
{ enum { value = sizeof (T) }; };
template <typename T, typename>
struct _hb_static_size : hb_integral_constant<unsigned, sizeof (T)> {};
template <typename T>
struct _hb_static_size<T, hb_bool_tt<true || sizeof (T::min_size)>>
{ enum { value = T::static_size }; };
struct _hb_static_size<T, hb_void_t<decltype (T::min_size)>> : hb_integral_constant<unsigned, T::static_size> {};
template <typename T>
struct hb_static_size
{ enum { value = _hb_static_size<T, hb_true_t>::value }; };
using hb_static_size = _hb_static_size<T, void>;
#define hb_static_size(T) hb_static_size<T>::value

View File

@ -57,7 +57,7 @@ template <typename Type, unsigned int Size>
struct IntType
{
typedef Type type;
typedef typename hb_signedness_int (hb_is_signed (Type)) wide_type;
typedef hb_conditional<hb_is_signed (Type), signed, unsigned> wide_type;
IntType<Type, Size>& operator = (wide_type i) { v = i; return *this; }
operator wide_type () const { return v; }
@ -279,6 +279,19 @@ struct OffsetTo : Offset<OffsetType, has_null>
return StructAtOffset<Type> (base, *this);
}
template <typename Base,
hb_enable_if (hb_is_convertible (const Base, const void *))>
friend const Type& operator + (const Base &base, const OffsetTo &offset) { return offset ((const void *) base); }
template <typename Base,
hb_enable_if (hb_is_convertible (const Base, const void *))>
friend const Type& operator + (const OffsetTo &offset, const Base &base) { return offset ((const void *) base); }
template <typename Base,
hb_enable_if (hb_is_convertible (Base, void *))>
friend Type& operator + (Base &&base, OffsetTo &offset) { return offset ((void *) base); }
template <typename Base,
hb_enable_if (hb_is_convertible (Base, void *))>
friend Type& operator + (OffsetTo &offset, Base &&base) { return offset ((void *) base); }
Type& serialize (hb_serialize_context_t *c, const void *base)
{
return * (Type *) Offset<OffsetType>::serialize (c, base);
@ -357,11 +370,6 @@ using NNOffsetTo = OffsetTo<Type, OffsetType, false>;
template <typename Type>
using LNNOffsetTo = LOffsetTo<Type, false>;
template <typename Base, typename OffsetType, bool has_null, typename Type>
static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType, has_null> &offset) { return offset (base); }
template <typename Base, typename OffsetType, bool has_null, typename Type>
static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType, has_null> &offset) { return offset (base); }
/*
* Array Types
@ -440,33 +448,12 @@ struct UnsizedArrayOf
return_trace (out);
}
bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
{
TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
/* Note: for structs that do not reference other structs,
* we do not need to call their sanitize() as we already did
* a bound check on the aggregate array size. We just include
* a small unreachable expression to make sure the structs
* pointed to do have a simple sanitize() as well as an
* assignment opreator. This ensures that they do not
* reference other structs via offsets.
*/
if (false)
{
arrayZ[0].sanitize (c);
Type v;
v = arrayZ[0];
}
return_trace (true);
}
template <typename ...Ts>
bool sanitize (hb_sanitize_context_t *c, unsigned int count, Ts&&... ds) const
{
TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true);
for (unsigned int i = 0; i < count; i++)
if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...)))
return_trace (false);
@ -621,33 +608,12 @@ struct ArrayOf
return_trace (out);
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return_trace (false);
/* Note: for structs that do not reference other structs,
* we do not need to call their sanitize() as we already did
* a bound check on the aggregate array size. We just include
* a small unreachable expression to make sure the structs
* pointed to do have a simple sanitize() as well as an
* assignment opreator. This ensures that they do not
* reference other structs via offsets.
*/
if (false)
{
arrayZ[0].sanitize (c);
Type v;
v = arrayZ[0];
}
return_trace (true);
}
template <typename ...Ts>
bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
{
TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return_trace (false);
if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true);
unsigned int count = len;
for (unsigned int i = 0; i < count; i++)
if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...)))
@ -760,26 +726,16 @@ struct HeadlessArrayOf
return_trace (true);
}
bool sanitize (hb_sanitize_context_t *c) const
template <typename ...Ts>
bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
{
TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return_trace (false);
/* Note: for structs that do not reference other structs,
* we do not need to call their sanitize() as we already did
* a bound check on the aggregate array size. We just include
* a small unreachable expression to make sure the structs
* pointed to do have a simple sanitize() as well as an
* assignment opreator. This ensures that they do not
* reference other structs via offsets.
*/
if (false)
{
arrayZ[0].sanitize (c);
Type v;
v = arrayZ[0];
}
if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true);
unsigned int count = lenP1 ? lenP1 - 1 : 0;
for (unsigned int i = 0; i < count; i++)
if (unlikely (!c->dispatch (arrayZ[i], hb_forward<Ts> (ds)...)))
return_trace (false);
return_trace (true);
}
@ -1001,33 +957,12 @@ struct VarSizedBinSearchArrayOf
unsigned int get_size () const
{ return header.static_size + header.nUnits * header.unitSize; }
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return_trace (false);
/* Note: for structs that do not reference other structs,
* we do not need to call their sanitize() as we already did
* a bound check on the aggregate array size. We just include
* a small unreachable expression to make sure the structs
* pointed to do have a simple sanitize() as well as an
* assignment opreator. This ensures that they do not
* reference other structs via offsets.
*/
if (false)
{
(*this)[0].sanitize (c);
Type v;
v = (*this)[0];
}
return_trace (true);
}
template <typename ...Ts>
bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
{
TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return_trace (false);
if (!sizeof... (Ts) && hb_is_trivially_copyable (Type)) return_trace (true);
unsigned int count = get_length ();
for (unsigned int i = 0; i < count; i++)
if (unlikely (!(*this)[i].sanitize (c, hb_forward<Ts> (ds)...)))

View File

@ -97,12 +97,12 @@ struct CFFIndex
unsigned int offset_array_size () const
{ return calculate_offset_array_size (offSize, count); }
static unsigned int calculate_serialized_size (unsigned int offSize, unsigned int count, unsigned int dataSize)
static unsigned int calculate_serialized_size (unsigned int offSize_, unsigned int count, unsigned int dataSize)
{
if (count == 0)
return COUNT::static_size;
else
return min_size + calculate_offset_array_size (offSize, count) + dataSize;
return min_size + calculate_offset_array_size (offSize_, count) + dataSize;
}
bool serialize (hb_serialize_context_t *c, const CFFIndex &src)
@ -167,7 +167,7 @@ struct CFFIndex
byteArray.resize (buffArray.length);
for (unsigned int i = 0; i < byteArray.length; i++)
{
byteArray[i] = byte_str_t (buffArray[i].arrayZ (), buffArray[i].length);
byteArray[i] = byte_str_t (buffArray[i].arrayZ, buffArray[i].length);
}
bool result = this->serialize (c, offSize_, byteArray);
byteArray.fini ();

View File

@ -27,6 +27,8 @@
#include "hb-ot-cff1-table.hh"
#include "hb-cff1-interp-cs.hh"
#ifndef HB_NO_CFF
using namespace CFF;
/* SID to code */
@ -305,6 +307,11 @@ bool _get_bounds (const OT::cff1::accelerator_t *cff, hb_codepoint_t glyph, boun
bool OT::cff1::accelerator_t::get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
{
#ifdef HB_NO_OT_FONT_CFF
/* XXX Remove check when this code moves to .hh file. */
return true;
#endif
bounds_t bounds;
if (!_get_bounds (this, glyph, bounds))
@ -383,3 +390,5 @@ bool OT::cff1::accelerator_t::get_seac_components (hb_codepoint_t glyph, hb_code
}
return false;
}
#endif

View File

@ -599,9 +599,9 @@ struct CFF1StringIndex : CFF1Index
}
/* in parallel to above */
unsigned int calculate_serialized_size (unsigned int &offSize /*OUT*/, const remap_t &sidmap) const
unsigned int calculate_serialized_size (unsigned int &offSize_ /*OUT*/, const remap_t &sidmap) const
{
offSize = 0;
offSize_ = 0;
if ((count == 0) || (sidmap.get_count () == 0))
return count.static_size;
@ -610,8 +610,8 @@ struct CFF1StringIndex : CFF1Index
if (sidmap[i] != CFF_UNDEF_CODE)
dataSize += length_at (i);
offSize = calcOffSize(dataSize);
return CFF1Index::calculate_serialized_size (offSize, sidmap.get_count (), dataSize);
offSize_ = calcOffSize(dataSize);
return CFF1Index::calculate_serialized_size (offSize_, sidmap.get_count (), dataSize);
}
};

View File

@ -27,6 +27,8 @@
#include "hb-ot-cff2-table.hh"
#include "hb-cff2-interp-cs.hh"
#ifndef HB_NO_OT_FONT_CFF
using namespace CFF;
struct extents_param_t
@ -99,6 +101,11 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
hb_codepoint_t glyph,
hb_glyph_extents_t *extents) const
{
#ifdef HB_NO_OT_FONT_CFF
/* XXX Remove check when this code moves to .hh file. */
return true;
#endif
if (unlikely (!is_valid () || (glyph >= num_glyphs))) return false;
unsigned int num_coords;
@ -134,3 +141,5 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
return true;
}
#endif

View File

@ -518,25 +518,25 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
bool serialize (hb_serialize_context_t *c,
const hb_sorted_vector_t<CmapSubtableLongGroup> &groups)
const hb_sorted_vector_t<CmapSubtableLongGroup> &groups_data)
{
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return_trace (false);
this->format = 12;
this->reserved = 0;
this->length = get_sub_table_size (groups);
this->length = get_sub_table_size (groups_data);
return_trace (CmapSubtableLongSegmented<CmapSubtableFormat12>::serialize (c, groups));
return_trace (CmapSubtableLongSegmented<CmapSubtableFormat12>::serialize (c, groups_data));
}
static size_t get_sub_table_size (const hb_sorted_vector_t<CmapSubtableLongGroup> &groups)
static size_t get_sub_table_size (const hb_sorted_vector_t<CmapSubtableLongGroup> &groups_data)
{
return 16 + 12 * groups.length;
return 16 + 12 * groups_data.length;
}
static bool create_sub_table_plan (const hb_subset_plan_t *plan,
hb_sorted_vector_t<CmapSubtableLongGroup> *groups)
hb_sorted_vector_t<CmapSubtableLongGroup> *groups_out)
{
CmapSubtableLongGroup *group = nullptr;
@ -551,7 +551,7 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
if (!group || !_is_gid_consecutive (group, cp, new_gid))
{
group = groups->push ();
group = groups_out->push ();
group->startCharCode = cp;
group->endCharCode = cp;
group->glyphID = new_gid;
@ -560,8 +560,8 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
}
DEBUG_MSG(SUBSET, nullptr, "cmap");
for (unsigned int i = 0; i < groups->length; i++) {
CmapSubtableLongGroup& group = (*groups)[i];
for (unsigned int i = 0; i < groups_out->length; i++) {
CmapSubtableLongGroup& group = (*groups_out)[i];
DEBUG_MSG(SUBSET, nullptr, " %d: U+%04X-U+%04X, gid %d-%d", i, (uint32_t) group.startCharCode, (uint32_t) group.endCharCode, (uint32_t) group.glyphID, (uint32_t) group.glyphID + ((uint32_t) group.endCharCode - (uint32_t) group.startCharCode));
}

View File

@ -47,6 +47,8 @@
* @include: hb-ot.h
*
* Functions for fetching color-font information from OpenType font faces.
*
* HarfBuzz supports `COLR`/`CPAL`, `sbix`, `CBDT`, and `SVG` color fonts.
**/
@ -57,42 +59,54 @@
/**
* hb_ot_color_has_palettes:
* @face: a font face.
* @face: #hb_face_t to work upon
*
* Returns: whether CPAL table is available.
* Tests whether a face includes a `CPAL` color-palette table.
*
* Return value: true if data found, false otherwise
*
* Since: 2.1.0
*/
hb_bool_t
hb_ot_color_has_palettes (hb_face_t *face)
{
#ifdef HB_NO_COLOR
return false;
#endif
return face->table.CPAL->has_data ();
}
/**
* hb_ot_color_palette_get_count:
* @face: a font face.
* @face: #hb_face_t to work upon
*
* Returns: the number of color palettes in @face, or zero if @face has
* no colors.
* Fetches the number of color palettes in a face.
*
* Return value: the number of palettes found
*
* Since: 2.1.0
*/
unsigned int
hb_ot_color_palette_get_count (hb_face_t *face)
{
#ifdef HB_NO_COLOR
return 0;
#endif
return face->table.CPAL->get_palette_count ();
}
/**
* hb_ot_color_palette_get_name_id:
* @face: a font face.
* @palette_index: the index of the color palette whose name is being requested.
* @face: #hb_face_t to work upon
* @palette_index: The index of the color palette
*
* Retrieves the name id of a color palette. For example, a color font can
* have themed palettes like "Spring", "Summer", "Fall", and "Winter".
* Fetches the `name` table Name ID that provides display names for
* a `CPAL` color palette.
*
* Returns: an identifier within @face's `name` table.
* Palette display names can be generic (e.g., "Default") or provide
* specific, themed names (e.g., "Spring", "Summer", "Fall", and "Winter").
*
* Return value: the Named ID found for the palette.
* If the requested palette has no name the result is #HB_OT_NAME_ID_INVALID.
*
* Since: 2.1.0
@ -101,15 +115,24 @@ hb_ot_name_id_t
hb_ot_color_palette_get_name_id (hb_face_t *face,
unsigned int palette_index)
{
#ifdef HB_NO_COLOR
return HB_OT_NAME_ID_INVALID;
#endif
return face->table.CPAL->get_palette_name_id (palette_index);
}
/**
* hb_ot_color_palette_color_get_name_id:
* @face: a font face.
* @color_index: palette entry index.
* @face: #hb_face_t to work upon
* @color_index: The index of the color
*
* Returns: Name ID associated with a palette entry, e.g. eye color
* Fetches the `name` table Name ID that provides display names for
* the specificed color in a face's `CPAL` color palette.
*
* Display names can be generic (e.g., "Background") or specific
* (e.g., "Eye color").
*
* Return value: the Name ID found for the color.
*
* Since: 2.1.0
*/
@ -117,15 +140,20 @@ hb_ot_name_id_t
hb_ot_color_palette_color_get_name_id (hb_face_t *face,
unsigned int color_index)
{
#ifdef HB_NO_COLOR
return HB_OT_NAME_ID_INVALID;
#endif
return face->table.CPAL->get_color_name_id (color_index);
}
/**
* hb_ot_color_palette_get_flags:
* @face: a font face
* @palette_index: the index of the color palette whose flags are being requested
* @face: #hb_face_t to work upon
* @palette_index: The index of the color palette
*
* Returns: the flags for the requested color palette.
* Fetches the flags defined for a color palette.
*
* Return value: the #hb_ot_color_palette_flags_t of the requested color palette
*
* Since: 2.1.0
*/
@ -133,30 +161,30 @@ hb_ot_color_palette_flags_t
hb_ot_color_palette_get_flags (hb_face_t *face,
unsigned int palette_index)
{
#ifdef HB_NO_COLOR
return HB_OT_COLOR_PALETTE_FLAG_DEFAULT;
#endif
return face->table.CPAL->get_palette_flags (palette_index);
}
/**
* hb_ot_color_palette_get_colors:
* @face: a font face.
* @palette_index:the index of the color palette whose colors
* are being requested.
* @start_offset: the index of the first color being requested.
* @color_count: (inout) (optional): on input, how many colors
* can be maximally stored into the @colors array;
* on output, how many colors were actually stored.
* @colors: (array length=color_count) (out) (optional):
* an array of #hb_color_t records. After calling
* this function, @colors will be filled with
* the palette colors. If @colors is NULL, the function
* will just return the number of total colors
* without storing any actual colors; this can be used
* for allocating a buffer of suitable size before calling
* hb_ot_color_palette_get_colors() a second time.
* @face: #hb_face_t to work upon
* @palette_index: the index of the color palette to query
* @start_offset: offset of the first color to retrieve
* @color_count: (inout) (optional): Input = the maximum number of colors to return;
* Output = the actual number of colors returned (may be zero)
* @colors: (out) (array length=color_count) (nullable): The array of #hb_color_t records found
*
* Retrieves the colors in a color palette.
* Fetches a list of the colors in a color palette.
*
* Returns: the total number of colors in the palette.
* After calling this function, @colors will be filled with the palette
* colors. If @colors is NULL, the function will just return the number
* of total colors without storing any actual colors; this can be used
* for allocating a buffer of suitable size before calling
* hb_ot_color_palette_get_colors() a second time.
*
* Return value: the total number of colors in the palette
*
* Since: 2.1.0
*/
@ -167,6 +195,11 @@ hb_ot_color_palette_get_colors (hb_face_t *face,
unsigned int *colors_count /* IN/OUT. May be NULL. */,
hb_color_t *colors /* OUT. May be NULL. */)
{
#ifdef HB_NO_COLOR
if (colors_count)
*colors_count = 0;
return 0;
#endif
return face->table.CPAL->get_palette_colors (palette_index, start_offset, colors_count, colors);
}
@ -177,28 +210,36 @@ hb_ot_color_palette_get_colors (hb_face_t *face,
/**
* hb_ot_color_has_layers:
* @face: a font face.
* @face: #hb_face_t to work upon
*
* Returns: whether COLR table is available.
* Tests whether a face includes any `COLR` color layers.
*
* Return value: true if data found, false otherwise
*
* Since: 2.1.0
*/
hb_bool_t
hb_ot_color_has_layers (hb_face_t *face)
{
#ifdef HB_NO_COLOR
return false;
#endif
return face->table.COLR->has_data ();
}
/**
* hb_ot_color_glyph_get_layers:
* @face: a font face.
* @glyph: a layered color glyph id.
* @start_offset: starting offset of layers.
* @count: (inout) (optional): gets number of layers available to be written on buffer
* and returns number of written layers.
* @layers: (array length=count) (out) (optional): layers buffer to buffer.
* @face: #hb_face_t to work upon
* @glyph: The glyph index to query
* @start_offset: offset of the first layer to retrieve
* @layer_count: (inout) (optional): Input = the maximum number of layers to return;
* Output = the actual number of layers returned (may be zero)
* @layers: (out) (array length=layer_count) (nullable): The array of layers found
*
* Returns: Total number of layers a layered color glyph have.
* Fetches a list of all color layers for the specified glyph index in the specified
* face. The list returned will begin at the offset provided.
*
* Return value: Total number of layers available for the glyph index queried
*
* Since: 2.1.0
*/
@ -206,10 +247,15 @@ unsigned int
hb_ot_color_glyph_get_layers (hb_face_t *face,
hb_codepoint_t glyph,
unsigned int start_offset,
unsigned int *count, /* IN/OUT. May be NULL. */
unsigned int *layer_count, /* IN/OUT. May be NULL. */
hb_ot_color_layer_t *layers /* OUT. May be NULL. */)
{
return face->table.COLR->get_glyph_layers (glyph, start_offset, count, layers);
#ifdef HB_NO_COLOR
if (layer_count)
*layer_count = 0;
return 0;
#endif
return face->table.COLR->get_glyph_layers (glyph, start_offset, layer_count, layers);
}
@ -219,34 +265,40 @@ hb_ot_color_glyph_get_layers (hb_face_t *face,
/**
* hb_ot_color_has_svg:
* @face: a font face.
* @face: #hb_face_t to work upon.
*
* Check whether @face has SVG glyph images.
* Tests whether a face includes any `SVG` glyph images.
*
* Returns true if available, false otherwise.
* Return value: true if data found, false otherwise.
*
* Since: 2.1.0
*/
hb_bool_t
hb_ot_color_has_svg (hb_face_t *face)
{
#ifdef HB_NO_COLOR
return false;
#endif
return face->table.SVG->has_data ();
}
/**
* hb_ot_color_glyph_reference_svg:
* @face: a font face.
* @glyph: a svg glyph index.
* @face: #hb_face_t to work upon
* @glyph: a svg glyph index
*
* Get SVG document for a glyph. The blob may be either plain text or gzip-encoded.
* Fetches the SVG document for a glyph. The blob may be either plain text or gzip-encoded.
*
* Returns: (transfer full): respective svg blob of the glyph, if available.
* Return value: (transfer full): An #hb_blob_t containing the SVG document of the glyph, if available
*
* Since: 2.1.0
*/
hb_blob_t *
hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph)
{
#ifdef HB_NO_COLOR
return hb_blob_get_empty ();
#endif
return face->table.SVG->reference_blob_for_glyph (glyph);
}
@ -257,36 +309,43 @@ hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph)
/**
* hb_ot_color_has_png:
* @face: a font face.
* @face: #hb_face_t to work upon
*
* Check whether @face has PNG glyph images (either CBDT or sbix tables).
* Tests whether a face has PNG glyph images (either in `CBDT` or `sbix` tables).
*
* Returns true if available, false otherwise.
* Return value: true if data found, false otherwise
*
* Since: 2.1.0
*/
hb_bool_t
hb_ot_color_has_png (hb_face_t *face)
{
#ifdef HB_NO_COLOR
return false;
#endif
return face->table.CBDT->has_data () || face->table.sbix->has_data ();
}
/**
* hb_ot_color_glyph_reference_png:
* @font: a font object, not face. upem should be set on
* that font object if one wants to get optimal png blob, otherwise
* return the biggest one
* @glyph: a glyph index.
* @font: #hb_font_t to work upon
* @glyph: a glyph index
*
* Get PNG image for a glyph.
* Fetches the PNG image for a glyph. This function takes a font object, not a face object,
* as input. To get an optimally sized PNG blob, the UPEM value must be set on the @font
* object. If UPEM is unset, the blob returned will be the largest PNG available.
*
* Returns: (transfer full): respective PNG blob of the glyph, if available.
* Return value: (transfer full): An #hb_blob_t containing the PNG image for the glyph, if available
*
* Since: 2.1.0
*/
hb_blob_t *
hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph)
{
#ifdef HB_NO_COLOR
return hb_blob_get_empty ();
#endif
hb_blob_t *blob = hb_blob_get_empty ();
if (font->face->table.sbix->has_data ())

View File

@ -59,11 +59,11 @@ hb_ot_color_palette_color_get_name_id (hb_face_t *face,
/**
* hb_ot_color_palette_flags_t:
* @HB_OT_COLOR_PALETTE_FLAG_DEFAULT: default indicating that there is nothing special
* @HB_OT_COLOR_PALETTE_FLAG_DEFAULT: Default indicating that there is nothing special
* to note about a color palette.
* @HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND: flag indicating that the color
* @HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_LIGHT_BACKGROUND: Flag indicating that the color
* palette is appropriate to use when displaying the font on a light background such as white.
* @HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND: flag indicating that the color
* @HB_OT_COLOR_PALETTE_FLAG_USABLE_WITH_DARK_BACKGROUND: Flag indicating that the color
* palette is appropriate to use when displaying the font on a dark background such as black.
*
* Since: 2.1.0
@ -110,7 +110,7 @@ HB_EXTERN unsigned int
hb_ot_color_glyph_get_layers (hb_face_t *face,
hb_codepoint_t glyph,
unsigned int start_offset,
unsigned int *count, /* IN/OUT. May be NULL. */
unsigned int *layer_count, /* IN/OUT. May be NULL. */
hb_ot_color_layer_t *layers /* OUT. May be NULL. */);
/*

View File

@ -180,19 +180,20 @@ hb_ot_get_glyph_extents (hb_font_t *font,
void *user_data HB_UNUSED)
{
const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
bool ret = ot_face->sbix->get_extents (font, glyph, extents);
if (!ret)
ret = ot_face->glyf->get_extents (glyph, extents);
#if !defined(HB_NO_OT_FONT_CFF)
if (!ret)
ret = ot_face->cff1->get_extents (glyph, extents);
if (!ret)
ret = ot_face->cff2->get_extents (font, glyph, extents);
bool ret = false;
#if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR)
if (!ret) ret = ot_face->sbix->get_extents (font, glyph, extents);
#endif
#if !defined(HB_NO_OT_FONT_BITMAP)
if (!ret)
ret = ot_face->CBDT->get_extents (font, glyph, extents);
if (!ret) ret = ot_face->glyf->get_extents (glyph, extents);
#ifndef HB_NO_OT_FONT_CFF
if (!ret) ret = ot_face->cff1->get_extents (glyph, extents);
if (!ret) ret = ot_face->cff2->get_extents (font, glyph, extents);
#endif
#if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR)
if (!ret) ret = ot_face->CBDT->get_extents (font, glyph, extents);
#endif
// TODO Hook up side-bearings variations.
extents->x_bearing = font->em_scale_x (extents->x_bearing);
extents->y_bearing = font->em_scale_y (extents->y_bearing);

View File

@ -108,7 +108,7 @@ struct hdmx
this->sizeDeviceRecord = DeviceRecord::get_size (it ? (*it).second.len () : 0);
+ it
| hb_apply ([&] (const hb_item_type<Iterator>& _) {
| hb_apply ([c] (const hb_item_type<Iterator>& _) {
c->start_embed<DeviceRecord> ()->serialize (c, _.first, _.second);
})
;
@ -126,7 +126,7 @@ struct hdmx
auto it =
+ hb_range ((unsigned) numRecords)
| hb_map ([&] (unsigned _)
| hb_map ([c, this] (unsigned _)
{
const DeviceRecord *device_record =
&StructAtOffset<DeviceRecord> (&firstDeviceRecord,

View File

@ -128,9 +128,13 @@ struct KernSubTable
TRACE_DISPATCH (this, subtable_type);
switch (subtable_type) {
case 0: return_trace (c->dispatch (u.format0));
#ifndef HB_NO_SHAPE_AAT
case 1: return_trace (u.header.apple ? c->dispatch (u.format1, hb_forward<Ts> (ds)...) : c->default_return_value ());
#endif
case 2: return_trace (c->dispatch (u.format2));
#ifndef HB_NO_SHAPE_AAT
case 3: return_trace (u.header.apple ? c->dispatch (u.format3, hb_forward<Ts> (ds)...) : c->default_return_value ());
#endif
default: return_trace (c->default_return_value ());
}
}
@ -278,7 +282,9 @@ struct kern
{
switch (get_type ()) {
case 0: return u.ot.has_state_machine ();
#ifndef HB_NO_SHAPE_AAT
case 1: return u.aat.has_state_machine ();
#endif
default:return false;
}
}
@ -287,7 +293,9 @@ struct kern
{
switch (get_type ()) {
case 0: return u.ot.has_cross_stream ();
#ifndef HB_NO_SHAPE_AAT
case 1: return u.aat.has_cross_stream ();
#endif
default:return false;
}
}
@ -296,7 +304,9 @@ struct kern
{
switch (get_type ()) {
case 0: return u.ot.get_h_kerning (left, right);
#ifndef HB_NO_SHAPE_AAT
case 1: return u.aat.get_h_kerning (left, right);
#endif
default:return 0;
}
}
@ -311,7 +321,9 @@ struct kern
TRACE_DISPATCH (this, subtable_type);
switch (subtable_type) {
case 0: return_trace (c->dispatch (u.ot, hb_forward<Ts> (ds)...));
#ifndef HB_NO_SHAPE_AAT
case 1: return_trace (c->dispatch (u.aat, hb_forward<Ts> (ds)...));
#endif
default: return_trace (c->default_return_value ());
}
}
@ -328,7 +340,9 @@ struct kern
HBUINT32 version32;
HBUINT16 major;
KernOT ot;
#ifndef HB_NO_SHAPE_AAT
KernAAT aat;
#endif
} u;
public:
DEFINE_SIZE_UNION (4, version32);

View File

@ -138,7 +138,7 @@ struct RecordListOf : RecordArrayOf<Type>
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
struct RecordListOf<Type> *out = c->serializer->embed (*this);
auto *out = c->serializer->embed (*this);
if (unlikely (!out)) return_trace (false);
unsigned int count = this->len;
for (unsigned int i = 0; i < count; i++)
@ -226,7 +226,7 @@ struct LangSys
{
if (reqFeatureIndex == 0xFFFFu)
return Index::NOT_FOUND_INDEX;
return reqFeatureIndex;;
return reqFeatureIndex;
}
LangSys* copy (hb_serialize_context_t *c) const
@ -277,7 +277,7 @@ struct Script
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
struct Script *out = c->serializer->embed (*this);
auto *out = c->serializer->embed (*this);
if (unlikely (!out)) return_trace (false);
out->defaultLangSys.serialize_copy (c->serializer, this+defaultLangSys, out);
unsigned int count = langSys.len;
@ -559,7 +559,7 @@ struct Feature
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
struct Feature *out = c->serializer->embed (*this);
auto *out = c->serializer->embed (*this);
if (unlikely (!out)) return_trace (false);
out->featureParams = 0; /* TODO(subset) FeatureParams. */
return_trace (true);
@ -647,10 +647,6 @@ struct Lookup
{
unsigned int get_subtable_count () const { return subTable.len; }
template <typename TSubTable>
const TSubTable& get_subtable (unsigned int i) const
{ return this+CastR<OffsetArrayOf<TSubTable>> (subTable)[i]; }
template <typename TSubTable>
const OffsetArrayOf<TSubTable>& get_subtables () const
{ return CastR<OffsetArrayOf<TSubTable>> (subTable); }
@ -658,6 +654,13 @@ struct Lookup
OffsetArrayOf<TSubTable>& get_subtables ()
{ return CastR<OffsetArrayOf<TSubTable>> (subTable); }
template <typename TSubTable>
const TSubTable& get_subtable (unsigned int i) const
{ return this+get_subtables<TSubTable> ()[i]; }
template <typename TSubTable>
TSubTable& get_subtable (unsigned int i)
{ return this+get_subtables<TSubTable> ()[i]; }
unsigned int get_size () const
{
const HBUINT16 &markFilteringSet = StructAfter<const HBUINT16> (subTable);
@ -719,7 +722,7 @@ struct Lookup
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
struct Lookup *out = c->serializer->embed (*this);
auto *out = c->serializer->embed (*this);
if (unlikely (!out)) return_trace (false);
/* Subset the actual subtables. */
@ -745,16 +748,21 @@ struct Lookup
if (!markFilteringSet.sanitize (c)) return_trace (false);
}
if (unlikely (!CastR<OffsetArrayOf<TSubTable>> (subTable)
.sanitize (c, this, get_type ())))
if (unlikely (!get_subtables<TSubTable> ().sanitize (c, this, get_type ())))
return_trace (false);
if (unlikely (get_type () == TSubTable::Extension))
if (unlikely (get_type () == TSubTable::Extension && !c->get_edit_count ()))
{
/* The spec says all subtables of an Extension lookup should
* have the same type, which shall not be the Extension type
* itself (but we already checked for that).
* This is specially important if one has a reverse type! */
* This is specially important if one has a reverse type!
*
* We only do this if sanitizer edit_count is zero. Otherwise,
* some of the subtables might have become insane after they
* were sanity-checked by the edits of subsequent subtables.
* https://bugs.chromium.org/p/chromium/issues/detail?id=960331
*/
unsigned int type = get_subtable<TSubTable> (0).u.extension.get_type ();
unsigned int count = get_subtable_count ();
for (unsigned int i = 1; i < count; i++)
@ -762,7 +770,6 @@ struct Lookup
return_trace (false);
}
return_trace (true);
return_trace (true);
}
private:
@ -797,7 +804,7 @@ struct CoverageFormat1
}
template <typename Iterator,
hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
bool serialize (hb_serialize_context_t *c, Iterator glyphs)
{
TRACE_SERIALIZE (this);
@ -866,7 +873,7 @@ struct CoverageFormat2
}
template <typename Iterator,
hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
bool serialize (hb_serialize_context_t *c, Iterator glyphs)
{
TRACE_SERIALIZE (this);
@ -877,30 +884,36 @@ struct CoverageFormat2
rangeRecord.len = 0;
return_trace (true);
}
/* TODO(iter) Port to non-random-access iterator interface. */
unsigned int count = glyphs.len ();
unsigned int num_ranges = 1;
for (unsigned int i = 1; i < count; i++)
if (glyphs[i - 1] + 1 != glyphs[i])
num_ranges++;
rangeRecord.len = num_ranges;
if (unlikely (!c->extend (rangeRecord))) return_trace (false);
/* TODO(iter) Write more efficiently? */
unsigned int range = 0;
rangeRecord[range].start = glyphs[0];
rangeRecord[range].value = 0;
for (unsigned int i = 1; i < count; i++)
unsigned num_ranges = 0;
hb_codepoint_t last = (hb_codepoint_t) -2;
for (auto g: glyphs)
{
if (glyphs[i - 1] + 1 != glyphs[i])
{
rangeRecord[range].end = glyphs[i - 1];
range++;
rangeRecord[range].start = glyphs[i];
rangeRecord[range].value = i;
}
if (last + 1 != g)
num_ranges++;
last = g;
}
rangeRecord[range].end = glyphs[count - 1];
if (unlikely (!rangeRecord.serialize (c, num_ranges))) return_trace (false);
unsigned count = 0;
unsigned range = (unsigned) -1;
last = (hb_codepoint_t) -2;
for (auto g: glyphs)
{
if (last + 1 != g)
{
range++;
rangeRecord[range].start = g;
rangeRecord[range].value = count;
}
rangeRecord[range].end = g;
last = g;
count++;
}
return_trace (true);
}
@ -1030,18 +1043,22 @@ struct Coverage
}
template <typename Iterator,
hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
bool serialize (hb_serialize_context_t *c, Iterator glyphs)
{
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return_trace (false);
/* TODO(iter) Port to non-random-access iterator interface. */
unsigned int count = glyphs.len ();
unsigned int num_ranges = 1;
for (unsigned int i = 1; i < count; i++)
if (glyphs[i - 1] + 1 != glyphs[i])
num_ranges++;
unsigned count = 0;
unsigned num_ranges = 0;
hb_codepoint_t last = (hb_codepoint_t) -2;
for (auto g: glyphs)
{
if (last + 1 != g)
num_ranges++;
last = g;
count++;
}
u.format = count * 2 < num_ranges * 3 ? 1 : 2;
switch (u.format)
@ -1207,7 +1224,7 @@ struct ClassDefFormat1
hb_codepoint_t glyph_max = +glyphs | hb_reduce (hb_max, 0u);
startGlyph = glyph_min;
classValue.len = glyph_max - glyph_min + 1;
c->check_assign (classValue.len, glyph_max - glyph_min + 1);
if (unlikely (!c->extend (classValue))) return_trace (false);
for (unsigned int i = 0; i < glyphs.length; i++)

View File

@ -439,7 +439,7 @@ struct GDEF
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
struct GDEF *out = c->serializer->embed (*this);
auto *out = c->serializer->embed (*this);
if (unlikely (!out)) return_trace (false);
out->glyphClassDef.serialize_subset (c, this+glyphClassDef, out);

View File

@ -726,7 +726,7 @@ struct PairPosFormat1
+ hb_zip (this+coverage, pairSet)
| hb_filter (*glyphs, hb_first)
| hb_map (hb_second)
| hb_map ([&] (const OffsetTo<PairSet> &_) -> bool
| hb_map ([=] (const OffsetTo<PairSet> &_)
{ return (this+_).intersects (glyphs, valueFormat); })
| hb_any
;

View File

@ -34,10 +34,12 @@
namespace OT {
typedef hb_pair_t<hb_codepoint_t, hb_codepoint_t> hb_codepoint_pair_t;
template<typename Iterator>
static inline void SingleSubst_serialize (hb_serialize_context_t *c,
hb_sorted_array_t<const GlyphID> glyphs,
hb_array_t<const GlyphID> substitutes);
Iterator it);
struct SingleSubstFormat1
{
@ -46,9 +48,10 @@ struct SingleSubstFormat1
void closure (hb_closure_context_t *c) const
{
unsigned d = deltaGlyphID;
+ hb_iter (this+coverage)
| hb_filter (*c->glyphs)
| hb_map ([&] (hb_codepoint_t g) -> hb_codepoint_t { return (g + deltaGlyphID) & 0xFFFFu; })
| hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; })
| hb_sink (c->output)
;
}
@ -56,9 +59,9 @@ struct SingleSubstFormat1
void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
if (unlikely (!(this+coverage).add_coverage (c->input))) return;
unsigned d = deltaGlyphID;
+ hb_iter (this+coverage)
| hb_map ([&] (hb_codepoint_t g) -> hb_codepoint_t { return (g + deltaGlyphID) & 0xFFFFu; })
| hb_map ([d] (hb_codepoint_t g) { return (g + d) & 0xFFFFu; })
| hb_sink (c->output)
;
}
@ -83,8 +86,11 @@ struct SingleSubstFormat1
return_trace (true);
}
template<typename Iterator,
hb_requires (hb_is_sorted_source_of (Iterator,
hb_codepoint_t))>
bool serialize (hb_serialize_context_t *c,
hb_sorted_array_t<const GlyphID> glyphs,
Iterator glyphs,
unsigned delta)
{
TRACE_SERIALIZE (this);
@ -100,20 +106,19 @@ struct SingleSubstFormat1
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
hb_sorted_vector_t<GlyphID> from;
hb_vector_t<GlyphID> to;
hb_codepoint_t delta = deltaGlyphID;
auto it =
+ hb_iter (this+coverage)
| hb_filter (glyphset)
| hb_map ([&] (hb_codepoint_t g) -> hb_pair_t<hb_codepoint_t, hb_codepoint_t>
{ return hb_pair<hb_codepoint_t, hb_codepoint_t> (glyph_map[g],
glyph_map[(g + delta) & 0xFFFF]); })
| hb_unzip (from, to);
| hb_map_retains_sorting ([&] (hb_codepoint_t g) {
return hb_codepoint_pair_t (glyph_map[g],
glyph_map[(g + delta) & 0xFFFF]); })
;
c->serializer->propagate_error (from, to);
SingleSubst_serialize (c->serializer, from, to);
return_trace (from.length);
bool ret = bool (it);
SingleSubst_serialize (c->serializer, it);
return_trace (ret);
}
bool sanitize (hb_sanitize_context_t *c) const
@ -174,11 +179,21 @@ struct SingleSubstFormat2
return_trace (true);
}
template<typename Iterator,
hb_requires (hb_is_sorted_source_of (Iterator,
const hb_codepoint_pair_t))>
bool serialize (hb_serialize_context_t *c,
hb_sorted_array_t<const GlyphID> glyphs,
hb_array_t<const GlyphID> substitutes)
Iterator it)
{
TRACE_SERIALIZE (this);
auto substitutes =
+ it
| hb_map (hb_second)
;
auto glyphs =
+ it
| hb_map_retains_sorting (hb_first)
;
if (unlikely (!c->extend_min (*this))) return_trace (false);
if (unlikely (!substitute.serialize (c, substitutes))) return_trace (false);
if (unlikely (!coverage.serialize (c, this).serialize (c, glyphs))) return_trace (false);
@ -191,18 +206,16 @@ struct SingleSubstFormat2
const hb_set_t &glyphset = *c->plan->glyphset ();
const hb_map_t &glyph_map = *c->plan->glyph_map;
hb_sorted_vector_t<GlyphID> from;
hb_vector_t<GlyphID> to;
auto it =
+ hb_zip (this+coverage, substitute)
| hb_filter (glyphset, hb_first)
| hb_map ([&] (hb_pair_t<hb_codepoint_t, const GlyphID &> p) -> hb_pair_t<hb_codepoint_t, hb_codepoint_t>
{ return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
| hb_unzip (from, to);
| hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const GlyphID &> p) -> hb_codepoint_pair_t
{ return hb_pair (glyph_map[p.first], glyph_map[p.second]); })
;
c->serializer->propagate_error (from, to);
SingleSubst_serialize (c->serializer, from, to);
return_trace (from.length);
bool ret = bool (it);
SingleSubst_serialize (c->serializer, it);
return_trace (ret);
}
bool sanitize (hb_sanitize_context_t *c) const
@ -225,28 +238,33 @@ struct SingleSubstFormat2
struct SingleSubst
{
template<typename Iterator,
hb_requires (hb_is_sorted_source_of (Iterator,
const hb_codepoint_pair_t))>
bool serialize (hb_serialize_context_t *c,
hb_sorted_array_t<const GlyphID> glyphs,
hb_array_t<const GlyphID> substitutes)
Iterator glyphs)
{
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (u.format))) return_trace (false);
unsigned format = 2;
unsigned delta = 0;
if (glyphs.length)
if (glyphs.len ())
{
format = 1;
delta = (unsigned) (substitutes[0] - glyphs[0]) & 0xFFFF;
for (unsigned int i = 1; i < glyphs.length; i++)
if (delta != ((unsigned) (substitutes[i] - glyphs[i]) & 0xFFFF)) {
format = 2;
break;
}
auto get_delta = [=] (hb_codepoint_pair_t _) {
return (unsigned) (_.second - _.first) & 0xFFFF;
};
delta = get_delta (*glyphs);
if (!hb_all (++(+glyphs), delta, get_delta)) format = 2;
}
u.format = format;
switch (u.format) {
case 1: return_trace (u.format1.serialize (c, glyphs, delta));
case 2: return_trace (u.format2.serialize (c, glyphs, substitutes));
case 1: return_trace (u.format1.serialize (c,
+ glyphs
| hb_map_retains_sorting (hb_first),
delta));
case 2: return_trace (u.format2.serialize (c, glyphs));
default:return_trace (false);
}
}
@ -271,11 +289,11 @@ struct SingleSubst
} u;
};
template<typename Iterator>
static inline void
SingleSubst_serialize (hb_serialize_context_t *c,
hb_sorted_array_t<const GlyphID> glyphs,
hb_array_t<const GlyphID> substitutes)
{ c->start_embed<SingleSubst> ()->serialize (c, glyphs, substitutes); }
Iterator it)
{ c->start_embed<SingleSubst> ()->serialize (c, it); }
struct Sequence
{
@ -351,7 +369,8 @@ struct MultipleSubstFormat1
+ hb_zip (this+coverage, sequence)
| hb_filter (*c->glyphs, hb_first)
| hb_map (hb_second)
| hb_apply ([&] (const OffsetTo<Sequence> &_) { (this+_).closure (c); })
| hb_map (hb_add (this))
| hb_apply ([c] (const Sequence &_) { _.closure (c); })
;
}
@ -360,7 +379,8 @@ struct MultipleSubstFormat1
if (unlikely (!(this+coverage).add_coverage (c->input))) return;
+ hb_zip (this+coverage, sequence)
| hb_map (hb_second)
| hb_apply ([&] (const OffsetTo<Sequence> &_) { (this+_).collect_glyphs (c); })
| hb_map (hb_add (this))
| hb_apply ([c] (const Sequence &_) { _.collect_glyphs (c); })
;
}
@ -525,7 +545,8 @@ struct AlternateSubstFormat1
{
+ hb_zip (this+coverage, alternateSet)
| hb_map (hb_second)
| hb_apply ([&] (const OffsetTo<AlternateSet> &_) { (this+_).closure (c); })
| hb_map (hb_add (this))
| hb_apply ([c] (const AlternateSet &_) { _.closure (c); })
;
}
@ -534,7 +555,8 @@ struct AlternateSubstFormat1
if (unlikely (!(this+coverage).add_coverage (c->input))) return;
+ hb_zip (this+coverage, alternateSet)
| hb_map (hb_second)
| hb_apply ([&] (const OffsetTo<AlternateSet> &_) { (this+_).collect_glyphs (c); })
| hb_map (hb_add (this))
| hb_apply ([c] (const AlternateSet &_) { _.collect_glyphs (c); })
;
}
@ -640,7 +662,7 @@ struct Ligature
unsigned int count = component.lenP1;
for (unsigned int i = 1; i < count; i++)
if (!glyphs->has (component[i]))
return false;
return false;
return true;
}
@ -741,7 +763,8 @@ struct LigatureSet
{
return
+ hb_iter (ligature)
| hb_map ([&] (const OffsetTo<Ligature> &_) -> bool { return (this+_).intersects (glyphs); })
| hb_map (hb_add (this))
| hb_map ([glyphs] (const Ligature &_) { return _.intersects (glyphs); })
| hb_any
;
}
@ -749,14 +772,16 @@ struct LigatureSet
void closure (hb_closure_context_t *c) const
{
+ hb_iter (ligature)
| hb_apply ([&] (const OffsetTo<Ligature> &_) { (this+_).closure (c); })
| hb_map (hb_add (this))
| hb_apply ([c] (const Ligature &_) { _.closure (c); })
;
}
void collect_glyphs (hb_collect_glyphs_context_t *c) const
{
+ hb_iter (ligature)
| hb_apply ([&] (const OffsetTo<Ligature> &_) { (this+_).collect_glyphs (c); })
| hb_map (hb_add (this))
| hb_apply ([c] (const Ligature &_) { _.collect_glyphs (c); })
;
}
@ -764,7 +789,8 @@ struct LigatureSet
{
return
+ hb_iter (ligature)
| hb_map ([&] (const OffsetTo<Ligature> &_) -> bool { return (this+_).would_apply (c); })
| hb_map (hb_add (this))
| hb_map ([c] (const Ligature &_) { return _.would_apply (c); })
| hb_any
;
}
@ -825,7 +851,7 @@ struct LigatureSubstFormat1
+ hb_zip (this+coverage, ligatureSet)
| hb_filter (*glyphs, hb_first)
| hb_map (hb_second)
| hb_map ([&] (const OffsetTo<LigatureSet> &_) -> bool
| hb_map ([this, glyphs] (const OffsetTo<LigatureSet> &_)
{ return (this+_).intersects (glyphs); })
| hb_any
;
@ -836,7 +862,8 @@ struct LigatureSubstFormat1
+ hb_zip (this+coverage, ligatureSet)
| hb_filter (*c->glyphs, hb_first)
| hb_map (hb_second)
| hb_apply ([&] (const OffsetTo<LigatureSet> &_) { (this+_).closure (c); })
| hb_map (hb_add (this))
| hb_apply ([c] (const LigatureSet &_) { _.closure (c); })
;
}
@ -846,7 +873,8 @@ struct LigatureSubstFormat1
+ hb_zip (this+coverage, ligatureSet)
| hb_map (hb_second)
| hb_apply ([&] (const OffsetTo<LigatureSet> &_) { (this+_).collect_glyphs (c); })
| hb_map (hb_add (this))
| hb_apply ([c] (const LigatureSet &_) { _.collect_glyphs (c); })
;
}
@ -990,12 +1018,12 @@ struct ReverseChainSingleSubstFormat1
count = backtrack.len;
for (unsigned int i = 0; i < count; i++)
if (!(this+backtrack[i]).intersects (glyphs))
return false;
return false;
count = lookahead.len;
for (unsigned int i = 0; i < count; i++)
if (!(this+lookahead[i]).intersects (glyphs))
return false;
return false;
return true;
}
@ -1056,7 +1084,7 @@ struct ReverseChainSingleSubstFormat1
backtrack.len, (HBUINT16 *) backtrack.arrayZ,
match_coverage, this,
&start_index) &&
match_lookahead (c,
match_lookahead (c,
lookahead.len, (HBUINT16 *) lookahead.arrayZ,
match_coverage, this,
1, &end_index))
@ -1259,12 +1287,14 @@ struct SubstLookup : Lookup
bool serialize_single (hb_serialize_context_t *c,
uint32_t lookup_props,
hb_sorted_array_t<const GlyphID> glyphs,
hb_array_t<const GlyphID> substitutes)
hb_sorted_array_t<const GlyphID> glyphs,
hb_array_t<const GlyphID> substitutes)
{
TRACE_SERIALIZE (this);
if (unlikely (!Lookup::serialize (c, SubTable::Single, lookup_props, 1))) return_trace (false);
return_trace (serialize_subtable (c, 0).u.single.serialize (c, glyphs, substitutes));
return_trace (serialize_subtable (c, 0).u.single
.serialize (c, hb_zip (glyphs, substitutes)));
}
bool serialize_multiple (hb_serialize_context_t *c,
@ -1319,7 +1349,7 @@ struct SubstLookup : Lookup
HB_INTERNAL static hb_closure_context_t::return_t dispatch_closure_recurse_func (hb_closure_context_t *c, unsigned int lookup_index)
{
if (!c->should_visit_lookup (lookup_index))
return hb_void_t ();
return hb_empty_t ();
hb_closure_context_t::return_t ret = dispatch_recurse_func (c, lookup_index);

View File

@ -59,13 +59,13 @@ struct hb_intersects_context_t :
};
struct hb_closure_context_t :
hb_dispatch_context_t<hb_closure_context_t, hb_void_t, 0>
hb_dispatch_context_t<hb_closure_context_t, hb_empty_t, 0>
{
const char *get_name () { return "CLOSURE"; }
typedef return_t (*recurse_func_t) (hb_closure_context_t *c, unsigned int lookup_index);
template <typename T>
return_t dispatch (const T &obj) { obj.closure (this); return hb_void_t (); }
static return_t default_return_value () { return hb_void_t (); }
return_t dispatch (const T &obj) { obj.closure (this); return hb_empty_t (); }
static return_t default_return_value () { return hb_empty_t (); }
void recurse (unsigned int lookup_index)
{
if (unlikely (nesting_level_left == 0 || !recurse_func))
@ -151,13 +151,13 @@ struct hb_would_apply_context_t :
struct hb_collect_glyphs_context_t :
hb_dispatch_context_t<hb_collect_glyphs_context_t, hb_void_t, 0>
hb_dispatch_context_t<hb_collect_glyphs_context_t, hb_empty_t, 0>
{
const char *get_name () { return "COLLECT_GLYPHS"; }
typedef return_t (*recurse_func_t) (hb_collect_glyphs_context_t *c, unsigned int lookup_index);
template <typename T>
return_t dispatch (const T &obj) { obj.collect_glyphs (this); return hb_void_t (); }
static return_t default_return_value () { return hb_void_t (); }
return_t dispatch (const T &obj) { obj.collect_glyphs (this); return hb_empty_t (); }
static return_t default_return_value () { return hb_empty_t (); }
void recurse (unsigned int lookup_index)
{
if (unlikely (nesting_level_left == 0 || !recurse_func))
@ -610,7 +610,7 @@ struct hb_ot_apply_context_t :
struct hb_get_subtables_context_t :
hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY>
hb_dispatch_context_t<hb_get_subtables_context_t, hb_empty_t, HB_DEBUG_APPLY>
{
template <typename Type>
HB_INTERNAL static bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c)
@ -652,9 +652,9 @@ struct hb_get_subtables_context_t :
{
hb_applicable_t *entry = array.push();
entry->init (obj, apply_to<T>);
return hb_void_t ();
return hb_empty_t ();
}
static return_t default_return_value () { return hb_void_t (); }
static return_t default_return_value () { return hb_empty_t (); }
hb_get_subtables_context_t (array_t &array_) :
array (array_),
@ -708,7 +708,7 @@ static inline bool intersects_array (const hb_set_t *glyphs,
{
return
+ hb_iter (values, count)
| hb_map ([&] (const HBUINT16 &_) -> bool { return intersects_func (glyphs, _, intersects_data); })
| hb_map ([&] (const HBUINT16 &_) { return intersects_func (glyphs, _, intersects_data); })
| hb_any
;
}
@ -849,7 +849,7 @@ static inline bool match_input (hb_ot_apply_context_t *c,
if (ligbase == LIGBASE_NOT_CHECKED)
{
bool found = false;
const hb_glyph_info_t *out = buffer->out_info;
const auto *out = buffer->out_info;
unsigned int j = buffer->out_len;
while (j && _hb_glyph_info_get_lig_id (&out[j - 1]) == first_lig_id)
{
@ -1371,7 +1371,8 @@ struct RuleSet
{
return
+ hb_iter (rule)
| hb_map ([&] (const OffsetTo<Rule> &_) -> bool { return (this+_).intersects (glyphs, lookup_context); })
| hb_map (hb_add (this))
| hb_map ([&] (const Rule &_) { return _.intersects (glyphs, lookup_context); })
| hb_any
;
}
@ -1381,7 +1382,8 @@ struct RuleSet
{
return
+ hb_iter (rule)
| hb_apply ([&] (const OffsetTo<Rule> &_) { (this+_).closure (c, lookup_context); })
| hb_map (hb_add (this))
| hb_apply ([&] (const Rule &_) { _.closure (c, lookup_context); })
;
}
@ -1390,7 +1392,8 @@ struct RuleSet
{
return
+ hb_iter (rule)
| hb_apply ([&] (const OffsetTo<Rule> &_) { (this+_).collect_glyphs (c, lookup_context); })
| hb_map (hb_add (this))
| hb_apply ([&] (const Rule &_) { _.collect_glyphs (c, lookup_context); })
;
}
@ -1399,7 +1402,8 @@ struct RuleSet
{
return
+ hb_iter (rule)
| hb_map ([&] (const OffsetTo<Rule> &_) -> bool { return (this+_).would_apply (c, lookup_context); })
| hb_map (hb_add (this))
| hb_map ([&] (const Rule &_) { return _.would_apply (c, lookup_context); })
| hb_any
;
}
@ -1410,7 +1414,8 @@ struct RuleSet
TRACE_APPLY (this);
return_trace (
+ hb_iter (rule)
| hb_map ([&] (const OffsetTo<Rule> &_) -> bool { return (this+_).apply (c, lookup_context); })
| hb_map (hb_add (this))
| hb_map ([&] (const Rule &_) { return _.apply (c, lookup_context); })
| hb_any
)
;
@ -1444,7 +1449,8 @@ struct ContextFormat1
+ hb_zip (this+coverage, ruleSet)
| hb_filter (*glyphs, hb_first)
| hb_map (hb_second)
| hb_map ([&] (const OffsetTo<RuleSet> &_) -> bool { return (this+_).intersects (glyphs, lookup_context); })
| hb_map (hb_add (this))
| hb_map ([&] (const RuleSet &_) { return _.intersects (glyphs, lookup_context); })
| hb_any
;
}
@ -1459,7 +1465,8 @@ struct ContextFormat1
+ hb_zip (this+coverage, ruleSet)
| hb_filter (*c->glyphs, hb_first)
| hb_map (hb_second)
| hb_apply ([&] (const OffsetTo<RuleSet> &_) { (this+_).closure (c, lookup_context); })
| hb_map (hb_add (this))
| hb_apply ([&] (const RuleSet &_) { _.closure (c, lookup_context); })
;
}
@ -1473,7 +1480,8 @@ struct ContextFormat1
};
+ hb_iter (ruleSet)
| hb_apply ([&] (const OffsetTo<RuleSet> &_) { (this+_).collect_glyphs (c, lookup_context); })
| hb_map (hb_add (this))
| hb_apply ([&] (const RuleSet &_) { _.collect_glyphs (c, lookup_context); })
;
}
@ -1546,7 +1554,7 @@ struct ContextFormat2
return
+ hb_enumerate (ruleSet)
| hb_map ([&] (const hb_pair_t<unsigned, const OffsetTo<RuleSet> &> p) -> bool
| hb_map ([&] (const hb_pair_t<unsigned, const OffsetTo<RuleSet> &> p)
{ return class_def.intersects_class (glyphs, p.first) &&
(this+p.second).intersects (glyphs, lookup_context); })
| hb_any
@ -1567,11 +1575,12 @@ struct ContextFormat2
return
+ hb_enumerate (ruleSet)
| hb_filter ([&] (unsigned _) -> bool
| hb_filter ([&] (unsigned _)
{ return class_def.intersects_class (c->glyphs, _); },
hb_first)
| hb_map (hb_second)
| hb_apply ([&] (const OffsetTo<RuleSet> &_) { (this+_).closure (c, lookup_context); })
| hb_map (hb_add (this))
| hb_apply ([&] (const RuleSet &_) { _.closure (c, lookup_context); })
;
}
@ -1586,7 +1595,8 @@ struct ContextFormat2
};
+ hb_iter (ruleSet)
| hb_apply ([&] (const OffsetTo<RuleSet> &_) { (this+_).collect_glyphs (c, lookup_context); })
| hb_map (hb_add (this))
| hb_apply ([&] (const RuleSet &_) { _.collect_glyphs (c, lookup_context); })
;
}
@ -2022,7 +2032,8 @@ struct ChainRuleSet
{
return
+ hb_iter (rule)
| hb_map ([&] (const OffsetTo<ChainRule> &_) -> bool { return (this+_).intersects (glyphs, lookup_context); })
| hb_map (hb_add (this))
| hb_map ([&] (const ChainRule &_) { return _.intersects (glyphs, lookup_context); })
| hb_any
;
}
@ -2030,7 +2041,8 @@ struct ChainRuleSet
{
return
+ hb_iter (rule)
| hb_apply ([&] (const OffsetTo<ChainRule> &_) { (this+_).closure (c, lookup_context); })
| hb_map (hb_add (this))
| hb_apply ([&] (const ChainRule &_) { _.closure (c, lookup_context); })
;
}
@ -2038,7 +2050,8 @@ struct ChainRuleSet
{
return
+ hb_iter (rule)
| hb_apply ([&] (const OffsetTo<ChainRule> &_) { (this+_).collect_glyphs (c, lookup_context); })
| hb_map (hb_add (this))
| hb_apply ([&] (const ChainRule &_) { _.collect_glyphs (c, lookup_context); })
;
}
@ -2046,7 +2059,8 @@ struct ChainRuleSet
{
return
+ hb_iter (rule)
| hb_map ([&] (const OffsetTo<ChainRule> &_) -> bool { return (this+_).would_apply (c, lookup_context); })
| hb_map (hb_add (this))
| hb_map ([&] (const ChainRule &_) { return _.would_apply (c, lookup_context); })
| hb_any
;
}
@ -2056,7 +2070,8 @@ struct ChainRuleSet
TRACE_APPLY (this);
return_trace (
+ hb_iter (rule)
| hb_map ([&] (const OffsetTo<ChainRule> &_) -> bool { return (this+_).apply (c, lookup_context); })
| hb_map (hb_add (this))
| hb_map ([&] (const ChainRule &_) { return _.apply (c, lookup_context); })
| hb_any
)
;
@ -2089,7 +2104,8 @@ struct ChainContextFormat1
+ hb_zip (this+coverage, ruleSet)
| hb_filter (*glyphs, hb_first)
| hb_map (hb_second)
| hb_map ([&] (const OffsetTo<ChainRuleSet> &_) -> bool { return (this+_).intersects (glyphs, lookup_context); })
| hb_map (hb_add (this))
| hb_map ([&] (const ChainRuleSet &_) { return _.intersects (glyphs, lookup_context); })
| hb_any
;
}
@ -2104,7 +2120,8 @@ struct ChainContextFormat1
+ hb_zip (this+coverage, ruleSet)
| hb_filter (*c->glyphs, hb_first)
| hb_map (hb_second)
| hb_apply ([&] (const OffsetTo<ChainRuleSet> &_) { (this+_).closure (c, lookup_context); })
| hb_map (hb_add (this))
| hb_apply ([&] (const ChainRuleSet &_) { _.closure (c, lookup_context); })
;
}
@ -2118,7 +2135,8 @@ struct ChainContextFormat1
};
+ hb_iter (ruleSet)
| hb_apply ([&] (const OffsetTo<ChainRuleSet> &_) { (this+_).collect_glyphs (c, lookup_context); })
| hb_map (hb_add (this))
| hb_apply ([&] (const ChainRuleSet &_) { _.collect_glyphs (c, lookup_context); })
;
}
@ -2193,9 +2211,9 @@ struct ChainContextFormat2
return
+ hb_enumerate (ruleSet)
| hb_map ([&] (const hb_pair_t<unsigned, const OffsetTo<ChainRuleSet> &> p) -> bool
{ return input_class_def.intersects_class (glyphs, p.first) &&
(this+p.second).intersects (glyphs, lookup_context); })
| hb_map ([&] (const hb_pair_t<unsigned, const OffsetTo<ChainRuleSet> &> p)
{ return input_class_def.intersects_class (glyphs, p.first) &&
(this+p.second).intersects (glyphs, lookup_context); })
| hb_any
;
}
@ -2217,11 +2235,12 @@ struct ChainContextFormat2
return
+ hb_enumerate (ruleSet)
| hb_filter ([&] (unsigned _) -> bool
| hb_filter ([&] (unsigned _)
{ return input_class_def.intersects_class (c->glyphs, _); },
hb_first)
| hb_map (hb_second)
| hb_apply ([&] (const OffsetTo<ChainRuleSet> &_) { (this+_).closure (c, lookup_context); })
| hb_map (hb_add (this))
| hb_apply ([&] (const ChainRuleSet &_) { _.closure (c, lookup_context); })
;
}
@ -2241,7 +2260,8 @@ struct ChainContextFormat2
};
+ hb_iter (ruleSet)
| hb_apply ([&] (const OffsetTo<ChainRuleSet> &_) { (this+_).collect_glyphs (c, lookup_context); })
| hb_map (hb_add (this))
| hb_apply ([&] (const ChainRuleSet &_) { _.collect_glyphs (c, lookup_context); })
;
}
@ -2504,11 +2524,7 @@ struct ExtensionFormat1
template <typename X>
const X& get_subtable () const
{
unsigned int offset = extensionOffset;
if (unlikely (!offset)) return Null(typename T::SubTable);
return StructAtOffset<typename T::SubTable> (this, offset);
}
{ return this + CastR<LOffsetTo<typename T::SubTable>> (extensionOffset); }
template <typename context_t, typename ...Ts>
typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
@ -2523,7 +2539,6 @@ struct ExtensionFormat1
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
extensionOffset != 0 &&
extensionLookupType != T::SubTable::Extension);
}
@ -2532,7 +2547,7 @@ struct ExtensionFormat1
HBUINT16 extensionLookupType; /* Lookup type of subtable referenced
* by ExtensionOffset (i.e. the
* extension subtable). */
HBUINT32 extensionOffset; /* Offset to the extension subtable,
Offset32 extensionOffset; /* Offset to the extension subtable,
* of lookup type subtable. */
public:
DEFINE_SIZE_STATIC (8);
@ -2666,7 +2681,7 @@ struct GSUBGPOS
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
struct GSUBGPOS *out = c->serializer->embed (*this);
auto *out = c->serializer->embed (*this);
if (unlikely (!out)) return_trace (false);
out->scriptList.serialize_subset (c, this+scriptList, out);
@ -2676,7 +2691,7 @@ struct GSUBGPOS
/* TODO Use intersects() to count how many subtables survive? */
CastR<OffsetTo<TLookupList>> (out->lookupList)
.serialize_subset (c,
this+CastR<const OffsetTo<TLookupList>> (lookupList),
this+CastR<OffsetTo<TLookupList>> (lookupList),
out);
if (version.to_int () >= 0x00010001u)

View File

@ -138,7 +138,7 @@ bool
OT::GDEF::is_blacklisted (hb_blob_t *blob,
hb_face_t *face) const
{
#if defined(HB_NO_OT_LAYOUT_BLACKLIST)
#ifdef HB_NO_OT_LAYOUT_BLACKLIST
return false;
#endif
/* The ugly business of blacklisting individual fonts' tables happen here!
@ -335,6 +335,12 @@ hb_ot_layout_get_attach_points (hb_face_t *face,
unsigned int *point_count /* IN/OUT */,
unsigned int *point_array /* OUT */)
{
#ifdef HB_NO_LAYOUT_UNUSED
if (point_count)
*point_count = 0;
return 0;
#endif
return face->table.GDEF->table->get_attach_points (glyph,
start_offset,
point_count,
@ -364,6 +370,12 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font,
unsigned int *caret_count /* IN/OUT */,
hb_position_t *caret_array /* OUT */)
{
#ifdef HB_NO_LAYOUT_UNUSED
if (caret_count)
*caret_count = 0;
return 0;
#endif
unsigned int result_caret_count = 0;
unsigned int result = font->face->table.GDEF->table->get_lig_carets (font, direction, glyph, start_offset, &result_caret_count, caret_array);
if (result)
@ -384,7 +396,7 @@ bool
OT::GSUB::is_blacklisted (hb_blob_t *blob HB_UNUSED,
hb_face_t *face) const
{
#if defined(HB_NO_OT_LAYOUT_BLACKLIST)
#ifdef HB_NO_OT_LAYOUT_BLACKLIST
return false;
#endif
/* Mac OS X prefers morx over GSUB. It also ships with various Indic fonts,
@ -412,7 +424,7 @@ bool
OT::GPOS::is_blacklisted (hb_blob_t *blob HB_UNUSED,
hb_face_t *face HB_UNUSED) const
{
#if defined(HB_NO_OT_LAYOUT_BLACKLIST)
#ifdef HB_NO_OT_LAYOUT_BLACKLIST
return false;
#endif
return false;
@ -500,6 +512,7 @@ hb_ot_layout_table_find_script (hb_face_t *face,
return false;
}
#ifndef HB_DISABLE_DEPRECATED
/**
* hb_ot_layout_table_choose_script:
* @face: #hb_face_t to work upon
@ -521,6 +534,7 @@ hb_ot_layout_table_choose_script (hb_face_t *face,
for (t = script_tags; *t; t++);
return hb_ot_layout_table_select_script (face, table_tag, t - script_tags, script_tags, script_index, chosen_script);
}
#endif
/**
* hb_ot_layout_table_select_script:
@ -672,6 +686,7 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face,
}
#ifndef HB_DISABLE_DEPRECATED
/**
* hb_ot_layout_script_find_language:
* @face: #hb_face_t to work upon
@ -685,6 +700,8 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face,
*
* Return value: true if the language tag is found, false otherwise
*
* Since: ??
* Deprecated: ??
**/
hb_bool_t
hb_ot_layout_script_find_language (hb_face_t *face,
@ -700,6 +717,7 @@ hb_ot_layout_script_find_language (hb_face_t *face,
&language_tag,
language_index);
}
#endif
/**
@ -716,7 +734,6 @@ hb_ot_layout_script_find_language (hb_face_t *face,
*
* Return value: true if the language tag is found, false otherwise
*
*
* Since: 2.0.0
**/
hb_bool_t

View File

@ -94,7 +94,7 @@ HB_EXTERN hb_bool_t
hb_ot_layout_has_glyph_classes (hb_face_t *face);
/**
* hb_ot_layout_get_glyph_class:
* hb_ot_layout_glyph_class_t:
* @HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED: Glyphs not matching the other classifications
* @HB_OT_LAYOUT_GLYPH_CLASS_BASE_GLYPH: Spacing, single characters, capable of accepting marks
* @HB_OT_LAYOUT_GLYPH_CLASS_LIGATURE: Glyphs that represent ligation of multiple characters

View File

@ -37,6 +37,11 @@
* @include: hb-ot.h
*
* Functions for fetching mathematics layout data from OpenType fonts.
*
* HarfBuzz itself does not implement a math layout solution. The
* functions and types provided can be used by client programs to access
* the font data necessary for typesetting OpenType Math layout.
*
**/
@ -48,31 +53,36 @@
* hb_ot_math_has_data:
* @face: #hb_face_t to test
*
* This function allows to verify the presence of an OpenType MATH table on the
* face.
* Tests whether a face has a `MATH` table.
*
* Return value: true if face has a MATH table, false otherwise
* Return value: true if the table is found, false otherwise
*
* Since: 1.3.3
**/
hb_bool_t
hb_ot_math_has_data (hb_face_t *face)
{
#ifdef HB_NO_MATH
return false;
#endif
return face->table.MATH->has_data ();
}
/**
* hb_ot_math_get_constant:
* @font: #hb_font_t from which to retrieve the value
* @font: #hb_font_t to work upon
* @constant: #hb_ot_math_constant_t the constant to retrieve
*
* This function returns the requested math constants as a #hb_position_t.
* If the request constant is HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN,
* HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN or
* HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN then the return value is
* actually an integer between 0 and 100 representing that percentage.
* Fetches the specified math constant. For most constants, the value returned
* is an #hb_position_t.
*
* Return value: the requested constant or 0
* However, if the requested constant is #HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN,
* #HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN or
* #HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN, then the return value is
* an integer between 0 and 100 representing that percentage.
*
* Return value: the requested constant or zero
*
* Since: 1.3.3
**/
@ -80,15 +90,22 @@ hb_position_t
hb_ot_math_get_constant (hb_font_t *font,
hb_ot_math_constant_t constant)
{
#ifdef HB_NO_MATH
return 0;
#endif
return font->face->table.MATH->get_constant(constant, font);
}
/**
* hb_ot_math_get_glyph_italics_correction:
* @font: #hb_font_t from which to retrieve the value
* @glyph: glyph index from which to retrieve the value
* @font: #hb_font_t to work upon
* @glyph: The glyph index from which to retrieve the value
*
* Return value: the italics correction of the glyph or 0
* Fetches an italics-correction value (if one exists) for the specified
* glyph index.
*
* Return value: the italics correction of the glyph or zero
*
* Since: 1.3.3
**/
@ -96,15 +113,29 @@ hb_position_t
hb_ot_math_get_glyph_italics_correction (hb_font_t *font,
hb_codepoint_t glyph)
{
#ifdef HB_NO_MATH
return 0;
#endif
return font->face->table.MATH->get_glyph_info().get_italics_correction (glyph, font);
}
/**
* hb_ot_math_get_glyph_top_accent_attachment:
* @font: #hb_font_t from which to retrieve the value
* @glyph: glyph index from which to retrieve the value
* @font: #hb_font_t to work upon
* @glyph: The glyph index from which to retrieve the value
*
* Return value: the top accent attachment of the glyph or 0
* Fetches a top-accent-attachment value (if one exists) for the specified
* glyph index.
*
* For any glyph that does not have a top-accent-attachment value - that is,
* a glyph not covered by the `MathTopAccentAttachment` table (or, when
* @font has no `MathTopAccentAttachment` table or no `MATH` table, any
* glyph) - the function synthesizes a value, returning the position at
* one-half the glyph's advance width.
*
* Return value: the top accent attachment of the glyph or 0.5 * the advance
* width of @glyph
*
* Since: 1.3.3
**/
@ -112,13 +143,19 @@ hb_position_t
hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font,
hb_codepoint_t glyph)
{
#ifdef HB_NO_MATH
return 0;
#endif
return font->face->table.MATH->get_glyph_info().get_top_accent_attachment (glyph, font);
}
/**
* hb_ot_math_is_glyph_extended_shape:
* @face: a #hb_face_t to test
* @glyph: a glyph index to test
* @face: #hb_face_t to work upon
* @glyph: The glyph index to test
*
* Tests whether the given glyph index is an extended shape in the face.
*
* Return value: true if the glyph is an extended shape, false otherwise
*
@ -128,23 +165,29 @@ hb_bool_t
hb_ot_math_is_glyph_extended_shape (hb_face_t *face,
hb_codepoint_t glyph)
{
#ifdef HB_NO_MATH
return false;
#endif
return face->table.MATH->get_glyph_info().is_extended_shape (glyph);
}
/**
* hb_ot_math_get_glyph_kerning:
* @font: #hb_font_t from which to retrieve the value
* @glyph: glyph index from which to retrieve the value
* @kern: the #hb_ot_math_kern_t from which to retrieve the value
* @font: #hb_font_t to work upon
* @glyph: The glyph index from which to retrieve the value
* @kern: The #hb_ot_math_kern_t from which to retrieve the value
* @correction_height: the correction height to use to determine the kerning.
*
* This function tries to retrieve the MathKern table for the specified font,
* glyph and #hb_ot_math_kern_t. Then it browses the list of heights from the
* MathKern table to find one value that is greater or equal to specified
* correction_height. If one is found the corresponding value from the list of
* kerns is returned and otherwise the last kern value is returned.
* Fetches the math kerning (cut-ins) value for the specified font, glyph index, and
* @kern.
*
* Return value: requested kerning or 0
* If the MathKern table is found, the function examines it to find a height
* value that is greater or equal to @correction_height. If such a height
* value is found, corresponding kerning value from the table is returned. If
* no such height value is found, the last kerning value is returned.
*
* Return value: requested kerning value or zero
*
* Since: 1.3.3
**/
@ -154,6 +197,10 @@ hb_ot_math_get_glyph_kerning (hb_font_t *font,
hb_ot_math_kern_t kern,
hb_position_t correction_height)
{
#ifdef HB_NO_MATH
return 0;
#endif
return font->face->table.MATH->get_glyph_info().get_kerning (glyph,
kern,
correction_height,
@ -162,20 +209,24 @@ hb_ot_math_get_glyph_kerning (hb_font_t *font,
/**
* hb_ot_math_get_glyph_variants:
* @font: #hb_font_t from which to retrieve the values
* @glyph: index of the glyph to stretch
* @direction: direction of the stretching
* @font: #hb_font_t to work upon
* @glyph: The index of the glyph to stretch
* @direction: The direction of the stretching (horizontal or vertical)
* @start_offset: offset of the first variant to retrieve
* @variants_count: maximum number of variants to retrieve after start_offset
* (IN) and actual number of variants retrieved (OUT)
* @variants: array of size at least @variants_count to store the result
* @variants_count: (inout): Input = the maximum number of variants to return;
* Output = the actual number of variants returned
* @variants: (out) (array length=variants_count): array of variants returned
*
* This function tries to retrieve the MathGlyphConstruction for the specified
* font, glyph and direction. Note that only the value of
* #HB_DIRECTION_IS_HORIZONTAL is considered. It provides the corresponding list
* of size variants as an array of hb_ot_math_glyph_variant_t structs.
* Fetches the MathGlyphConstruction for the specified font, glyph index, and
* direction. The corresponding list of size variants is returned as a list of
* #hb_ot_math_glyph_variant_t structs.
*
* Return value: the total number of size variants available or 0
* <note>The @direction parameter is only used to select between horizontal
* or vertical directions for the construction. Even though all #hb_direction_t
* values are accepted, only the result of #HB_DIRECTION_IS_HORIZONTAL is
* considered.</note>
*
* Return value: the total number of size variants available or zero
*
* Since: 1.3.3
**/
@ -187,6 +238,12 @@ hb_ot_math_get_glyph_variants (hb_font_t *font,
unsigned int *variants_count, /* IN/OUT */
hb_ot_math_glyph_variant_t *variants /* OUT */)
{
#ifdef HB_NO_MATH
if (variants_count)
*variants_count = 0;
return 0;
#endif
return font->face->table.MATH->get_variants().get_glyph_variants (glyph, direction, font,
start_offset,
variants_count,
@ -195,15 +252,19 @@ hb_ot_math_get_glyph_variants (hb_font_t *font,
/**
* hb_ot_math_get_min_connector_overlap:
* @font: #hb_font_t from which to retrieve the value
* @direction: direction of the stretching
* @font: #hb_font_t to work upon
* @direction: direction of the stretching (horizontal or vertical)
*
* This function tries to retrieve the MathVariants table for the specified
* font and returns the minimum overlap of connecting glyphs to draw a glyph
* assembly in the specified direction. Note that only the value of
* #HB_DIRECTION_IS_HORIZONTAL is considered.
* Fetches the MathVariants table for the specified font and returns the
* minimum overlap of connecting glyphs that are required to draw a glyph
* assembly in the specified direction.
*
* Return value: requested min connector overlap or 0
* <note>The @direction parameter is only used to select between horizontal
* or vertical directions for the construction. Even though all #hb_direction_t
* values are accepted, only the result of #HB_DIRECTION_IS_HORIZONTAL is
* considered.</note>
*
* Return value: requested minimum connector overlap or zero
*
* Since: 1.3.3
**/
@ -211,24 +272,33 @@ hb_position_t
hb_ot_math_get_min_connector_overlap (hb_font_t *font,
hb_direction_t direction)
{
#ifdef HB_NO_MATH
return 0;
#endif
return font->face->table.MATH->get_variants().get_min_connector_overlap (direction, font);
}
/**
* hb_ot_math_get_glyph_assembly:
* @font: #hb_font_t from which to retrieve the values
* @glyph: index of the glyph to stretch
* @direction: direction of the stretching
* @font: #hb_font_t to work upon
* @glyph: The index of the glyph to stretch
* @direction: direction of the stretching (horizontal or vertical)
* @start_offset: offset of the first glyph part to retrieve
* @parts_count: maximum number of glyph parts to retrieve after start_offset
* (IN) and actual number of parts retrieved (OUT)
* @parts: array of size at least @parts_count to store the result
* @italics_correction: italic correction of the glyph assembly
* @parts_count: (inout): Input = maximum number of glyph parts to return;
* Output = actual number of parts returned
* @parts: (out) (array length=parts_count): the glyph parts returned
* @italics_correction: (out): italics correction of the glyph assembly
*
* This function tries to retrieve the GlyphAssembly for the specified font,
* glyph and direction. Note that only the value of #HB_DIRECTION_IS_HORIZONTAL
* is considered. It provides the information necessary to draw the glyph
* assembly as an array of #hb_ot_math_glyph_part_t.
* Fetches the GlyphAssembly for the specified font, glyph index, and direction.
* Returned are a list of #hb_ot_math_glyph_part_t glyph parts that can be
* used to draw the glyph and an italics-correction value (if one is defined
* in the font).
*
* <note>The @direction parameter is only used to select between horizontal
* or vertical directions for the construction. Even though all #hb_direction_t
* values are accepted, only the result of #HB_DIRECTION_IS_HORIZONTAL is
* considered.</note>
*
* Return value: the total number of parts in the glyph assembly
*
@ -243,6 +313,12 @@ hb_ot_math_get_glyph_assembly (hb_font_t *font,
hb_ot_math_glyph_part_t *parts, /* OUT */
hb_position_t *italics_correction /* OUT */)
{
#ifdef HB_NO_MATH
if (parts_count)
*parts_count = 0;
return 0;
#endif
return font->face->table.MATH->get_variants().get_glyph_parts (glyph,
direction,
font,

View File

@ -50,6 +50,9 @@ HB_BEGIN_DECLS
/**
* hb_ot_math_constant_t:
*
* The 'MATH' table constants specified at
* https://docs.microsoft.com/en-us/typography/opentype/spec/math
*
* Since: 1.3.3
*/
typedef enum {
@ -114,6 +117,9 @@ typedef enum {
/**
* hb_ot_math_kern_t:
*
* The math kerning-table types defined for the four corners
* of a glyph.
*
* Since: 1.3.3
*/
typedef enum {
@ -125,6 +131,10 @@ typedef enum {
/**
* hb_ot_math_glyph_variant_t:
* @glyph: The glyph index of the variant
* @advance: The advance width of the variant
*
* Data type to hold math-variant information for a glyph.
*
* Since: 1.3.3
*/
@ -136,6 +146,8 @@ typedef struct hb_ot_math_glyph_variant_t {
/**
* hb_ot_math_glyph_part_flags_t:
*
* Flags for math glyph parts.
*
* Since: 1.3.3
*/
typedef enum { /*< flags >*/
@ -144,6 +156,15 @@ typedef enum { /*< flags >*/
/**
* hb_ot_math_glyph_part_t:
* @glyph: The glyph index of the variant part
* @start_connector_length: The length of the connector on the starting side of the variant part
* @end_connection_length: The length of the conector on the ending side of the variant part
* @full_advance: The total advance of the part
* @flags: #hb_ot_math_glyph_part_flags_t flags for the part
*
* Data type to hold information for a "part" component of a math-variant glyph.
* Large variants for stretchable math glyphs (such as parentheses) can be constructed
* on the fly from parts.
*
* Since: 1.3.3
*/

View File

@ -430,6 +430,9 @@ _hb_ot_name_language_for (unsigned int code,
const hb_ot_language_map_t *array,
unsigned int len)
{
#ifdef HB_NO_OT_NAME_LANGUAGE
return HB_LANGUAGE_INVALID;
#endif
const hb_ot_language_map_t *entry = (const hb_ot_language_map_t *)
hb_bsearch (&code,
array,

View File

@ -51,6 +51,7 @@ struct NameRecord
{
hb_language_t language (hb_face_t *face) const
{
#ifndef HB_NO_OT_NAME_LANGUAGE
unsigned int p = platformID;
unsigned int l = languageID;
@ -60,11 +61,12 @@ struct NameRecord
if (p == 1)
return _hb_ot_name_language_for_mac_code (l);
#if !defined(HB_NO_NAME_TABLE_AAT)
#ifndef HB_NO_OT_NAME_LANGUAGE_AAT
if (p == 0)
return _hb_aat_language_get (face, l);
#endif
#endif
return HB_LANGUAGE_INVALID;
}
@ -190,7 +192,7 @@ struct name
const void *dst_string_pool = &(this + this->stringOffset);
+ it
| hb_apply ([&] (const NameRecord& _) { c->copy (_, src_string_pool, dst_string_pool); })
| hb_apply ([=] (const NameRecord& _) { c->copy (_, src_string_pool, dst_string_pool); })
;
if (unlikely (c->ran_out_of_room)) return_trace (false);

View File

@ -58,6 +58,11 @@ const hb_ot_name_entry_t *
hb_ot_name_list_names (hb_face_t *face,
unsigned int *num_entries /* OUT */)
{
#ifdef HB_NO_NAME
if (num_entries)
*num_entries = 0;
return 0;
#endif
const OT::name_accelerator_t &name = *face->table.name;
if (num_entries) *num_entries = name.names.length;
return (const hb_ot_name_entry_t *) name.names;
@ -93,7 +98,7 @@ hb_ot_name_convert_utf (hb_bytes_t bytes,
dst = dst_next;
src = src_next;
};
}
*text_size = dst - text;
*dst = 0; /* NUL-terminate. */
@ -105,7 +110,7 @@ hb_ot_name_convert_utf (hb_bytes_t bytes,
{
src = in_utf_t::next (src, src_end, &unicode, replacement);
dst_len += out_utf_t::encode_len (unicode);
};
}
return dst_len;
}
@ -167,6 +172,11 @@ hb_ot_name_get_utf8 (hb_face_t *face,
unsigned int *text_size /* IN/OUT */,
char *text /* OUT */)
{
#ifdef HB_NO_NAME
if (text_size)
*text_size = 0;
return 0;
#endif
return hb_ot_name_get_utf<hb_utf8_t> (face, name_id, language, text_size,
(hb_utf8_t::codepoint_t *) text);
}
@ -194,6 +204,11 @@ hb_ot_name_get_utf16 (hb_face_t *face,
unsigned int *text_size /* IN/OUT */,
uint16_t *text /* OUT */)
{
#ifdef HB_NO_NAME
if (text_size)
*text_size = 0;
return 0;
#endif
return hb_ot_name_get_utf<hb_utf16_t> (face, name_id, language, text_size, text);
}
@ -220,5 +235,10 @@ hb_ot_name_get_utf32 (hb_face_t *face,
unsigned int *text_size /* IN/OUT */,
uint32_t *text /* OUT */)
{
#ifdef HB_NO_NAME
if (text_size)
*text_size = 0;
return 0;
#endif
return hb_ot_name_get_utf<hb_utf32_t> (face, name_id, language, text_size, text);
}

View File

@ -383,7 +383,7 @@ arabic_fallback_shape (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
#if defined(HB_NO_OT_SHAPE_COMPLEX_ARABIC_FALLBACK)
#ifdef HB_NO_OT_SHAPE_COMPLEX_ARABIC_FALLBACK
return;
#endif

View File

@ -70,7 +70,7 @@ compose_hebrew (const hb_ot_shape_normalize_context_t *c,
bool found = (bool) c->unicode->compose (a, b, ab);
#if defined(HB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK)
#ifdef HB_NO_OT_SHAPE_COMPLEX_HEBREW_FALLBACK
return found;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -64,14 +64,14 @@ reph = (Ra H | Repha); # possible reph
cn = c.ZWJ?.n?;
forced_rakar = ZWJ H ZWJ Ra;
symbol = Symbol.N?;
matra_group = z{0,3}.M.N?.(H | forced_rakar)?;
syllable_tail = (z?.SM.SM?.ZWNJ?)? A{0,3}?;
matra_group = z*.M.N?.(H | forced_rakar)?;
syllable_tail = (z?.SM.SM?.ZWNJ?)? A*;
halant_group = (z?.H.(ZWJ.N?)?);
final_halant_group = halant_group | H.ZWNJ;
medial_group = CM?;
halant_or_matra_group = (final_halant_group | matra_group{0,4});
halant_or_matra_group = (final_halant_group | matra_group*);
complex_syllable_tail = (halant_group.cn){0,4} medial_group halant_or_matra_group syllable_tail;
complex_syllable_tail = (halant_group.cn)* medial_group halant_or_matra_group syllable_tail;
consonant_syllable = (Repha|CS)? cn complex_syllable_tail;
vowel_syllable = reph? V.n? (ZWJ | complex_syllable_tail);

View File

@ -274,7 +274,11 @@ struct indic_shape_plan_t
const indic_config_t *config;
bool is_old_spec;
#ifndef HB_NO_UNISCRIBE_BUG_COMPATIBLE
bool uniscribe_bug_compatible;
#else
static constexpr bool uniscribe_bug_compatible = false;
#endif
mutable hb_atomic_int_t virama_glyph;
would_substitute_feature_t rphf;
@ -300,7 +304,9 @@ data_create_indic (const hb_ot_shape_plan_t *plan)
}
indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FFu) != '2');
#ifndef HB_NO_UNISCRIBE_BUG_COMPATIBLE
indic_plan->uniscribe_bug_compatible = hb_options ().uniscribe_bug_compatible;
#endif
indic_plan->virama_glyph.set_relaxed (-1);
/* Use zero-context would_substitute() matching for new-spec of the main
@ -918,11 +924,10 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
unsigned int start, unsigned int end)
{
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
/* We treat placeholder/dotted-circle as if they are consonants, so we
* should just chain. Only if not in compatibility mode that is... */
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
if (indic_plan->uniscribe_bug_compatible)
{
/* For dotted-circle, this is what Uniscribe does:
@ -1371,13 +1376,15 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
* TEST: U+0930,U+094D,U+0915,U+094B,U+094D
*/
if (!indic_plan->uniscribe_bug_compatible &&
unlikely (is_halant (info[new_reph_pos]))) {
unlikely (is_halant (info[new_reph_pos])))
{
for (unsigned int i = base + 1; i < new_reph_pos; i++)
if (info[i].indic_category() == OT_M) {
/* Ok, got it. */
new_reph_pos--;
}
}
goto reph_move;
}
@ -1590,11 +1597,10 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c,
* https://docs.microsoft.com/en-us/typography/script-development/sinhala#shaping
*/
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) c->plan->data;
hb_codepoint_t glyph;
if (hb_options ().uniscribe_bug_compatible ||
if (indic_plan->uniscribe_bug_compatible ||
(c->font->get_nominal_glyph (ab, &glyph) &&
indic_plan->pstf.would_substitute (&glyph, 1, c->font->face)))
{

View File

@ -278,7 +278,7 @@ matra_position_indic (hb_codepoint_t u, indic_position_t side)
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;
}

View File

@ -1,28 +1,30 @@
#line 1 "hb-ot-shape-complex-khmer-machine.rl"
/*
* Copyright © 2011,2012 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
*/
* Copyright © 2011,2012 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_MACHINE_HH
#define HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH
@ -30,185 +32,180 @@
#include "hb.hh"
#line 36 "hb-ot-shape-complex-khmer-machine.hh"
static const unsigned char _khmer_syllable_machine_trans_keys[] = {
2u, 8u, 2u, 6u, 2u, 8u, 2u, 6u,
0u, 0u, 2u, 6u, 2u, 8u, 2u, 6u,
2u, 8u, 2u, 6u, 2u, 6u, 2u, 8u,
2u, 6u, 0u, 0u, 2u, 6u, 2u, 8u,
2u, 6u, 2u, 8u, 2u, 6u, 2u, 8u,
0u, 11u, 2u, 11u, 2u, 11u, 2u, 11u,
7u, 7u, 2u, 7u, 2u, 11u, 2u, 11u,
2u, 11u, 0u, 0u, 2u, 8u, 2u, 11u,
2u, 11u, 7u, 7u, 2u, 7u, 2u, 11u,
2u, 11u, 0u, 0u, 2u, 11u, 2u, 11u,
0u
5u, 26u, 5u, 21u, 5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, 5u, 26u, 5u, 21u,
5u, 26u, 5u, 21u, 5u, 21u, 5u, 26u, 5u, 21u, 1u, 16u, 5u, 21u, 5u, 26u,
5u, 21u, 5u, 26u, 5u, 21u, 5u, 26u, 1u, 29u, 5u, 29u, 5u, 29u, 5u, 29u,
22u, 22u, 5u, 22u, 5u, 29u, 5u, 29u, 5u, 29u, 1u, 16u, 5u, 26u, 5u, 29u,
5u, 29u, 22u, 22u, 5u, 22u, 5u, 29u, 5u, 29u, 1u, 16u, 5u, 29u, 5u, 29u,
0
};
static const char _khmer_syllable_machine_char_class[] = {
0, 0, 1, 1, 2, 2, 1, 1,
1, 1, 3, 3, 1, 4, 1, 0,
1, 1, 1, 5, 6, 7, 1, 1,
1, 8, 9, 10, 11, 0
static const char _khmer_syllable_machine_key_spans[] = {
22, 17, 22, 17, 16, 17, 22, 17,
22, 17, 17, 22, 17, 16, 17, 22,
17, 22, 17, 22, 29, 25, 25, 25,
1, 18, 25, 25, 25, 16, 22, 25,
25, 1, 18, 25, 25, 16, 25, 25
};
static const short _khmer_syllable_machine_index_offsets[] = {
0, 7, 12, 19, 24, 25, 30, 37,
42, 49, 54, 59, 66, 71, 72, 77,
84, 89, 96, 101, 108, 120, 130, 140,
150, 151, 157, 167, 177, 187, 188, 195,
205, 215, 216, 222, 232, 242, 243, 253,
0
0, 23, 41, 64, 82, 99, 117, 140,
158, 181, 199, 217, 240, 258, 275, 293,
316, 334, 357, 375, 398, 428, 454, 480,
506, 508, 527, 553, 579, 605, 622, 645,
671, 697, 699, 718, 744, 770, 787, 813
};
static const char _khmer_syllable_machine_indicies[] = {
1, 0, 0, 2, 3, 0, 4, 1,
0, 0, 0, 3, 1, 0, 0, 0,
3, 0, 4, 5, 0, 0, 0, 4,
6, 7, 0, 0, 0, 8, 9, 0,
0, 0, 10, 0, 4, 9, 0, 0,
0, 10, 11, 0, 0, 0, 12, 0,
4, 11, 0, 0, 0, 12, 14, 13,
13, 13, 15, 14, 16, 16, 16, 15,
16, 17, 18, 16, 16, 16, 17, 19,
20, 16, 16, 16, 21, 22, 16, 16,
16, 23, 16, 17, 22, 16, 16, 16,
23, 24, 16, 16, 16, 25, 16, 17,
24, 16, 16, 16, 25, 14, 16, 16,
26, 15, 16, 17, 28, 27, 29, 2,
30, 27, 15, 19, 17, 23, 25, 21,
32, 31, 33, 2, 3, 6, 4, 10,
12, 8, 34, 31, 35, 31, 3, 6,
4, 10, 12, 8, 5, 31, 35, 31,
4, 6, 31, 31, 31, 8, 6, 7,
31, 35, 31, 8, 6, 36, 31, 35,
31, 10, 6, 4, 31, 31, 8, 37,
31, 35, 31, 12, 6, 4, 10, 31,
8, 34, 31, 33, 31, 3, 6, 4,
10, 12, 8, 28, 14, 38, 38, 38,
15, 38, 17, 40, 39, 41, 39, 15,
19, 17, 23, 25, 21, 18, 39, 41,
39, 17, 19, 39, 39, 39, 21, 19,
20, 39, 41, 39, 21, 19, 42, 39,
41, 39, 23, 19, 17, 39, 39, 21,
43, 39, 41, 39, 25, 19, 17, 23,
39, 21, 44, 45, 39, 30, 26, 15,
19, 17, 23, 25, 21, 40, 39, 30,
39, 15, 19, 17, 23, 25, 21, 0
1, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 2,
3, 0, 0, 0, 0, 4, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 3,
0, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 3, 0, 0, 0, 0, 4, 0,
5, 5, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
4, 0, 6, 6, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 6, 0, 7, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 8, 0, 9, 9, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 10, 0, 0,
0, 0, 4, 0, 9, 9, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 10, 0, 11, 11,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 12, 0,
0, 0, 0, 4, 0, 11, 11, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 12, 0, 14,
14, 13, 13, 13, 13, 13, 13, 13,
13, 13, 13, 13, 13, 13, 13, 15,
13, 14, 14, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 15, 16, 16, 16, 16, 17, 16,
18, 18, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
17, 16, 19, 19, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 19, 16, 20, 20, 16, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 21, 16, 22, 22, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 23, 16, 16,
16, 16, 17, 16, 22, 22, 16, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 23, 16, 24, 24,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 25, 16,
16, 16, 16, 17, 16, 24, 24, 16,
16, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 25, 16, 14,
14, 16, 16, 16, 16, 16, 16, 16,
16, 16, 16, 16, 16, 16, 26, 15,
16, 16, 16, 16, 17, 16, 28, 28,
27, 27, 29, 29, 27, 27, 27, 27,
2, 2, 27, 30, 27, 28, 27, 27,
27, 27, 15, 19, 27, 27, 27, 17,
23, 25, 21, 27, 32, 32, 31, 31,
31, 31, 31, 31, 31, 33, 31, 31,
31, 31, 31, 2, 3, 6, 31, 31,
31, 4, 10, 12, 8, 31, 34, 34,
31, 31, 31, 31, 31, 31, 31, 35,
31, 31, 31, 31, 31, 31, 3, 6,
31, 31, 31, 4, 10, 12, 8, 31,
5, 5, 31, 31, 31, 31, 31, 31,
31, 35, 31, 31, 31, 31, 31, 31,
4, 6, 31, 31, 31, 31, 31, 31,
8, 31, 6, 31, 7, 7, 31, 31,
31, 31, 31, 31, 31, 35, 31, 31,
31, 31, 31, 31, 8, 6, 31, 36,
36, 31, 31, 31, 31, 31, 31, 31,
35, 31, 31, 31, 31, 31, 31, 10,
6, 31, 31, 31, 4, 31, 31, 8,
31, 37, 37, 31, 31, 31, 31, 31,
31, 31, 35, 31, 31, 31, 31, 31,
31, 12, 6, 31, 31, 31, 4, 10,
31, 8, 31, 34, 34, 31, 31, 31,
31, 31, 31, 31, 33, 31, 31, 31,
31, 31, 31, 3, 6, 31, 31, 31,
4, 10, 12, 8, 31, 28, 28, 31,
31, 31, 31, 31, 31, 31, 31, 31,
31, 31, 31, 31, 28, 31, 14, 14,
38, 38, 38, 38, 38, 38, 38, 38,
38, 38, 38, 38, 38, 38, 15, 38,
38, 38, 38, 17, 38, 40, 40, 39,
39, 39, 39, 39, 39, 39, 41, 39,
39, 39, 39, 39, 39, 15, 19, 39,
39, 39, 17, 23, 25, 21, 39, 18,
18, 39, 39, 39, 39, 39, 39, 39,
41, 39, 39, 39, 39, 39, 39, 17,
19, 39, 39, 39, 39, 39, 39, 21,
39, 19, 39, 20, 20, 39, 39, 39,
39, 39, 39, 39, 41, 39, 39, 39,
39, 39, 39, 21, 19, 39, 42, 42,
39, 39, 39, 39, 39, 39, 39, 41,
39, 39, 39, 39, 39, 39, 23, 19,
39, 39, 39, 17, 39, 39, 21, 39,
43, 43, 39, 39, 39, 39, 39, 39,
39, 41, 39, 39, 39, 39, 39, 39,
25, 19, 39, 39, 39, 17, 23, 39,
21, 39, 44, 44, 39, 39, 39, 39,
39, 39, 39, 39, 39, 39, 39, 39,
39, 44, 39, 45, 45, 39, 39, 39,
39, 39, 39, 39, 30, 39, 39, 39,
39, 39, 26, 15, 19, 39, 39, 39,
17, 23, 25, 21, 39, 40, 40, 39,
39, 39, 39, 39, 39, 39, 30, 39,
39, 39, 39, 39, 39, 15, 19, 39,
39, 39, 17, 23, 25, 21, 39, 0
};
static const char _khmer_syllable_machine_index_defaults[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 13, 16, 16, 16, 16, 16,
16, 16, 16, 16, 27, 31, 31, 31,
31, 31, 31, 31, 31, 31, 38, 39,
39, 39, 39, 39, 39, 39, 39, 39,
0
static const char _khmer_syllable_machine_trans_targs[] = {
20, 1, 28, 22, 23, 3, 24, 5,
25, 7, 26, 9, 27, 20, 10, 31,
20, 32, 12, 33, 14, 34, 16, 35,
18, 36, 39, 20, 21, 30, 37, 20,
0, 29, 2, 4, 6, 8, 20, 20,
11, 13, 15, 17, 38, 19
};
static const char _khmer_syllable_machine_trans_cond_spaces[] = {
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, 0
};
static const char _khmer_syllable_machine_cond_targs[] = {
20, 1, 28, 22, 23, 3, 24, 5,
25, 7, 26, 9, 27, 20, 10, 31,
20, 32, 12, 33, 14, 34, 16, 35,
18, 36, 39, 20, 21, 30, 37, 20,
0, 29, 2, 4, 6, 8, 20, 20,
11, 13, 15, 17, 38, 19, 0
};
static const char _khmer_syllable_machine_cond_actions[] = {
1, 0, 2, 2, 2, 0, 0, 0,
2, 0, 2, 0, 2, 3, 0, 4,
5, 2, 0, 0, 0, 2, 0, 2,
0, 2, 4, 8, 2, 9, 0, 10,
0, 0, 0, 0, 0, 0, 11, 12,
0, 0, 0, 0, 4, 0, 0
static const char _khmer_syllable_machine_trans_actions[] = {
1, 0, 2, 2, 2, 0, 0, 0,
2, 0, 2, 0, 2, 3, 0, 4,
5, 2, 0, 0, 0, 2, 0, 2,
0, 2, 4, 8, 2, 9, 0, 10,
0, 0, 0, 0, 0, 0, 11, 12,
0, 0, 0, 0, 4, 0
};
static const char _khmer_syllable_machine_to_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 6, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 6, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
static const char _khmer_syllable_machine_from_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 7, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
static const char _khmer_syllable_machine_eof_cond_spaces[] = {
-1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, 0
};
static const char _khmer_syllable_machine_eof_cond_key_offs[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0
};
static const char _khmer_syllable_machine_eof_cond_key_lens[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0
};
static const char _khmer_syllable_machine_eof_cond_keys[] = {
0
};
static const char _khmer_syllable_machine_eof_trans[] = {
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 14, 17, 17, 17, 17, 17,
17, 17, 17, 17, 0, 32, 32, 32,
32, 32, 32, 32, 32, 32, 39, 40,
40, 40, 40, 40, 40, 40, 40, 40,
0
};
static const char _khmer_syllable_machine_nfa_targs[] = {
0, 0
};
static const char _khmer_syllable_machine_nfa_offsets[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0
};
static const char _khmer_syllable_machine_nfa_push_actions[] = {
0, 0
};
static const char _khmer_syllable_machine_nfa_pop_trans[] = {
0, 0
static const unsigned char _khmer_syllable_machine_eof_trans[] = {
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 14, 17, 17, 17, 17, 17,
17, 17, 17, 17, 0, 32, 32, 32,
32, 32, 32, 32, 32, 32, 39, 40,
40, 40, 40, 40, 40, 40, 40, 40
};
static const int khmer_syllable_machine_start = 20;
@ -218,228 +215,156 @@ static const int khmer_syllable_machine_error = -1;
static const int khmer_syllable_machine_en_main = 20;
#line 36 "hb-ot-shape-complex-khmer-machine.rl"
#line 80 "hb-ot-shape-complex-khmer-machine.rl"
#define found_syllable(syllable_type) \
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial=1; \
} HB_STMT_END
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
static void
find_syllables (hb_buffer_t *buffer)
{
unsigned int p, pe, eof, ts, te, act HB_UNUSED;
int cs;
hb_glyph_info_t *info = buffer->info;
unsigned int p, pe, eof, ts, te, act HB_UNUSED;
int cs;
hb_glyph_info_t *info = buffer->info;
#line 242 "hb-ot-shape-complex-khmer-machine.hh"
{
cs = (int)khmer_syllable_machine_start;
ts = 0;
te = 0;
act = 0;
cs = khmer_syllable_machine_start;
ts = 0;
te = 0;
act = 0;
}
p=0;
pe = eof = buffer->len;
unsigned int syllable_serial=1;
#line 100 "hb-ot-shape-complex-khmer-machine.rl"
p = 0;
pe = eof = buffer->len;
unsigned int syllable_serial = 1;
#line 258 "hb-ot-shape-complex-khmer-machine.hh"
{
int _cpc;
int _klen;const char * _cekeys;unsigned int _trans = 0;const unsigned char * _keys;const char * _inds; {
if ( p == pe )
goto _test_eof;
_resume: {
switch ( _khmer_syllable_machine_from_state_actions[cs] ) {
case 7: {
{
#line 1 "NONE"
{ts = p;}}
break; }
}
_keys = ( _khmer_syllable_machine_trans_keys + ((cs<<1)));
_inds = ( _khmer_syllable_machine_indicies + (_khmer_syllable_machine_index_offsets[cs]));
if ( (info[p].khmer_category()) <= 29 && (info[p].khmer_category()) >= 1 )
{
int _ic = (int)_khmer_syllable_machine_char_class[(int)(info[p].khmer_category()) - 1];
if ( _ic <= (int)(*( _keys+1)) && _ic >= (int)(*( _keys)) )
_trans = (unsigned int)(*( _inds + (int)( _ic - (int)(*( _keys)) ) ));
else
_trans = (unsigned int)_khmer_syllable_machine_index_defaults[cs];
}
else {
_trans = (unsigned int)_khmer_syllable_machine_index_defaults[cs];
}
goto _match_cond;
}
_match_cond: {
cs = (int)_khmer_syllable_machine_cond_targs[_trans];
if ( _khmer_syllable_machine_cond_actions[_trans] == 0 )
goto _again;
switch ( _khmer_syllable_machine_cond_actions[_trans] ) {
case 2: {
{
#line 1 "NONE"
{te = p+1;}}
break; }
case 8: {
{
#line 76 "hb-ot-shape-complex-khmer-machine.rl"
{te = p+1;{
#line 76 "hb-ot-shape-complex-khmer-machine.rl"
found_syllable (non_khmer_cluster); }}}
break; }
case 10: {
{
#line 74 "hb-ot-shape-complex-khmer-machine.rl"
{te = p;p = p - 1;{
#line 74 "hb-ot-shape-complex-khmer-machine.rl"
found_syllable (consonant_syllable); }}}
break; }
case 12: {
{
#line 75 "hb-ot-shape-complex-khmer-machine.rl"
{te = p;p = p - 1;{
#line 75 "hb-ot-shape-complex-khmer-machine.rl"
found_syllable (broken_cluster); }}}
break; }
case 11: {
{
#line 76 "hb-ot-shape-complex-khmer-machine.rl"
{te = p;p = p - 1;{
#line 76 "hb-ot-shape-complex-khmer-machine.rl"
found_syllable (non_khmer_cluster); }}}
break; }
case 1: {
{
#line 74 "hb-ot-shape-complex-khmer-machine.rl"
{p = ((te))-1;
{
#line 74 "hb-ot-shape-complex-khmer-machine.rl"
found_syllable (consonant_syllable); }}}
break; }
case 5: {
{
#line 75 "hb-ot-shape-complex-khmer-machine.rl"
{p = ((te))-1;
{
#line 75 "hb-ot-shape-complex-khmer-machine.rl"
found_syllable (broken_cluster); }}}
break; }
case 3: {
{
#line 1 "NONE"
{switch( act ) {
case 2: {
p = ((te))-1;
{
#line 75 "hb-ot-shape-complex-khmer-machine.rl"
found_syllable (broken_cluster); } break; }
case 3: {
p = ((te))-1;
{
#line 76 "hb-ot-shape-complex-khmer-machine.rl"
found_syllable (non_khmer_cluster); } break; }
}}
}
break; }
case 4: {
{
#line 1 "NONE"
{te = p+1;}}
{
#line 75 "hb-ot-shape-complex-khmer-machine.rl"
{act = 2;}}
break; }
case 9: {
{
#line 1 "NONE"
{te = p+1;}}
{
#line 76 "hb-ot-shape-complex-khmer-machine.rl"
{act = 3;}}
break; }
}
}
_again: {
switch ( _khmer_syllable_machine_to_state_actions[cs] ) {
case 6: {
{
#line 1 "NONE"
{ts = 0;}}
break; }
}
p += 1;
if ( p != pe )
goto _resume;
}
_test_eof: { {}
if ( p == eof )
{
if ( _khmer_syllable_machine_eof_cond_spaces[cs] != -1 ) {
_cekeys = ( _khmer_syllable_machine_eof_cond_keys + (_khmer_syllable_machine_eof_cond_key_offs[cs]));
_klen = (int)_khmer_syllable_machine_eof_cond_key_lens[cs];
_cpc = 0;
{
const char *_lower = _cekeys;
const char *_upper = _cekeys + _klen - 1;
const char *_mid;
while ( 1 ) {
if ( _upper < _lower )
break;
_mid = _lower + ((_upper-_lower) >> 1);
if ( _cpc < (int)(*( _mid)) )
_upper = _mid - 1;
else if ( _cpc > (int)(*( _mid)) )
_lower = _mid + 1;
else {
goto _ok;
}
}
cs = -1;
goto _out;
}
_ok: {}
}
if ( _khmer_syllable_machine_eof_trans[cs] > 0 ) {
_trans = (unsigned int)_khmer_syllable_machine_eof_trans[cs] - 1;
goto _match_cond;
}
}
}
_out: { {}
}
}
int _slen;
int _trans;
const unsigned char *_keys;
const char *_inds;
if ( p == pe )
goto _test_eof;
_resume:
switch ( _khmer_syllable_machine_from_state_actions[cs] ) {
case 7:
#line 1 "NONE"
{ts = p;}
break;
#line 272 "hb-ot-shape-complex-khmer-machine.hh"
}
_keys = _khmer_syllable_machine_trans_keys + (cs<<1);
_inds = _khmer_syllable_machine_indicies + _khmer_syllable_machine_index_offsets[cs];
_slen = _khmer_syllable_machine_key_spans[cs];
_trans = _inds[ _slen > 0 && _keys[0] <=( info[p].khmer_category()) &&
( info[p].khmer_category()) <= _keys[1] ?
( info[p].khmer_category()) - _keys[0] : _slen ];
_eof_trans:
cs = _khmer_syllable_machine_trans_targs[_trans];
if ( _khmer_syllable_machine_trans_actions[_trans] == 0 )
goto _again;
switch ( _khmer_syllable_machine_trans_actions[_trans] ) {
case 2:
#line 1 "NONE"
{te = p+1;}
break;
case 8:
#line 76 "hb-ot-shape-complex-khmer-machine.rl"
{te = p+1;{ found_syllable (non_khmer_cluster); }}
break;
case 10:
#line 74 "hb-ot-shape-complex-khmer-machine.rl"
{te = p;p--;{ found_syllable (consonant_syllable); }}
break;
case 12:
#line 75 "hb-ot-shape-complex-khmer-machine.rl"
{te = p;p--;{ found_syllable (broken_cluster); }}
break;
case 11:
#line 76 "hb-ot-shape-complex-khmer-machine.rl"
{te = p;p--;{ found_syllable (non_khmer_cluster); }}
break;
case 1:
#line 74 "hb-ot-shape-complex-khmer-machine.rl"
{{p = ((te))-1;}{ found_syllable (consonant_syllable); }}
break;
case 5:
#line 75 "hb-ot-shape-complex-khmer-machine.rl"
{{p = ((te))-1;}{ found_syllable (broken_cluster); }}
break;
case 3:
#line 1 "NONE"
{ switch( act ) {
case 2:
{{p = ((te))-1;} found_syllable (broken_cluster); }
break;
case 3:
{{p = ((te))-1;} found_syllable (non_khmer_cluster); }
break;
}
}
break;
case 4:
#line 1 "NONE"
{te = p+1;}
#line 75 "hb-ot-shape-complex-khmer-machine.rl"
{act = 2;}
break;
case 9:
#line 1 "NONE"
{te = p+1;}
#line 76 "hb-ot-shape-complex-khmer-machine.rl"
{act = 3;}
break;
#line 342 "hb-ot-shape-complex-khmer-machine.hh"
}
_again:
switch ( _khmer_syllable_machine_to_state_actions[cs] ) {
case 6:
#line 1 "NONE"
{ts = 0;}
break;
#line 351 "hb-ot-shape-complex-khmer-machine.hh"
}
if ( ++p != pe )
goto _resume;
_test_eof: {}
if ( p == eof )
{
if ( _khmer_syllable_machine_eof_trans[cs] > 0 ) {
_trans = _khmer_syllable_machine_eof_trans[cs] - 1;
goto _eof_trans;
}
}
}
#line 108 "hb-ot-shape-complex-khmer-machine.rl"
}
#endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */

View File

@ -105,7 +105,7 @@ set_khmer_properties (hb_glyph_info_t &info)
case POS_ABOVE_C: cat = OT_VAbv; break;
case POS_POST_C: cat = OT_VPst; break;
default: assert (0);
};
}
info.khmer_category() = cat;
}

View File

@ -1,28 +1,30 @@
#line 1 "hb-ot-shape-complex-myanmar-machine.rl"
/*
* Copyright © 2011,2012 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
*/
* Copyright © 2011,2012 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_MACHINE_HH
#define HB_OT_SHAPE_COMPLEX_MYANMAR_MACHINE_HH
@ -30,276 +32,251 @@
#include "hb.hh"
#line 36 "hb-ot-shape-complex-myanmar-machine.hh"
static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
0u, 21u, 1u, 20u, 3u, 19u, 3u, 5u,
3u, 19u, 1u, 15u, 3u, 15u, 3u, 15u,
1u, 19u, 1u, 19u, 1u, 19u, 1u, 19u,
0u, 8u, 1u, 19u, 1u, 19u, 1u, 19u,
1u, 19u, 1u, 19u, 1u, 20u, 1u, 19u,
1u, 19u, 1u, 19u, 1u, 19u, 3u, 19u,
3u, 5u, 3u, 19u, 1u, 15u, 3u, 15u,
3u, 15u, 1u, 19u, 1u, 19u, 1u, 19u,
1u, 19u, 0u, 8u, 1u, 20u, 1u, 19u,
1u, 19u, 1u, 19u, 1u, 19u, 1u, 19u,
1u, 20u, 1u, 19u, 1u, 19u, 1u, 19u,
1u, 19u, 1u, 20u, 1u, 19u, 0u, 20u,
0u, 8u, 5u, 5u, 0u
1u, 32u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u,
3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 5u, 29u,
5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u,
3u, 29u, 1u, 16u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 1u, 32u,
1u, 32u, 8u, 8u, 0
};
static const char _myanmar_syllable_machine_char_class[] = {
0, 0, 1, 2, 3, 3, 4, 5,
4, 6, 7, 4, 4, 4, 4, 8,
4, 9, 10, 4, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 7,
0
static const char _myanmar_syllable_machine_key_spans[] = {
32, 28, 25, 4, 25, 23, 21, 21,
27, 27, 27, 27, 16, 27, 27, 27,
27, 27, 28, 27, 27, 27, 27, 25,
4, 25, 23, 21, 21, 27, 27, 27,
27, 16, 28, 27, 27, 27, 27, 27,
28, 27, 27, 27, 27, 28, 27, 32,
32, 1
};
static const short _myanmar_syllable_machine_index_offsets[] = {
0, 22, 42, 59, 62, 79, 94, 107,
120, 139, 158, 177, 196, 205, 224, 243,
262, 281, 300, 320, 339, 358, 377, 396,
413, 416, 433, 448, 461, 474, 493, 512,
531, 550, 559, 579, 598, 617, 636, 655,
674, 694, 713, 732, 751, 770, 790, 809,
830, 839, 0
0, 33, 62, 88, 93, 119, 143, 165,
187, 215, 243, 271, 299, 316, 344, 372,
400, 428, 456, 485, 513, 541, 569, 597,
623, 628, 654, 678, 700, 722, 750, 778,
806, 834, 851, 880, 908, 936, 964, 992,
1020, 1049, 1077, 1105, 1133, 1161, 1190, 1218,
1251, 1284
};
static const char _myanmar_syllable_machine_indicies[] = {
1, 2, 3, 4, 0, 5, 6, 1,
7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 22, 23,
24, 21, 25, 26, 21, 21, 27, 21,
28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 24, 21, 25, 21, 21, 21,
38, 21, 21, 21, 21, 21, 32, 21,
21, 21, 36, 24, 21, 25, 24, 21,
25, 21, 21, 21, 21, 21, 21, 21,
21, 21, 32, 21, 21, 21, 36, 39,
21, 24, 21, 25, 32, 21, 21, 40,
21, 21, 21, 21, 21, 32, 24, 21,
25, 21, 21, 21, 40, 21, 21, 21,
21, 21, 32, 24, 21, 25, 21, 21,
21, 21, 21, 21, 21, 21, 21, 32,
22, 21, 24, 21, 25, 26, 21, 21,
41, 21, 41, 21, 21, 21, 32, 42,
21, 21, 36, 22, 21, 24, 21, 25,
26, 21, 21, 21, 21, 21, 21, 21,
21, 32, 21, 21, 21, 36, 22, 21,
24, 21, 25, 26, 21, 21, 41, 21,
21, 21, 21, 21, 32, 42, 21, 21,
36, 22, 21, 24, 21, 25, 26, 21,
21, 21, 21, 21, 21, 21, 21, 32,
42, 21, 21, 36, 1, 21, 21, 21,
21, 21, 21, 21, 1, 22, 21, 24,
21, 25, 26, 21, 21, 27, 21, 28,
29, 30, 31, 32, 33, 34, 35, 36,
22, 21, 24, 21, 25, 26, 21, 21,
43, 21, 21, 21, 21, 21, 32, 33,
34, 35, 36, 22, 21, 24, 21, 25,
26, 21, 21, 21, 21, 21, 21, 21,
21, 32, 33, 34, 35, 36, 22, 21,
24, 21, 25, 26, 21, 21, 21, 21,
21, 21, 21, 21, 32, 33, 34, 21,
36, 22, 21, 24, 21, 25, 26, 21,
21, 21, 21, 21, 21, 21, 21, 32,
21, 34, 21, 36, 22, 21, 24, 21,
25, 26, 21, 21, 21, 21, 21, 21,
21, 21, 32, 33, 34, 35, 36, 43,
22, 21, 24, 21, 25, 26, 21, 21,
43, 21, 28, 21, 30, 21, 32, 33,
34, 35, 36, 22, 21, 24, 21, 25,
26, 21, 21, 43, 21, 28, 21, 21,
21, 32, 33, 34, 35, 36, 22, 21,
24, 21, 25, 26, 21, 21, 43, 21,
28, 29, 30, 21, 32, 33, 34, 35,
36, 22, 23, 24, 21, 25, 26, 21,
21, 27, 21, 28, 29, 30, 31, 32,
33, 34, 35, 36, 45, 44, 5, 44,
44, 44, 46, 44, 44, 44, 44, 44,
14, 44, 44, 44, 18, 45, 44, 5,
45, 44, 5, 44, 44, 44, 44, 44,
44, 44, 44, 44, 14, 44, 44, 44,
18, 47, 44, 45, 44, 5, 14, 44,
44, 48, 44, 44, 44, 44, 44, 14,
45, 44, 5, 44, 44, 44, 48, 44,
44, 44, 44, 44, 14, 45, 44, 5,
44, 44, 44, 44, 44, 44, 44, 44,
44, 14, 2, 44, 45, 44, 5, 6,
44, 44, 49, 44, 49, 44, 44, 44,
14, 50, 44, 44, 18, 2, 44, 45,
44, 5, 6, 44, 44, 44, 44, 44,
44, 44, 44, 14, 44, 44, 44, 18,
2, 44, 45, 44, 5, 6, 44, 44,
49, 44, 44, 44, 44, 44, 14, 50,
44, 44, 18, 2, 44, 45, 44, 5,
6, 44, 44, 44, 44, 44, 44, 44,
44, 14, 50, 44, 44, 18, 51, 44,
44, 44, 44, 44, 44, 44, 51, 2,
3, 45, 44, 5, 6, 44, 44, 8,
44, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 2, 44, 45, 44, 5,
6, 44, 44, 8, 44, 10, 11, 12,
13, 14, 15, 16, 17, 18, 2, 44,
45, 44, 5, 6, 44, 44, 52, 44,
44, 44, 44, 44, 14, 15, 16, 17,
18, 2, 44, 45, 44, 5, 6, 44,
44, 44, 44, 44, 44, 44, 44, 14,
15, 16, 17, 18, 2, 44, 45, 44,
5, 6, 44, 44, 44, 44, 44, 44,
44, 44, 14, 15, 16, 44, 18, 2,
44, 45, 44, 5, 6, 44, 44, 44,
44, 44, 44, 44, 44, 14, 44, 16,
44, 18, 2, 44, 45, 44, 5, 6,
44, 44, 44, 44, 44, 44, 44, 44,
14, 15, 16, 17, 18, 52, 2, 44,
45, 44, 5, 6, 44, 44, 52, 44,
10, 44, 12, 44, 14, 15, 16, 17,
18, 2, 44, 45, 44, 5, 6, 44,
44, 52, 44, 10, 44, 44, 44, 14,
15, 16, 17, 18, 2, 44, 45, 44,
5, 6, 44, 44, 52, 44, 10, 11,
12, 44, 14, 15, 16, 17, 18, 2,
3, 45, 44, 5, 6, 44, 44, 8,
44, 10, 11, 12, 13, 14, 15, 16,
17, 18, 22, 23, 24, 21, 25, 26,
21, 21, 53, 21, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 22, 54,
24, 21, 25, 26, 21, 21, 27, 21,
28, 29, 30, 31, 32, 33, 34, 35,
36, 1, 2, 3, 45, 44, 5, 6,
1, 1, 8, 44, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 1, 55,
55, 55, 55, 55, 55, 1, 1, 56,
1, 1, 2, 3, 4, 4, 0, 5,
0, 6, 1, 0, 0, 0, 0, 7,
0, 8, 9, 0, 10, 11, 12, 13,
14, 15, 16, 17, 18, 19, 20, 1,
0, 22, 23, 24, 24, 21, 25, 21,
26, 21, 21, 21, 21, 21, 21, 21,
27, 21, 21, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 21, 24, 24,
21, 25, 21, 21, 21, 21, 21, 21,
21, 21, 21, 38, 21, 21, 21, 21,
21, 21, 32, 21, 21, 21, 36, 21,
24, 24, 21, 25, 21, 24, 24, 21,
25, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21,
21, 32, 21, 21, 21, 36, 21, 39,
21, 24, 24, 21, 25, 21, 32, 21,
21, 21, 21, 21, 21, 21, 40, 21,
21, 21, 21, 21, 21, 32, 21, 24,
24, 21, 25, 21, 21, 21, 21, 21,
21, 21, 21, 21, 40, 21, 21, 21,
21, 21, 21, 32, 21, 24, 24, 21,
25, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21,
21, 32, 21, 22, 21, 24, 24, 21,
25, 21, 26, 21, 21, 21, 21, 21,
21, 21, 41, 21, 21, 41, 21, 21,
21, 32, 42, 21, 21, 36, 21, 22,
21, 24, 24, 21, 25, 21, 26, 21,
21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 32, 21, 21,
21, 36, 21, 22, 21, 24, 24, 21,
25, 21, 26, 21, 21, 21, 21, 21,
21, 21, 41, 21, 21, 21, 21, 21,
21, 32, 42, 21, 21, 36, 21, 22,
21, 24, 24, 21, 25, 21, 26, 21,
21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 32, 42, 21,
21, 36, 21, 1, 1, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 1, 21, 22, 21, 24, 24,
21, 25, 21, 26, 21, 21, 21, 21,
21, 21, 21, 27, 21, 21, 28, 29,
30, 31, 32, 33, 34, 35, 36, 21,
22, 21, 24, 24, 21, 25, 21, 26,
21, 21, 21, 21, 21, 21, 21, 43,
21, 21, 21, 21, 21, 21, 32, 33,
34, 35, 36, 21, 22, 21, 24, 24,
21, 25, 21, 26, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 32, 33, 34, 35, 36, 21,
22, 21, 24, 24, 21, 25, 21, 26,
21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 32, 33,
34, 21, 36, 21, 22, 21, 24, 24,
21, 25, 21, 26, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 32, 21, 34, 21, 36, 21,
22, 21, 24, 24, 21, 25, 21, 26,
21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 32, 33,
34, 35, 36, 43, 21, 22, 21, 24,
24, 21, 25, 21, 26, 21, 21, 21,
21, 21, 21, 21, 43, 21, 21, 28,
21, 30, 21, 32, 33, 34, 35, 36,
21, 22, 21, 24, 24, 21, 25, 21,
26, 21, 21, 21, 21, 21, 21, 21,
43, 21, 21, 28, 21, 21, 21, 32,
33, 34, 35, 36, 21, 22, 21, 24,
24, 21, 25, 21, 26, 21, 21, 21,
21, 21, 21, 21, 43, 21, 21, 28,
29, 30, 21, 32, 33, 34, 35, 36,
21, 22, 23, 24, 24, 21, 25, 21,
26, 21, 21, 21, 21, 21, 21, 21,
27, 21, 21, 28, 29, 30, 31, 32,
33, 34, 35, 36, 21, 45, 45, 44,
5, 44, 44, 44, 44, 44, 44, 44,
44, 44, 46, 44, 44, 44, 44, 44,
44, 14, 44, 44, 44, 18, 44, 45,
45, 44, 5, 44, 45, 45, 44, 5,
44, 44, 44, 44, 44, 44, 44, 44,
44, 44, 44, 44, 44, 44, 44, 44,
14, 44, 44, 44, 18, 44, 47, 44,
45, 45, 44, 5, 44, 14, 44, 44,
44, 44, 44, 44, 44, 48, 44, 44,
44, 44, 44, 44, 14, 44, 45, 45,
44, 5, 44, 44, 44, 44, 44, 44,
44, 44, 44, 48, 44, 44, 44, 44,
44, 44, 14, 44, 45, 45, 44, 5,
44, 44, 44, 44, 44, 44, 44, 44,
44, 44, 44, 44, 44, 44, 44, 44,
14, 44, 2, 44, 45, 45, 44, 5,
44, 6, 44, 44, 44, 44, 44, 44,
44, 49, 44, 44, 49, 44, 44, 44,
14, 50, 44, 44, 18, 44, 2, 44,
45, 45, 44, 5, 44, 6, 44, 44,
44, 44, 44, 44, 44, 44, 44, 44,
44, 44, 44, 44, 14, 44, 44, 44,
18, 44, 2, 44, 45, 45, 44, 5,
44, 6, 44, 44, 44, 44, 44, 44,
44, 49, 44, 44, 44, 44, 44, 44,
14, 50, 44, 44, 18, 44, 2, 44,
45, 45, 44, 5, 44, 6, 44, 44,
44, 44, 44, 44, 44, 44, 44, 44,
44, 44, 44, 44, 14, 50, 44, 44,
18, 44, 51, 51, 44, 44, 44, 44,
44, 44, 44, 44, 44, 44, 44, 44,
44, 51, 44, 2, 3, 45, 45, 44,
5, 44, 6, 44, 44, 44, 44, 44,
44, 44, 8, 44, 44, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 44,
2, 44, 45, 45, 44, 5, 44, 6,
44, 44, 44, 44, 44, 44, 44, 8,
44, 44, 10, 11, 12, 13, 14, 15,
16, 17, 18, 44, 2, 44, 45, 45,
44, 5, 44, 6, 44, 44, 44, 44,
44, 44, 44, 52, 44, 44, 44, 44,
44, 44, 14, 15, 16, 17, 18, 44,
2, 44, 45, 45, 44, 5, 44, 6,
44, 44, 44, 44, 44, 44, 44, 44,
44, 44, 44, 44, 44, 44, 14, 15,
16, 17, 18, 44, 2, 44, 45, 45,
44, 5, 44, 6, 44, 44, 44, 44,
44, 44, 44, 44, 44, 44, 44, 44,
44, 44, 14, 15, 16, 44, 18, 44,
2, 44, 45, 45, 44, 5, 44, 6,
44, 44, 44, 44, 44, 44, 44, 44,
44, 44, 44, 44, 44, 44, 14, 44,
16, 44, 18, 44, 2, 44, 45, 45,
44, 5, 44, 6, 44, 44, 44, 44,
44, 44, 44, 44, 44, 44, 44, 44,
44, 44, 14, 15, 16, 17, 18, 52,
44, 2, 44, 45, 45, 44, 5, 44,
6, 44, 44, 44, 44, 44, 44, 44,
52, 44, 44, 10, 44, 12, 44, 14,
15, 16, 17, 18, 44, 2, 44, 45,
45, 44, 5, 44, 6, 44, 44, 44,
44, 44, 44, 44, 52, 44, 44, 10,
44, 44, 44, 14, 15, 16, 17, 18,
44, 2, 44, 45, 45, 44, 5, 44,
6, 44, 44, 44, 44, 44, 44, 44,
52, 44, 44, 10, 11, 12, 44, 14,
15, 16, 17, 18, 44, 2, 3, 45,
45, 44, 5, 44, 6, 44, 44, 44,
44, 44, 44, 44, 8, 44, 44, 10,
11, 12, 13, 14, 15, 16, 17, 18,
44, 22, 23, 24, 24, 21, 25, 21,
26, 21, 21, 21, 21, 21, 21, 21,
53, 21, 21, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 21, 22, 54,
24, 24, 21, 25, 21, 26, 21, 21,
21, 21, 21, 21, 21, 27, 21, 21,
28, 29, 30, 31, 32, 33, 34, 35,
36, 21, 1, 1, 2, 3, 45, 45,
44, 5, 44, 6, 1, 44, 44, 44,
44, 1, 44, 8, 44, 44, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19,
44, 1, 44, 1, 1, 55, 55, 55,
55, 55, 55, 55, 55, 1, 55, 55,
55, 55, 1, 55, 55, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 1, 55, 56, 55, 0
};
static const char _myanmar_syllable_machine_trans_targs[] = {
0, 1, 23, 33, 0, 24, 30, 45,
35, 48, 36, 41, 42, 43, 26, 38,
39, 40, 29, 44, 49, 0, 2, 12,
0, 3, 9, 13, 14, 19, 20, 21,
5, 16, 17, 18, 8, 22, 4, 6,
7, 10, 11, 15, 0, 0, 25, 27,
28, 31, 32, 34, 37, 46, 47, 0,
0
};
static const char _myanmar_syllable_machine_index_defaults[] = {
0, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 44,
44, 44, 44, 44, 44, 44, 44, 44,
44, 44, 44, 44, 44, 44, 44, 44,
44, 44, 44, 44, 44, 21, 21, 44,
55, 55, 0
};
static const char _myanmar_syllable_machine_trans_cond_spaces[] = {
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, 0
};
static const char _myanmar_syllable_machine_cond_targs[] = {
0, 1, 23, 33, 0, 24, 30, 45,
35, 48, 36, 41, 42, 43, 26, 38,
39, 40, 29, 44, 49, 0, 2, 12,
0, 3, 9, 13, 14, 19, 20, 21,
5, 16, 17, 18, 8, 22, 4, 6,
7, 10, 11, 15, 0, 0, 25, 27,
28, 31, 32, 34, 37, 46, 47, 0,
0, 0
};
static const char _myanmar_syllable_machine_cond_actions[] = {
3, 0, 0, 0, 4, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 5, 0, 0,
6, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 7, 8, 0, 0,
0, 0, 0, 0, 0, 0, 0, 9,
10, 0
static const char _myanmar_syllable_machine_trans_actions[] = {
3, 0, 0, 0, 4, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 5, 0, 0,
6, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 7, 8, 0, 0,
0, 0, 0, 0, 0, 0, 0, 9,
10
};
static const char _myanmar_syllable_machine_to_state_actions[] = {
1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0
1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0
};
static const char _myanmar_syllable_machine_from_state_actions[] = {
2, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0
};
static const char _myanmar_syllable_machine_eof_cond_spaces[] = {
-1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, 0
};
static const char _myanmar_syllable_machine_eof_cond_key_offs[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0
};
static const char _myanmar_syllable_machine_eof_cond_key_lens[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0
};
static const char _myanmar_syllable_machine_eof_cond_keys[] = {
0
};
static const char _myanmar_syllable_machine_eof_trans[] = {
0, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 45,
45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 22, 22, 45,
56, 56, 0
};
static const char _myanmar_syllable_machine_nfa_targs[] = {
2, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0
};
static const char _myanmar_syllable_machine_nfa_offsets[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0
};
static const char _myanmar_syllable_machine_nfa_push_actions[] = {
0, 0
};
static const char _myanmar_syllable_machine_nfa_pop_trans[] = {
0, 0
static const short _myanmar_syllable_machine_eof_trans[] = {
0, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 45,
45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 22, 22, 45,
56, 56
};
static const int myanmar_syllable_machine_start = 0;
@ -309,199 +286,136 @@ static const int myanmar_syllable_machine_error = -1;
static const int myanmar_syllable_machine_en_main = 0;
#line 36 "hb-ot-shape-complex-myanmar-machine.rl"
#line 94 "hb-ot-shape-complex-myanmar-machine.rl"
#define found_syllable(syllable_type) \
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial=1; \
} HB_STMT_END
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", ts, te, #syllable_type); \
for (unsigned int i = ts; i < te; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
syllable_serial++; \
if (unlikely (syllable_serial == 16)) syllable_serial = 1; \
} HB_STMT_END
static void
find_syllables (hb_buffer_t *buffer)
{
unsigned int p, pe, eof, ts, te, act HB_UNUSED;
int cs;
hb_glyph_info_t *info = buffer->info;
unsigned int p, pe, eof, ts, te, act HB_UNUSED;
int cs;
hb_glyph_info_t *info = buffer->info;
#line 313 "hb-ot-shape-complex-myanmar-machine.hh"
{
cs = (int)myanmar_syllable_machine_start;
ts = 0;
te = 0;
cs = myanmar_syllable_machine_start;
ts = 0;
te = 0;
act = 0;
}
p=0;
pe = eof = buffer->len;
unsigned int syllable_serial=1;
#line 114 "hb-ot-shape-complex-myanmar-machine.rl"
p = 0;
pe = eof = buffer->len;
unsigned int syllable_serial = 1;
#line 329 "hb-ot-shape-complex-myanmar-machine.hh"
{
int _cpc;
int _klen;const char * _cekeys;unsigned int _trans = 0;const unsigned char * _keys;const char * _inds; {
if ( p == pe )
goto _test_eof;
_resume: {
switch ( _myanmar_syllable_machine_from_state_actions[cs] ) {
case 2: {
{
#line 1 "NONE"
{ts = p;}}
break; }
}
_keys = ( _myanmar_syllable_machine_trans_keys + ((cs<<1)));
_inds = ( _myanmar_syllable_machine_indicies + (_myanmar_syllable_machine_index_offsets[cs]));
if ( (info[p].myanmar_category()) <= 32 && (info[p].myanmar_category()) >= 1 )
{
int _ic = (int)_myanmar_syllable_machine_char_class[(int)(info[p].myanmar_category()) - 1];
if ( _ic <= (int)(*( _keys+1)) && _ic >= (int)(*( _keys)) )
_trans = (unsigned int)(*( _inds + (int)( _ic - (int)(*( _keys)) ) ));
else
_trans = (unsigned int)_myanmar_syllable_machine_index_defaults[cs];
}
else {
_trans = (unsigned int)_myanmar_syllable_machine_index_defaults[cs];
}
goto _match_cond;
}
_match_cond: {
cs = (int)_myanmar_syllable_machine_cond_targs[_trans];
if ( _myanmar_syllable_machine_cond_actions[_trans] == 0 )
goto _again;
switch ( _myanmar_syllable_machine_cond_actions[_trans] ) {
case 6: {
{
#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{
#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
found_syllable (consonant_syllable); }}}
break; }
case 4: {
{
#line 87 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{
#line 87 "hb-ot-shape-complex-myanmar-machine.rl"
found_syllable (non_myanmar_cluster); }}}
break; }
case 10: {
{
#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{
#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
found_syllable (punctuation_cluster); }}}
break; }
case 8: {
{
#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{
#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
found_syllable (broken_cluster); }}}
break; }
case 3: {
{
#line 90 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{
#line 90 "hb-ot-shape-complex-myanmar-machine.rl"
found_syllable (non_myanmar_cluster); }}}
break; }
case 5: {
{
#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p = p - 1;{
#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
found_syllable (consonant_syllable); }}}
break; }
case 7: {
{
#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p = p - 1;{
#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
found_syllable (broken_cluster); }}}
break; }
case 9: {
{
#line 90 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p = p - 1;{
#line 90 "hb-ot-shape-complex-myanmar-machine.rl"
found_syllable (non_myanmar_cluster); }}}
break; }
}
}
_again: {
switch ( _myanmar_syllable_machine_to_state_actions[cs] ) {
case 1: {
{
#line 1 "NONE"
{ts = 0;}}
break; }
}
p += 1;
if ( p != pe )
goto _resume;
}
_test_eof: { {}
if ( p == eof )
{
if ( _myanmar_syllable_machine_eof_cond_spaces[cs] != -1 ) {
_cekeys = ( _myanmar_syllable_machine_eof_cond_keys + (_myanmar_syllable_machine_eof_cond_key_offs[cs]));
_klen = (int)_myanmar_syllable_machine_eof_cond_key_lens[cs];
_cpc = 0;
{
const char *_lower = _cekeys;
const char *_upper = _cekeys + _klen - 1;
const char *_mid;
while ( 1 ) {
if ( _upper < _lower )
break;
_mid = _lower + ((_upper-_lower) >> 1);
if ( _cpc < (int)(*( _mid)) )
_upper = _mid - 1;
else if ( _cpc > (int)(*( _mid)) )
_lower = _mid + 1;
else {
goto _ok;
}
}
cs = -1;
goto _out;
}
_ok: {}
}
if ( _myanmar_syllable_machine_eof_trans[cs] > 0 ) {
_trans = (unsigned int)_myanmar_syllable_machine_eof_trans[cs] - 1;
goto _match_cond;
}
}
}
_out: { {}
}
}
int _slen;
int _trans;
const unsigned char *_keys;
const char *_inds;
if ( p == pe )
goto _test_eof;
_resume:
switch ( _myanmar_syllable_machine_from_state_actions[cs] ) {
case 2:
#line 1 "NONE"
{ts = p;}
break;
#line 343 "hb-ot-shape-complex-myanmar-machine.hh"
}
_keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
_inds = _myanmar_syllable_machine_indicies + _myanmar_syllable_machine_index_offsets[cs];
_slen = _myanmar_syllable_machine_key_spans[cs];
_trans = _inds[ _slen > 0 && _keys[0] <=( info[p].myanmar_category()) &&
( info[p].myanmar_category()) <= _keys[1] ?
( info[p].myanmar_category()) - _keys[0] : _slen ];
_eof_trans:
cs = _myanmar_syllable_machine_trans_targs[_trans];
if ( _myanmar_syllable_machine_trans_actions[_trans] == 0 )
goto _again;
switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
case 6:
#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (consonant_syllable); }}
break;
case 4:
#line 87 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
break;
case 10:
#line 88 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (punctuation_cluster); }}
break;
case 8:
#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (broken_cluster); }}
break;
case 3:
#line 90 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
break;
case 5:
#line 86 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (consonant_syllable); }}
break;
case 7:
#line 89 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (broken_cluster); }}
break;
case 9:
#line 90 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (non_myanmar_cluster); }}
break;
#line 393 "hb-ot-shape-complex-myanmar-machine.hh"
}
_again:
switch ( _myanmar_syllable_machine_to_state_actions[cs] ) {
case 1:
#line 1 "NONE"
{ts = 0;}
break;
#line 402 "hb-ot-shape-complex-myanmar-machine.hh"
}
if ( ++p != pe )
goto _resume;
_test_eof: {}
if ( p == eof )
{
if ( _myanmar_syllable_machine_eof_trans[cs] > 0 ) {
_trans = _myanmar_syllable_machine_eof_trans[cs] - 1;
goto _eof_trans;
}
}
}
#line 122 "hb-ot-shape-complex-myanmar-machine.rl"
}
#undef found_syllable

View File

@ -218,7 +218,7 @@ do_thai_pua_shaping (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer,
hb_font_t *font)
{
#if defined(HB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK)
#ifdef HB_NO_OT_SHAPE_COMPLEX_THAI_FALLBACK
return;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -302,7 +302,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1A20 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1A30 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1A40 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1A50 */ B, B, B, B, B, MPre, MBlw, SUB, FAbv, FAbv, FAbv, SUB, SUB, SUB, SUB, O,
/* 1A50 */ B, B, B, B, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, SUB, SUB, SUB, O,
/* 1A60 */ H, VPst, VAbv, VPst, VPst, VAbv, VAbv, VAbv, VAbv, VBlw, VBlw, VAbv, VBlw, VPst, VPre, VPre,
/* 1A70 */ VPre, VPre, VPre, VAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VAbv, FM, FM, O, O, FBlw,
/* 1A80 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,

View File

@ -34,7 +34,7 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer,
hb_font_t *font HB_UNUSED)
{
#if defined(HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS)
#ifdef HB_NO_OT_SHAPE_COMPLEX_VOWEL_CONSTRAINTS
return;
#endif
if (buffer->flags & HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE)

View File

@ -166,7 +166,7 @@ _hb_ot_shape_fallback_mark_position_recategorize_marks (const hb_ot_shape_plan_t
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
#if defined(HB_NO_OT_SHAPE_FALLBACK)
#ifdef HB_NO_OT_SHAPE_FALLBACK
return;
#endif
@ -438,7 +438,7 @@ _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
bool adjust_offsets_when_zeroing)
{
#if defined(HB_NO_OT_SHAPE_FALLBACK)
#ifdef HB_NO_OT_SHAPE_FALLBACK
return;
#endif
@ -456,6 +456,7 @@ _hb_ot_shape_fallback_mark_position (const hb_ot_shape_plan_t *plan,
}
#ifndef HB_DISABLE_DEPRECATED
struct hb_ot_shape_fallback_kern_driver_t
{
hb_ot_shape_fallback_kern_driver_t (hb_font_t *font_,
@ -474,6 +475,7 @@ struct hb_ot_shape_fallback_kern_driver_t
hb_font_t *font;
hb_direction_t direction;
};
#endif
/* Performs font-assisted kerning. */
void
@ -481,10 +483,11 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
#if defined(HB_NO_OT_SHAPE_FALLBACK)
#ifdef HB_NO_OT_SHAPE_FALLBACK
return;
#endif
#ifndef HB_DISABLE_DEPRECATED
if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction) ?
!font->has_glyph_h_kerning_func () :
!font->has_glyph_v_kerning_func ())
@ -501,6 +504,7 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
if (reverse)
buffer->reverse ();
#endif
}

View File

@ -55,7 +55,8 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
const hb_feature_t *user_features,
unsigned int num_user_features);
static bool
#ifndef HB_NO_SHAPE_AAT
static inline bool
_hb_apply_morx (hb_face_t *face)
{
if (hb_options ().aat &&
@ -69,14 +70,17 @@ _hb_apply_morx (hb_face_t *face)
0, nullptr, nullptr)) &&
hb_aat_layout_has_substitution (face);
}
#endif
hb_ot_shape_planner_t::hb_ot_shape_planner_t (hb_face_t *face,
const hb_segment_properties_t *props) :
face (face),
props (*props),
map (face, props),
aat_map (face, props),
apply_morx (_hb_apply_morx (face))
aat_map (face, props)
#ifndef HB_NO_SHAPE_AAT
, apply_morx (_hb_apply_morx (face))
#endif
{
shaper = hb_ot_shape_complex_categorize (this);
@ -124,24 +128,36 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
* Decide who does substitutions. GSUB, morx, or fallback.
*/
#ifndef HB_NO_SHAPE_AAT
plan.apply_morx = apply_morx;
#endif
/*
* Decide who does positioning. GPOS, kerx, kern, or fallback.
*/
if (hb_options ().aat && hb_aat_layout_has_positioning (face))
if (0)
;
#ifndef HB_NO_SHAPE_AAT
else if (hb_options ().aat && hb_aat_layout_has_positioning (face))
plan.apply_kerx = true;
#endif
else if (!apply_morx && !disable_gpos && hb_ot_layout_has_positioning (face))
plan.apply_gpos = true;
#ifndef HB_NO_SHAPE_AAT
else if (hb_aat_layout_has_positioning (face))
plan.apply_kerx = true;
#endif
if (!plan.apply_kerx && !has_gpos_kern)
{
/* Apparently Apple applies kerx if GPOS kern was not applied. */
if (hb_aat_layout_has_positioning (face))
if (0)
;
#ifndef HB_NO_SHAPE_AAT
else if (hb_aat_layout_has_positioning (face))
plan.apply_kerx = true;
#endif
else if (hb_ot_layout_has_kerning (face))
plan.apply_kern = true;
}
@ -158,8 +174,10 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
plan.fallback_mark_positioning = plan.adjust_mark_positioning_when_zeroing &&
script_fallback_mark_positioning;
#ifndef HB_NO_SHAPE_AAT
/* Currently we always apply trak. */
plan.apply_trak = plan.requested_tracking && hb_aat_layout_has_tracking (face);
#endif
}
bool

View File

@ -80,10 +80,16 @@ struct hb_ot_shape_plan_t
bool adjust_mark_positioning_when_zeroing : 1;
bool apply_gpos : 1;
bool apply_kerx : 1;
bool apply_kern : 1;
#ifndef HB_NO_SHAPE_AAT
bool apply_kerx : 1;
bool apply_morx : 1;
bool apply_trak : 1;
#else
static constexpr bool apply_kerx = false;
static constexpr bool apply_morx = false;
static constexpr bool apply_trak = false;
#endif
void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const
{
@ -113,7 +119,11 @@ struct hb_ot_shape_planner_t
hb_segment_properties_t props;
hb_ot_map_builder_t map;
hb_aat_map_builder_t aat_map;
#ifndef HB_NO_SHAPE_AAT
bool apply_morx : 1;
#else
static constexpr bool apply_morx = false;
#endif
bool script_zero_marks : 1;
bool script_fallback_mark_positioning : 1;
const struct hb_ot_complex_shaper_t *shaper;

View File

@ -65,6 +65,8 @@ struct AxisValueFormat1
return_trace (likely (c->check_struct (this)));
}
hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
protected:
HBUINT16 format; /* Format identifier — set to 1. */
HBUINT16 axisIndex; /* Zero-base index into the axis record array
@ -88,6 +90,8 @@ struct AxisValueFormat2
return_trace (likely (c->check_struct (this)));
}
hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
protected:
HBUINT16 format; /* Format identifier — set to 2. */
HBUINT16 axisIndex; /* Zero-base index into the axis record array
@ -115,6 +119,8 @@ struct AxisValueFormat3
return_trace (likely (c->check_struct (this)));
}
hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
protected:
HBUINT16 format; /* Format identifier — set to 3. */
HBUINT16 axisIndex; /* Zero-base index into the axis record array
@ -157,6 +163,8 @@ struct AxisValueFormat4
return_trace (likely (c->check_struct (this)));
}
hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
protected:
HBUINT16 format; /* Format identifier — set to 4. */
HBUINT16 axisCount; /* The total number of axes contributing to
@ -191,6 +199,18 @@ struct AxisValue
}
}
hb_ot_name_id_t get_value_name_id () const
{
switch (u.format)
{
case 1: return u.format1.get_value_name_id ();
case 2: return u.format2.get_value_name_id ();
case 3: return u.format3.get_value_name_id ();
case 4: return u.format4.get_value_name_id ();
default: return HB_OT_NAME_ID_INVALID;
}
}
protected:
union
{
@ -212,6 +232,8 @@ struct StatAxisRecord
return_trace (likely (c->check_struct (this)));
}
hb_ot_name_id_t get_name_id () const { return nameID; }
protected:
Tag tag; /* A tag identifying the axis of design variation. */
NameID nameID; /* The name ID for entries in the 'name' table that
@ -231,17 +253,59 @@ struct STAT
{
TRACE_SANITIZE (this);
return_trace (likely (c->check_struct (this) &&
majorVersion == 1 &&
minorVersion > 0 &&
version.major == 1 &&
version.minor > 0 &&
designAxesOffset.sanitize (c, this, designAxisCount) &&
offsetToAxisValueOffsets.sanitize (c, this, axisValueCount, &(this+offsetToAxisValueOffsets))));
}
bool has_data () const { return version.to_int (); }
unsigned get_design_axis_count () const { return designAxisCount; }
hb_ot_name_id_t get_axis_record_name_id (unsigned axis_record_index) const
{
if (unlikely (axis_record_index >= designAxisCount)) return HB_OT_NAME_ID_INVALID;
const StatAxisRecord &axis_record = get_design_axes ()[axis_record_index];
return axis_record.get_name_id ();
}
unsigned get_axis_value_count () const { return axisValueCount; }
hb_ot_name_id_t get_axis_value_name_id (unsigned axis_value_index) const
{
if (unlikely (axis_value_index >= axisValueCount)) return HB_OT_NAME_ID_INVALID;
const AxisValue &axis_value = (this + get_axis_value_offsets ()[axis_value_index]);
return axis_value.get_value_name_id ();
}
void collect_name_ids (hb_set_t *nameids_to_retain) const
{
if (!has_data ()) return;
+ get_design_axes ()
| hb_map (&StatAxisRecord::get_name_id)
| hb_sink (nameids_to_retain)
;
+ get_axis_value_offsets ()
| hb_map (hb_add (this))
| hb_map (&AxisValue::get_value_name_id)
| hb_sink (nameids_to_retain)
;
}
protected:
HBUINT16 majorVersion; /* Major version number of the style attributes
* table set to 1. */
HBUINT16 minorVersion; /* Minor version number of the style attributes
* table set to 2. */
hb_array_t<const StatAxisRecord> const get_design_axes () const
{ return (this+designAxesOffset).as_array (designAxisCount); }
hb_array_t<const OffsetTo<AxisValue>> const get_axis_value_offsets () const
{ return (this+offsetToAxisValueOffsets).as_array (axisValueCount); }
protected:
FixedVersion<>version; /* Version of the stat table
* initially set to 0x00010002u */
HBUINT16 designAxisSize; /* The size in bytes of each axis record. */
HBUINT16 designAxisCount;/* The number of design axis records. In a
* font with an 'fvar' table, this value must be

View File

@ -113,6 +113,7 @@ hb_ot_new_tag_to_script (hb_tag_t tag)
return HB_SCRIPT_UNKNOWN;
}
#ifndef HB_DISABLE_DEPRECATED
void
hb_ot_tags_from_script (hb_script_t script,
hb_tag_t *script_tag_1,
@ -124,6 +125,7 @@ hb_ot_tags_from_script (hb_script_t script,
*script_tag_1 = count > 0 ? tags[0] : HB_OT_TAG_DEFAULT_SCRIPT;
*script_tag_2 = count > 1 ? tags[1] : HB_OT_TAG_DEFAULT_SCRIPT;
}
#endif
/*
* Complete list at:
@ -230,6 +232,7 @@ struct LangTag
/*{"??", {HB_TAG('Y','I','C',' ')}},*/ /* Yi Classic */
/*{"zh?", {HB_TAG('Z','H','P',' ')}},*/ /* Chinese Phonetic */
#ifndef HB_DISABLE_DEPRECATED
hb_tag_t
hb_ot_tag_from_language (hb_language_t language)
{
@ -238,6 +241,7 @@ hb_ot_tag_from_language (hb_language_t language)
hb_ot_tags_from_script_and_language (HB_SCRIPT_UNKNOWN, language, nullptr, nullptr, &count, tags);
return count > 0 ? tags[0] : HB_OT_TAG_DEFAULT_LANGUAGE;
}
#endif
static void
hb_ot_tags_from_language (const char *lang_str,

View File

@ -114,6 +114,7 @@ struct fvar
unsigned int get_axis_count () const { return axisCount; }
#ifndef HB_DISABLE_DEPRECATED
void get_axis_deprecated (unsigned int axis_index,
hb_ot_var_axis_t *info) const
{
@ -125,6 +126,7 @@ struct fvar
info->min_value = hb_min (info->default_value, axis.minValue / 65536.f);
info->max_value = hb_max (info->default_value, axis.maxValue / 65536.f);
}
#endif
void get_axis_info (unsigned int axis_index,
hb_ot_var_axis_info_t *info) const
@ -141,6 +143,7 @@ struct fvar
info->reserved = 0;
}
#ifndef HB_DISABLE_DEPRECATED
unsigned int get_axes_deprecated (unsigned int start_offset,
unsigned int *axes_count /* IN/OUT */,
hb_ot_var_axis_t *axes_array /* OUT */) const
@ -162,6 +165,7 @@ struct fvar
}
return axisCount;
}
#endif
unsigned int get_axis_infos (unsigned int start_offset,
unsigned int *axes_count /* IN/OUT */,
@ -185,6 +189,7 @@ struct fvar
return axisCount;
}
#ifndef HB_DISABLE_DEPRECATED
bool find_axis_deprecated (hb_tag_t tag,
unsigned int *axis_index,
hb_ot_var_axis_t *info) const
@ -203,6 +208,7 @@ struct fvar
*axis_index = HB_OT_VAR_NO_AXIS_INDEX;
return false;
}
#endif
bool find_axis_info (hb_tag_t tag,
hb_ot_var_axis_info_t *info) const
@ -253,8 +259,8 @@ struct fvar
}
unsigned int get_instance_coords (unsigned int instance_index,
unsigned int *coords_length, /* IN/OUT */
float *coords /* OUT */) const
unsigned int *coords_length, /* IN/OUT */
float *coords /* OUT */) const
{
const InstanceRecord *instance = get_instance (instance_index);
if (unlikely (!instance))
@ -274,6 +280,27 @@ struct fvar
return axisCount;
}
void collect_name_ids (hb_set_t *nameids) const
{
if (!has_data ()) return;
+ get_axes ()
| hb_map (&AxisRecord::axisNameID)
| hb_sink (nameids)
;
+ hb_range ((unsigned) instanceCount)
| hb_map ([this] (const unsigned _) { return get_instance_subfamily_name_id (_); })
| hb_sink (nameids)
;
+ hb_range ((unsigned) instanceCount)
| hb_map ([this] (const unsigned _) { return get_instance_postscript_name_id (_); })
| hb_sink (nameids)
;
}
protected:
hb_array_t<const AxisRecord> get_axes () const
{ return hb_array (&(this+firstAxis), axisCount); }

View File

@ -75,6 +75,7 @@ hb_ot_var_get_axis_count (hb_face_t *face)
return face->table.fvar->get_axis_count ();
}
#ifndef HB_DISABLE_DEPRECATED
/**
* hb_ot_var_get_axes:
*
@ -104,6 +105,7 @@ hb_ot_var_find_axis (hb_face_t *face,
{
return face->table.fvar->find_axis_deprecated (axis_tag, axis_index, axis_info);
}
#endif
/**
* hb_ot_var_get_axis_infos:

View File

@ -211,6 +211,8 @@ struct hb_sanitize_context_t :
this->start = this->end = nullptr;
}
unsigned get_edit_count () { return edit_count; }
bool check_range (const void *base,
unsigned int len) const
{

View File

@ -389,6 +389,7 @@ hb_set_symmetric_difference (hb_set_t *set,
set->symmetric_difference (other);
}
#ifndef HB_DISABLE_DEPRECATED
/**
* hb_set_invert:
* @set: a set.
@ -403,6 +404,7 @@ void
hb_set_invert (hb_set_t *set HB_UNUSED)
{
}
#endif
/**
* hb_set_get_population:

View File

@ -440,8 +440,8 @@ struct hb_set_t
return true;
}
template <class Op>
void process (const hb_set_t *other)
template <typename Op>
void process (const Op& op, const hb_set_t *other)
{
if (unlikely (!successful)) return;
@ -495,7 +495,7 @@ struct hb_set_t
b--;
count--;
page_map[count] = page_map[a];
Op::process (page_at (count).v, page_at (a).v, other->page_at (b).v);
page_at (count).v = op (page_at (a).v, other->page_at (b).v);
}
else if (page_map[a - 1].major > other->page_map[b - 1].major)
{
@ -541,19 +541,19 @@ struct hb_set_t
void union_ (const hb_set_t *other)
{
process<HbOpOr> (other);
process (hb_bitwise_or, other);
}
void intersect (const hb_set_t *other)
{
process<HbOpAnd> (other);
process (hb_bitwise_and, other);
}
void subtract (const hb_set_t *other)
{
process<HbOpMinus> (other);
process (hb_bitwise_sub, other);
}
void symmetric_difference (const hb_set_t *other)
{
process<HbOpXor> (other);
process (hb_bitwise_xor, other);
}
bool next (hb_codepoint_t *codepoint) const
{

View File

@ -32,6 +32,8 @@
#include "hb-subset-cff-common.hh"
#include "hb-cff1-interp-cs.hh"
#ifndef HB_NO_SUBSET_CFF
using namespace CFF;
struct remap_sid_t : remap_t
@ -394,8 +396,8 @@ struct cff1_cs_opset_subr_subset_t : cff1_cs_opset_t<cff1_cs_opset_subr_subset_t
struct cff1_subr_subsetter_t : subr_subsetter_t<cff1_subr_subsetter_t, CFF1Subrs, const OT::cff1::accelerator_subset_t, cff1_cs_interp_env_t, cff1_cs_opset_subr_subset_t, OpCode_endchar>
{
cff1_subr_subsetter_t (const OT::cff1::accelerator_subset_t &acc, const hb_subset_plan_t *plan)
: subr_subsetter_t (acc, plan) {}
cff1_subr_subsetter_t (const OT::cff1::accelerator_subset_t &acc_, const hb_subset_plan_t *plan_)
: subr_subsetter_t (acc_, plan_) {}
static void finalize_parsed_str (cff1_cs_interp_env_t &env, subr_subset_param_t& param, parsed_cs_str_t &charstring)
{
@ -1064,7 +1066,7 @@ static inline bool _write_cff1 (const cff_subset_plan &plan,
return true;
}
static bool
static inline bool
_hb_subset_cff1 (const OT::cff1::accelerator_subset_t &acc,
const char *data,
hb_subset_plan_t *plan,
@ -1118,3 +1120,5 @@ hb_subset_cff1 (hb_subset_plan_t *plan,
return result;
}
#endif

View File

@ -32,6 +32,8 @@
#include "hb-subset-cff-common.hh"
#include "hb-cff2-interp-cs.hh"
#ifndef HB_NO_SUBSET_CFF
using namespace CFF;
struct cff2_sub_table_offsets_t : cff_sub_table_offsets_t
@ -225,8 +227,8 @@ struct cff2_cs_opset_subr_subset_t : cff2_cs_opset_t<cff2_cs_opset_subr_subset_t
struct cff2_subr_subsetter_t : subr_subsetter_t<cff2_subr_subsetter_t, CFF2Subrs, const OT::cff2::accelerator_subset_t, cff2_cs_interp_env_t, cff2_cs_opset_subr_subset_t>
{
cff2_subr_subsetter_t (const OT::cff2::accelerator_subset_t &acc, const hb_subset_plan_t *plan)
: subr_subsetter_t (acc, plan) {}
cff2_subr_subsetter_t (const OT::cff2::accelerator_subset_t &acc_, const hb_subset_plan_t *plan_)
: subr_subsetter_t (acc_, plan_) {}
static void finalize_parsed_str (cff2_cs_interp_env_t &env, subr_subset_param_t& param, parsed_cs_str_t &charstring)
{
@ -571,7 +573,7 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan,
return true;
}
static bool
static inline bool
_hb_subset_cff2 (const OT::cff2::accelerator_subset_t &acc,
const char *data,
hb_subset_plan_t *plan,
@ -626,3 +628,5 @@ hb_subset_cff2 (hb_subset_plan_t *plan,
return result;
}
#endif

View File

@ -31,8 +31,10 @@
#include "hb-ot-cmap-table.hh"
#include "hb-ot-glyf-table.hh"
#include "hb-ot-cff1-table.hh"
#include "hb-ot-var-fvar-table.hh"
#include "hb-ot-stat-table.hh"
static void
static inline void
_add_gid_and_children (const OT::glyf::accelerator_t &glyf,
hb_codepoint_t gid,
hb_set_t *gids_to_retain)
@ -53,7 +55,8 @@ _add_gid_and_children (const OT::glyf::accelerator_t &glyf,
}
}
static void
#ifndef HB_NO_SUBSET_CFF
static inline void
_add_cff_seac_components (const OT::cff1::accelerator_t &cff,
hb_codepoint_t gid,
hb_set_t *gids_to_retain)
@ -65,8 +68,10 @@ _add_cff_seac_components (const OT::cff1::accelerator_t &cff,
hb_set_add (gids_to_retain, accent_gid);
}
}
#endif
static void
#ifndef HB_NO_SUBSET_LAYOUT
static inline void
_gsub_closure (hb_face_t *face, hb_set_t *gids_to_retain)
{
hb_set_t lookup_indices;
@ -80,8 +85,9 @@ _gsub_closure (hb_face_t *face, hb_set_t *gids_to_retain)
&lookup_indices,
gids_to_retain);
}
#endif
static void
static inline void
_remove_invalid_gids (hb_set_t *glyphs,
unsigned int num_glyphs)
{
@ -126,9 +132,11 @@ _populate_gids_to_retain (hb_face_t *face,
initial_gids_to_retain->add (gid);
}
#ifndef HB_NO_SUBSET_LAYOUT
if (close_over_gsub)
// Add all glyphs needed for GSUB substitutions.
_gsub_closure (face, initial_gids_to_retain);
#endif
// Populate a full set of glyphs to retain by adding all referenced
// composite glyphs.
@ -137,14 +145,15 @@ _populate_gids_to_retain (hb_face_t *face,
while (initial_gids_to_retain->next (&gid))
{
_add_gid_and_children (glyf, gid, all_gids_to_retain);
#ifndef HB_NO_SUBSET_CFF
if (cff.is_valid ())
_add_cff_seac_components (cff, gid, all_gids_to_retain);
#endif
}
hb_set_destroy (initial_gids_to_retain);
_remove_invalid_gids (all_gids_to_retain, face->get_num_glyphs ());
cff.fini ();
glyf.fini ();
cmap.fini ();
@ -168,15 +177,17 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face,
*num_glyphs = reverse_glyph_map->get_population ();
} else {
+ hb_iter (all_gids_to_retain)
| hb_map ([=] (hb_codepoint_t _) {
| hb_map ([] (hb_codepoint_t _) {
return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (_, _);
})
| hb_sink (reverse_glyph_map);
| hb_sink (reverse_glyph_map)
;
// TODO(grieger): Should we discard glyphs past the max glyph to keep?
// *num_glyphs = + hb_iter (all_gids_to_retain) | hb_reduce (hb_max, 0);
*num_glyphs = face->get_num_glyphs ();
unsigned max_glyph =
+ hb_iter (all_gids_to_retain)
| hb_reduce (hb_max, 0)
;
*num_glyphs = max_glyph + 1;
}
+ reverse_glyph_map->iter ()
@ -185,6 +196,29 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face,
;
}
static void
_nameid_closure (hb_face_t *face,
hb_set_t *nameids)
{
hb_tag_t table_tags[32];
unsigned count = ARRAY_LENGTH (table_tags);
hb_face_get_table_tags (face, 0, &count, table_tags);
for (unsigned int i = 0; i < count; i++)
{
hb_tag_t tag = table_tags[i];
switch (tag) {
case HB_OT_TAG_STAT:
face->table.STAT->collect_name_ids (nameids);
break;
case HB_OT_TAG_fvar:
face->table.fvar->collect_name_ids (nameids);
break;
default:
break;
}
}
}
/**
* hb_subset_plan_create:
* Computes a plan for subsetting the supplied face according
@ -210,6 +244,7 @@ hb_subset_plan_create (hb_face_t *face,
/* TODO Clean this up... */
if (hb_set_is_empty (plan->name_ids))
hb_set_add_range (plan->name_ids, 0, 0x7FFF);
_nameid_closure (face, plan->name_ids);
plan->source = hb_face_reference (face);
plan->dest = hb_face_builder_create ();
plan->codepoint_to_glyph = hb_map_create ();

View File

@ -195,6 +195,8 @@ _subset_table (hb_subset_plan_t *plan,
case HB_OT_TAG_post:
result = _subset<const OT::post> (plan);
break;
#ifndef HB_NO_SUBSET_CFF
case HB_OT_TAG_cff1:
result = _subset<const OT::cff1> (plan);
break;
@ -204,8 +206,9 @@ _subset_table (hb_subset_plan_t *plan,
case HB_OT_TAG_VORG:
result = _subset<const OT::VORG> (plan);
break;
#endif
#if !defined(HB_NO_SUBSET_LAYOUT)
#ifndef HB_NO_SUBSET_LAYOUT
case HB_OT_TAG_GDEF:
result = _subset2<const OT::GDEF> (plan);
break;
@ -246,7 +249,7 @@ _should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag)
case HB_OT_TAG_GDEF:
case HB_OT_TAG_GPOS:
case HB_OT_TAG_GSUB:
#if defined(HB_NO_SUBSET_LAYOUT)
#ifdef HB_NO_SUBSET_LAYOUT
return true;
#endif
return plan->drop_layout;

View File

@ -163,7 +163,8 @@ static int hangul_pair_decompose(uint32_t code, uint32_t *a, uint32_t *b)
static int hangul_pair_compose(uint32_t *code, uint32_t a, uint32_t b)
{
if (a >= SBASE && a < (SBASE + SCOUNT) && b >= TBASE && b < (TBASE + TCOUNT)) {
if (a >= SBASE && a < (SBASE + SCOUNT) && b > TBASE && b < (TBASE + TCOUNT) &&
!((a - SBASE) % TCOUNT)) {
/* LV,T */
*code = a + (b - TBASE);
return 3;

View File

@ -60,6 +60,7 @@ hb_unicode_combining_class_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
return HB_UNICODE_COMBINING_CLASS_NOT_REORDERED;
}
#ifndef HB_DISABLE_DEPRECATED
static unsigned int
hb_unicode_eastasian_width_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
hb_codepoint_t unicode HB_UNUSED,
@ -67,6 +68,7 @@ hb_unicode_eastasian_width_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
{
return 1;
}
#endif
static hb_unicode_general_category_t
hb_unicode_general_category_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
@ -113,6 +115,7 @@ hb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
}
#ifndef HB_DISABLE_DEPRECATED
static unsigned int
hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
hb_codepoint_t u HB_UNUSED,
@ -121,6 +124,7 @@ hb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED
{
return 0;
}
#endif
extern "C" hb_unicode_funcs_t *hb_glib_get_unicode_funcs ();
@ -425,6 +429,7 @@ hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
return ufuncs->decompose (ab, a, b);
}
#ifndef HB_DISABLE_DEPRECATED
/**
* hb_unicode_decompose_compatibility:
* @ufuncs: Unicode functions.
@ -445,6 +450,7 @@ hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
{
return ufuncs->decompose_compatibility (u, decomposed);
}
#endif
/* See hb-unicode.hh for details. */

View File

@ -42,19 +42,19 @@ extern HB_INTERNAL const uint8_t _hb_modified_combining_class[256];
#define HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS \
HB_UNICODE_FUNC_IMPLEMENT (combining_class) \
HB_UNICODE_FUNC_IMPLEMENT (eastasian_width) \
HB_IF_NOT_DEPRECATED (HB_UNICODE_FUNC_IMPLEMENT (eastasian_width)) \
HB_UNICODE_FUNC_IMPLEMENT (general_category) \
HB_UNICODE_FUNC_IMPLEMENT (mirroring) \
HB_UNICODE_FUNC_IMPLEMENT (script) \
HB_UNICODE_FUNC_IMPLEMENT (compose) \
HB_UNICODE_FUNC_IMPLEMENT (decompose) \
HB_UNICODE_FUNC_IMPLEMENT (decompose_compatibility) \
HB_IF_NOT_DEPRECATED (HB_UNICODE_FUNC_IMPLEMENT (decompose_compatibility)) \
/* ^--- Add new callbacks here */
/* Simple callbacks are those taking a hb_codepoint_t and returning a hb_codepoint_t */
#define HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE \
HB_UNICODE_FUNC_IMPLEMENT (hb_unicode_combining_class_t, combining_class) \
HB_UNICODE_FUNC_IMPLEMENT (unsigned int, eastasian_width) \
HB_IF_NOT_DEPRECATED (HB_UNICODE_FUNC_IMPLEMENT (unsigned int, eastasian_width)) \
HB_UNICODE_FUNC_IMPLEMENT (hb_unicode_general_category_t, general_category) \
HB_UNICODE_FUNC_IMPLEMENT (hb_codepoint_t, mirroring) \
HB_UNICODE_FUNC_IMPLEMENT (hb_script_t, script) \
@ -89,7 +89,11 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
unsigned int decompose_compatibility (hb_codepoint_t u,
hb_codepoint_t *decomposed)
{
#ifdef HB_DISABLE_DEPRECATED
unsigned int ret = 0;
#else
unsigned int ret = func.decompose_compatibility (this, u, decomposed, user_data.decompose_compatibility);
#endif
if (ret == 1 && u == decomposed[0]) {
decomposed[0] = 0;
return 0;

View File

@ -698,7 +698,7 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan,
{
active_feature_t *feature = active_features.find (&event->feature);
if (feature)
active_features.remove (feature - active_features.arrayZ ());
active_features.remove (feature - active_features.arrayZ);
}
}
@ -728,12 +728,12 @@ retry:
#define ALLOCATE_ARRAY(Type, name, len) \
Type *name = (Type *) scratch; \
{ \
do { \
unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
assert (_consumed <= scratch_size); \
scratch += _consumed; \
scratch_size -= _consumed; \
}
} while (0)
#define utf16_index() var1.u32
@ -889,8 +889,8 @@ retry:
&items[i].a,
script_tags[i],
language_tag,
range_char_counts.arrayZ (),
range_properties.arrayZ (),
range_char_counts.arrayZ,
range_properties.arrayZ,
range_properties.length,
pchars + chars_offset,
item_chars_len,
@ -930,8 +930,8 @@ retry:
&items[i].a,
script_tags[i],
language_tag,
range_char_counts.arrayZ (),
range_properties.arrayZ (),
range_char_counts.arrayZ,
range_properties.arrayZ,
range_properties.length,
pchars + chars_offset,
log_clusters + chars_offset,

View File

@ -49,35 +49,34 @@ struct hb_vector_t
{
allocated = o.allocated;
length = o.length;
arrayZ_ = o.arrayZ_;
arrayZ = o.arrayZ;
o.init ();
}
~hb_vector_t () { fini (); }
unsigned int length;
private:
int allocated; /* == -1 means allocation failed. */
Type *arrayZ_;
public:
unsigned int length;
public:
Type *arrayZ;
void init ()
{
allocated = length = 0;
arrayZ_ = nullptr;
arrayZ = nullptr;
}
void fini ()
{
if (arrayZ_)
free (arrayZ_);
free (arrayZ);
init ();
}
void fini_deep ()
{
Type *array = arrayZ();
unsigned int count = length;
for (unsigned int i = 0; i < count; i++)
array[i].fini ();
arrayZ[i].fini ();
fini ();
}
@ -95,33 +94,31 @@ struct hb_vector_t
fini ();
allocated = o.allocated;
length = o.length;
arrayZ_ = o.arrayZ_;
arrayZ = o.arrayZ;
o.init ();
return *this;
}
hb_bytes_t as_bytes () const
{ return hb_bytes_t ((const char *) arrayZ(), length * item_size); }
{ return hb_bytes_t ((const char *) arrayZ, length * item_size); }
bool operator == (const hb_vector_t &o) const { return as_array () == o.as_array (); }
bool operator != (const hb_vector_t &o) const { return !(*this == o); }
uint32_t hash () const { return as_array ().hash (); }
const Type * arrayZ () const { return arrayZ_; }
Type * arrayZ () { return arrayZ_; }
Type& operator [] (int i_)
{
unsigned int i = (unsigned int) i_;
if (unlikely (i >= length))
return Crap (Type);
return arrayZ()[i];
return arrayZ[i];
}
const Type& operator [] (int i_) const
{
unsigned int i = (unsigned int) i_;
if (unlikely (i >= length))
return Null(Type);
return arrayZ()[i];
return arrayZ[i];
}
Type& tail () { return (*this)[length - 1]; }
@ -134,8 +131,8 @@ struct hb_vector_t
template <typename T>
hb_vector_t& operator << (T&& v) { push (hb_forward<T> (v)); return *this; }
hb_array_t< Type> as_array () { return hb_array (arrayZ(), length); }
hb_array_t<const Type> as_array () const { return hb_array (arrayZ(), length); }
hb_array_t< Type> as_array () { return hb_array (arrayZ, length); }
hb_array_t<const Type> as_array () const { return hb_array (arrayZ, length); }
/* Iterator. */
typedef hb_array_t<const Type> iter_t;
@ -155,21 +152,21 @@ struct hb_vector_t
{ return as_array ().sub_array (start_offset, count);}
hb_sorted_array_t<Type> as_sorted_array ()
{ return hb_sorted_array (arrayZ(), length); }
{ return hb_sorted_array (arrayZ, length); }
hb_sorted_array_t<const Type> as_sorted_array () const
{ return hb_sorted_array (arrayZ(), length); }
{ return hb_sorted_array (arrayZ, length); }
template <typename T> explicit operator T * () { return arrayZ(); }
template <typename T> explicit operator const T * () const { return arrayZ(); }
template <typename T> explicit operator T * () { return arrayZ; }
template <typename T> explicit operator const T * () const { return arrayZ; }
Type * operator + (unsigned int i) { return arrayZ() + i; }
const Type * operator + (unsigned int i) const { return arrayZ() + i; }
Type * operator + (unsigned int i) { return arrayZ + i; }
const Type * operator + (unsigned int i) const { return arrayZ + i; }
Type *push ()
{
if (unlikely (!resize (length + 1)))
return &Crap(Type);
return &arrayZ()[length - 1];
return &arrayZ[length - 1];
}
template <typename T>
Type *push (T&& v)
@ -202,7 +199,7 @@ struct hb_vector_t
(new_allocated < (unsigned) allocated) ||
hb_unsigned_mul_overflows (new_allocated, sizeof (Type));
if (likely (!overflows))
new_array = (Type *) realloc (arrayZ_, new_allocated * sizeof (Type));
new_array = (Type *) realloc (arrayZ, new_allocated * sizeof (Type));
if (unlikely (!new_array))
{
@ -210,7 +207,7 @@ struct hb_vector_t
return false;
}
arrayZ_ = new_array;
arrayZ = new_array;
allocated = new_allocated;
return true;
@ -223,7 +220,7 @@ struct hb_vector_t
return false;
if (size > length)
memset (arrayZ() + length, 0, (size - length) * sizeof (*arrayZ()));
memset (arrayZ + length, 0, (size - length) * sizeof (*arrayZ));
length = size;
return true;
@ -232,16 +229,15 @@ struct hb_vector_t
Type pop ()
{
if (!length) return Null(Type);
return hb_move (arrayZ()[--length]); /* Does this move actually work? */
return hb_move (arrayZ[--length]); /* Does this move actually work? */
}
void remove (unsigned int i)
{
if (unlikely (i >= length))
return;
Type *array = arrayZ();
memmove (static_cast<void *> (&array[i]),
static_cast<void *> (&array[i + 1]),
memmove (static_cast<void *> (&arrayZ[i]),
static_cast<void *> (&arrayZ[i + 1]),
(length - i - 1) * sizeof (Type));
length--;
}
@ -256,19 +252,17 @@ struct hb_vector_t
template <typename T>
Type *find (T v)
{
Type *array = arrayZ();
for (unsigned int i = 0; i < length; i++)
if (array[i] == v)
return &array[i];
if (arrayZ[i] == v)
return &arrayZ[i];
return nullptr;
}
template <typename T>
const Type *find (T v) const
{
const Type *array = arrayZ();
for (unsigned int i = 0; i < length; i++)
if (array[i] == v)
return &array[i];
if (arrayZ[i] == v)
return &arrayZ[i];
return nullptr;
}
@ -288,8 +282,8 @@ struct hb_vector_t
template <typename Type>
struct hb_sorted_vector_t : hb_vector_t<Type>
{
hb_sorted_array_t< Type> as_array () { return hb_sorted_array (this->arrayZ(), this->length); }
hb_sorted_array_t<const Type> as_array () const { return hb_sorted_array (this->arrayZ(), this->length); }
hb_sorted_array_t< Type> as_array () { return hb_sorted_array (this->arrayZ, this->length); }
hb_sorted_array_t<const Type> as_array () const { return hb_sorted_array (this->arrayZ, this->length); }
/* Iterator. */
typedef hb_sorted_array_t<const Type> const_iter_t;

View File

@ -26,12 +26,12 @@
#include "hb.hh"
#if defined(HB_ATOMIC_INT_NIL)
#ifdef HB_ATOMIC_INT_NIL
#error "Could not find any system to define atomic_int macros, library WILL NOT be thread-safe"
#error "Check hb-atomic.hh for possible resolutions."
#endif
#if defined(HB_MUTEX_IMPL_NIL)
#ifdef HB_MUTEX_IMPL_NIL
#error "Could not find any system to define mutex macros, library WILL NOT be thread-safe"
#error "Check hb-mutex.hh for possible resolutions."
#endif

View File

@ -29,8 +29,9 @@
#ifndef HB_HH
#define HB_HH
#ifndef HB_NO_PRAGMA_GCC_DIAGNOSTIC
#if defined(_MSC_VER)
#ifdef _MSC_VER
#pragma warning( disable: 4068 ) /* Unknown pragma */
#endif
#if defined(__GNUC__) || defined(__clang__)
@ -66,6 +67,7 @@
#pragma GCC diagnostic error "-Wcast-function-type"
#pragma GCC diagnostic error "-Wdelete-non-virtual-dtor"
#pragma GCC diagnostic error "-Wdouble-promotion"
#pragma GCC diagnostic error "-Wextra-semi-stmt"
#pragma GCC diagnostic error "-Wformat-security"
#pragma GCC diagnostic error "-Wimplicit-function-declaration"
#pragma GCC diagnostic error "-Winit-self"
@ -129,9 +131,9 @@
#endif
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "hb-config.hh"
/*
* Following added based on what AC_USE_SYSTEM_EXTENSIONS adds to
@ -203,7 +205,7 @@ extern "C" void hb_free_impl(void *ptr);
#define realloc hb_realloc_impl
#define free hb_free_impl
#if defined(hb_memalign_impl)
#ifdef hb_memalign_impl
extern "C" int hb_memalign_impl(void **memptr, size_t alignment, size_t size);
#define posix_memalign hb_memalign_impl
#else
@ -315,7 +317,7 @@ extern "C" int hb_memalign_impl(void **memptr, size_t alignment, size_t size);
# define HB_FALLTHROUGH /* FALLTHROUGH */
#endif
#if defined(__clang__)
#ifdef __clang__
/* Disable certain sanitizer errors. */
/* https://github.com/harfbuzz/harfbuzz/issues/1247 */
#define HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW __attribute__((no_sanitize("signed-integer-overflow")))
@ -445,12 +447,12 @@ static_assert ((sizeof (hb_var_int_t) == 4), "");
*
* https://bugs.chromium.org/p/chromium/issues/detail?id=860184
*/
#if !defined(HB_VECTOR_SIZE)
#ifndef HB_VECTOR_SIZE
# define HB_VECTOR_SIZE 0
#endif
/* The `vector_size' attribute was introduced in gcc 3.1. */
#if !defined(HB_VECTOR_SIZE)
#ifndef HB_VECTOR_SIZE
# if defined( __GNUC__ ) && ( __GNUC__ >= 4 )
# define HB_VECTOR_SIZE 128
# else
@ -466,16 +468,6 @@ typedef uint64_t hb_vector_size_impl_t;
#endif
/* HB_NDEBUG disables some sanity checks that are very safe to disable and
* should be disabled in production systems. If NDEBUG is defined, enable
* HB_NDEBUG; but if it's desirable that normal assert()s (which are very
* light-weight) to be enabled, then HB_DEBUG can be defined to disable
* the costlier checks. */
#ifdef NDEBUG
#define HB_NDEBUG 1
#endif
/* Flags */
/* Enable bitwise ops on enums marked as flags_t */

View File

@ -62,19 +62,30 @@ main (int argc, char **argv)
A a;
hb_invoke (&A::a, a);
assert (1 == hb_min (3, 8, 1, 2));
assert (8 == hb_max (3, 8, 1, 2));
assert (1 == hb_min (8, 1));
assert (8 == hb_max (8, 1));
int x = 1, y = 2;
hb_min (x, 3);
hb_min (3, x, 4);
hb_min (3, x, 4 + 3);
hb_min (3, x);
hb_min (x, 4 + 3);
int &z = hb_min (x, y);
z = 3;
assert (x == 3);
hb_pair_t<const int*, int> xp = hb_pair_t<int *, long> (nullptr, 0);
xp = hb_pair_t<int *, double> (nullptr, 1);
xp = hb_pair_t<const int*, int> (nullptr, 1);
assert (3 == hb_partial (hb_min, 3) (4));
assert (3 == hb_partial<1> (hb_min, 4) (3));
auto M0 = hb_partial<2> (hb_max, 0);
assert (M0 (-2) == 0);
assert (M0 (+2) == 2);
assert (hb_add (2) (5) == 7);
assert (hb_add (5) (2) == 7);
return 0;
}

View File

@ -82,10 +82,8 @@ test_iterator_non_default_constructable (Iter it)
(void) _;
it += it.len ();
if (0)
it = it + 10;
if (0)
it = 10 + it;
it = it + 10;
it = 10 + it;
assert (*it == it[0]);
@ -205,8 +203,8 @@ main (int argc, char **argv)
;
+ hb_iter (src)
| hb_map ([&] (int i) -> int { return 1; })
| hb_reduce ([&] (int acc, int value) -> int { return acc; }, 2)
| hb_map ([] (int i) { return 1; })
| hb_reduce ([=] (int acc, int value) { return acc; }, 2)
;
using map_pair_t = hb_item_type<hb_map_t>;
@ -253,8 +251,8 @@ main (int argc, char **argv)
unsigned int temp3 = 0;
+ hb_iter(src)
| hb_map([&] (int i) -> int { return ++temp3; })
| hb_reduce([&] (float acc, int value) -> float { return acc + value; }, 0)
| hb_map([&] (int i) { return ++temp3; })
| hb_reduce([&] (float acc, int value) { return acc + value; }, 0)
;
hb_map_destroy (result);

View File

@ -27,11 +27,11 @@
#include "hb.hh"
#include "hb-meta.hh"
#include <type_traits>
int
main (int argc, char **argv)
{
static_assert (hb_is_convertible (void, void), "");
static_assert (hb_is_convertible (void, const void), "");
static_assert (hb_is_convertible (const void, void), "");
@ -58,6 +58,7 @@ main (int argc, char **argv)
static_assert (hb_is_convertible (const int&, const int), "");
struct X {};
struct Y : X {};
static_assert (hb_is_convertible (const X &, const X), "");
static_assert (hb_is_convertible (X &, const X), "");
@ -78,5 +79,50 @@ main (int argc, char **argv)
static_assert (hb_is_convertible (int *, void *), "");
static_assert (!hb_is_convertible (void *, int *), "");
static_assert (hb_is_base_of (void, void), "");
static_assert (hb_is_base_of (void, int), "");
static_assert (!hb_is_base_of (int, void), "");
static_assert (hb_is_base_of (int, int), "");
static_assert (hb_is_base_of (const int, int), "");
static_assert (hb_is_base_of (int, const int), "");
static_assert (hb_is_base_of (X, X), "");
static_assert (hb_is_base_of (X, Y), "");
static_assert (hb_is_base_of (const X, Y), "");
static_assert (hb_is_base_of (X, const Y), "");
static_assert (!hb_is_base_of (Y, X), "");
static_assert (hb_is_constructible (int), "");
static_assert (hb_is_constructible (int, int), "");
static_assert (hb_is_constructible (int, char), "");
static_assert (hb_is_constructible (int, long), "");
static_assert (!hb_is_constructible (int, X), "");
static_assert (!hb_is_constructible (int, int, int), "");
static_assert (hb_is_constructible (X), "");
static_assert (!hb_is_constructible (X, int), "");
static_assert (hb_is_constructible (X, X), "");
static_assert (!hb_is_constructible (X, X, X), "");
static_assert (hb_is_constructible (X, Y), "");
static_assert (!hb_is_constructible (Y, X), "");
static_assert (hb_is_trivially_default_constructible (X), "");
static_assert (hb_is_trivially_default_constructible (Y), "");
static_assert (hb_is_trivially_copy_constructible (X), "");
static_assert (hb_is_trivially_copy_constructible (Y), "");
static_assert (hb_is_trivially_move_constructible (X), "");
static_assert (hb_is_trivially_move_constructible (Y), "");
static_assert (hb_is_trivially_destructible (Y), "");
static_assert (hb_is_trivially_copyable (int), "");
static_assert (hb_is_trivially_copyable (X), "");
static_assert (hb_is_trivially_copyable (Y), "");
static_assert (hb_is_trivial (int), "");
static_assert (hb_is_trivial (X), "");
static_assert (hb_is_trivial (Y), "");
/* TODO Add more meaningful tests. */
return 0;
}

Binary file not shown.

View File

@ -146,9 +146,6 @@ _test_font_nil_funcs (hb_font_t *font)
glyph = 3;
g_assert (!hb_font_get_glyph (font, 17, 2, &glyph));
g_assert_cmpint (glyph, ==, 0);
x = hb_font_get_glyph_h_kerning (font, 17, 19);
g_assert_cmpint (x, ==, 0);
}
static void

View File

@ -67,17 +67,6 @@ glyph_func (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED,
return FALSE;
}
static hb_position_t
glyph_h_kerning_func (hb_font_t *font HB_UNUSED, void *font_data HB_UNUSED,
hb_codepoint_t left, hb_codepoint_t right,
void *user_data HB_UNUSED)
{
if (left == 1 && right == 2)
return -2;
return 0;
}
static const char TesT[] = "TesT";
static void
@ -102,7 +91,6 @@ test_shape (void)
ffuncs = hb_font_funcs_create ();
hb_font_funcs_set_glyph_h_advance_func (ffuncs, glyph_h_advance_func, NULL, NULL);
hb_font_funcs_set_nominal_glyph_func (ffuncs, glyph_func, malloc (10), free);
hb_font_funcs_set_glyph_h_kerning_func (ffuncs, glyph_h_kerning_func, NULL, NULL);
hb_font_set_funcs (font, ffuncs, NULL, NULL);
hb_font_funcs_destroy (ffuncs);
@ -118,8 +106,8 @@ test_shape (void)
{
const hb_codepoint_t output_glyphs[] = {1, 2, 3, 1};
const hb_position_t output_x_advances[] = {9, 5, 5, 10};
const hb_position_t output_x_offsets[] = {0, -1, 0, 0};
const hb_position_t output_x_advances[] = {10, 6, 5, 10};
const hb_position_t output_x_offsets[] = {0, 0, 0, 0};
unsigned int i;
g_assert_cmpint (len, ==, 4);
for (i = 0; i < len; i++) {

View File

@ -305,6 +305,30 @@ test_subset_glyf_retain_gids (void)
hb_face_destroy (face_ac);
}
static void
test_subset_glyf_retain_gids_truncates (void)
{
hb_face_t *face_abc = hb_test_open_font_file ("fonts/Roboto-Regular.abc.ttf");
hb_face_t *face_a = hb_test_open_font_file ("fonts/Roboto-Regular.a.retaingids.ttf");
hb_set_t *codepoints = hb_set_create();
hb_face_t *face_abc_subset;
hb_set_add (codepoints, 97);
hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
hb_subset_input_set_retain_gids (input, true);
face_abc_subset = hb_subset_test_create_subset (face_abc, input);
hb_set_destroy (codepoints);
hb_subset_test_check (face_a, face_abc_subset, HB_TAG ('g','l','y','f'));
hb_subset_test_check (face_a, face_abc_subset, HB_TAG ('l','o','c', 'a'));
check_maxp_num_glyphs(face_abc_subset, 2, true);
hb_face_destroy (face_abc_subset);
hb_face_destroy (face_abc);
hb_face_destroy (face_a);
}
// TODO(grieger): test for long loca generation.
int
@ -322,6 +346,7 @@ main (int argc, char **argv)
hb_test_add (test_subset_glyf_with_gsub);
hb_test_add (test_subset_glyf_without_gsub);
hb_test_add (test_subset_glyf_retain_gids);
hb_test_add (test_subset_glyf_retain_gids_truncates);
return hb_test_run();
}

View File

@ -755,6 +755,10 @@ test_unicode_normalization (gconstpointer user_data)
g_assert (hb_unicode_compose (uf, 0xCE20, 0x11B8, &ab) && ab == 0xCE31);
g_assert (hb_unicode_compose (uf, 0x110E, 0x1173, &ab) && ab == 0xCE20);
g_assert (!hb_unicode_compose (uf, 0xAC00, 0x11A7, &ab));
g_assert (hb_unicode_compose (uf, 0xAC00, 0x11A8, &ab) && ab == 0xAC01);
g_assert (!hb_unicode_compose (uf, 0xAC01, 0x11A8, &ab));
/* Test decompose() */

View File

@ -4,8 +4,10 @@
#include <stdlib.h>
#include <assert.h>
int main(int argc, char **argv) {
int main (int argc, char **argv)
{
hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
unsigned int len;
const char *font_data = hb_blob_get_data (blob, &len);
if (len == 0)
@ -14,10 +16,13 @@ int main(int argc, char **argv) {
exit (1);
}
for (int i = 1; i < argc; i++) {
for (int i = 1; i < argc; i++)
{
printf ("%s\n", argv[i]);
LLVMFuzzerTestOneInput((const uint8_t *) font_data, len);
LLVMFuzzerTestOneInput ((const uint8_t *) font_data, len);
}
hb_blob_destroy (blob);
return 0;
}

View File

@ -10,3 +10,4 @@
../fonts/28f497629c04ceb15546c9a70e0730125ed6698d.ttf::U+11013,U+11044,U+11046:[brm_KA=0+754|brm_vowelOO=0@-647,0+0|brm_virama=0@-524,0+0]
../fonts/28f497629c04ceb15546c9a70e0730125ed6698d.ttf::U+11013,U+1103C:[brm_KA=0+754|brm_vowelU=0@-403,0+0]
../fonts/86cdd983c4e4c4d7f27dd405d6ceb7d4b9ed3d35.ttf::U+111C8,U+111C9,U+111C9:[u111C8=0+500|u111C9=0@-500,0+0|u111C9=0@-500,0+0]
../fonts/fd565cabd5208d345d0ed4fda7ae742917d846a5.ttf::U+1A3D,U+1A5A,U+1A63:[uni1A3D=0+250|uni1A5A=0+0|uni1A63=0+250]

Some files were not shown because too many files have changed in this diff Show More