Bug 1434447 - Update HarfBuzz to 1.7.5. r=jfkthame

--HG--
extra : rebase_source : 04cf40893bd7dc2e2cf7727574af1ef956968f84
This commit is contained in:
Ryan VanderMeulen 2018-02-27 12:37:56 -05:00
Родитель 31d536ed63
Коммит 6ecf16b619
82 изменённых файлов: 5114 добавлений и 2372 удалений

Просмотреть файл

@ -1,3 +1,12 @@
Overview of changes leading to 1.7.5
Tuesday, January 30, 2018
====================================
- Separate Khmer shaper from Indic.
- First stab at AAT morx. Not hooked up.
- Misc bug fixes.
Overview of changes leading to 1.7.4
Wednesday, December 20, 2017
====================================

Просмотреть файл

@ -1,6 +1,7 @@
[![Build Status](https://travis-ci.org/harfbuzz/harfbuzz.svg)](https://travis-ci.org/harfbuzz/harfbuzz)
[![Build status](https://ci.appveyor.com/api/projects/status/0t0flrxpstj9lb9w?svg=true)](https://ci.appveyor.com/project/harfbuzz/harfbuzz)
[![CircleCI](https://circleci.com/gh/harfbuzz/harfbuzz.svg?style=svg)](https://circleci.com/gh/harfbuzz/harfbuzz)
[![Coverity](https://img.shields.io/coverity/scan/5450.svg)](https://scan.coverity.com/projects/behdad-harfbuzz)
[![Coverage Status](https://img.shields.io/coveralls/harfbuzz/harfbuzz.svg)](https://coveralls.io/r/harfbuzz/harfbuzz)
[ABI Tracker](http://abi-laboratory.pro/tracker/timeline/harfbuzz/)

Просмотреть файл

@ -1,9 +1,9 @@
gfx/harfbuzz status as of 2017-12-20:
gfx/harfbuzz status as of 2018-01-30:
This directory contains the HarfBuzz source from the 'master' branch of
https://github.com/behdad/harfbuzz.
Current version: 1.7.4
Current version: 1.7.5
UPDATING:

Просмотреть файл

@ -42,5 +42,7 @@ echo "running autoreconf --force --install --verbose"
autoreconf --force --install --verbose || exit $?
cd $olddir
echo "running configure $@"
test -n "$NOCONFIGURE" || "$srcdir/configure" "$@"
test -n "$NOCONFIGURE" || {
echo "running configure $@"
"$srcdir/configure" "$@"
}

Просмотреть файл

@ -1,6 +1,6 @@
AC_PREREQ([2.64])
AC_INIT([HarfBuzz],
[1.7.4],
[1.7.5],
[https://github.com/harfbuzz/harfbuzz/issues/new],
[harfbuzz],
[http://harfbuzz.org/])
@ -9,8 +9,7 @@ AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([src/harfbuzz.pc.in])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([1.11.1 gnits tar-ustar dist-bzip2 no-dist-gzip -Wall no-define color-tests -Wno-portability])
AM_CONDITIONAL(AUTOMAKE_OLDER_THAN_1_13, test $am__api_version = 1.11 -o $am__api_version = 1.12)
AM_INIT_AUTOMAKE([1.13.0 gnits tar-ustar dist-bzip2 no-dist-gzip -Wall no-define color-tests -Wno-portability])
AM_SILENT_RULES([yes])
# Initialize libtool
@ -23,7 +22,7 @@ AC_USE_SYSTEM_EXTENSIONS
AC_PROG_CC
AM_PROG_CC_C_O
AC_PROG_CXX
AX_CXX_COMPILE_STDCXX(11, noext, optional)
dnl AX_CXX_COMPILE_STDCXX(11, noext, optional)
AC_SYS_LARGEFILE
PKG_PROG_PKG_CONFIG([0.20])
AM_MISSING_PROG([RAGEL], [ragel])
@ -84,6 +83,9 @@ if test "x$GCC" = "xyes"; then
# Make sure we don't link to libstdc++
CXXFLAGS="$CXXFLAGS -fno-rtti -fno-exceptions"
# No threadsafe statics and C++ as we do it ourselves
CXXFLAGS="$CXXFLAGS -fno-threadsafe-statics"
# Assorted warnings
CXXFLAGS="$CXXFLAGS -Wcast-align"
@ -355,6 +357,7 @@ if $have_freetype; then
LIBS="$LIBS $FREETYPE_LIBS"
AC_CHECK_FUNCS(FT_Get_Var_Blend_Coordinates)
AC_CHECK_FUNCS(FT_Set_Var_Blend_Coordinates)
AC_CHECK_FUNCS(FT_Done_MM_Var)
LIBS=$save_libs
fi
AM_CONDITIONAL(HAVE_FREETYPE, $have_freetype)
@ -429,7 +432,7 @@ if test "x$with_coretext" = "xyes" -o "x$with_coretext" = "xauto"; then
if $have_coretext; then
CORETEXT_CFLAGS=
CORETEXT_LIBS="-framework CoreText -framework CoreGraphics"
CORETEXT_LIBS="-framework CoreText -framework CoreGraphics -framework CoreFoundation"
AC_SUBST(CORETEXT_CFLAGS)
AC_SUBST(CORETEXT_LIBS)
fi
@ -494,6 +497,9 @@ test/Makefile
test/api/Makefile
test/fuzzing/Makefile
test/shaping/Makefile
test/shaping/data/Makefile
test/shaping/data/in-house/Makefile
test/shaping/data/text-rendering-tests/Makefile
docs/Makefile
docs/version.xml
])

Просмотреть файл

@ -1,5 +1,6 @@
# Process this file with automake to produce Makefile.in
NULL =
SUBDIRS =
DIST_SUBDIRS =
BUILT_SOURCES =
@ -134,7 +135,7 @@ pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = harfbuzz.pc
EXTRA_DIST += harfbuzz.pc.in
FUZZING_CPPFLAGS= \
FUZZING_CPPFLAGS = \
-DHB_NDEBUG \
-DHB_MAX_NESTING_LEVEL=3 \
-DHB_SANITIZE_MAX_EDITS=3 \
@ -222,21 +223,14 @@ CLEANFILES += $(pkgconfig_DATA)
CLEANFILES += harfbuzz.def
harfbuzz.def: $(HBHEADERS) $(HBNODISTHEADERS)
$(AM_V_GEN) (echo EXPORTS; \
(cat $^ || echo 'hb_ERROR ()' ) | \
$(EGREP) '^hb_.* \(' | \
sed -e 's/ (.*//' | \
LC_ALL=C sort; \
echo LIBRARY libharfbuzz-0.dll; \
) >"$@"
@ ! grep -q hb_ERROR "$@" \
|| ($(RM) "$@"; false)
$(AM_V_GEN) headers="$^" $(srcdir)/gen-def.py $@
GENERATORS = \
gen-arabic-table.py \
gen-indic-table.py \
gen-use-table.py \
gen-def.py \
$(NULL)
EXTRA_DIST += $(GENERATORS)

Просмотреть файл

@ -7,8 +7,7 @@ test -z "$srcdir" && srcdir=.
stat=0
test "x$HBHEADERS" = x && HBHEADERS=`cd "$srcdir"; find . -maxdepth 1 -name 'hb*.h'`
test "x$HBSOURCES" = x && HBSOURCES=`cd "$srcdir"; find . -maxdepth 1 -name 'hb*.h'`
test "x$HBSOURCES" = x && HBSOURCES=`cd "$srcdir"; find . -maxdepth 1 -name 'hb*.cc'`
for x in $HBHEADERS; do
test -f "$srcdir/$x" -a ! -f "$x" && x="$srcdir/$x"

Просмотреть файл

@ -4,7 +4,7 @@ LC_ALL=C
export LC_ALL
test -z "$srcdir" && srcdir=.
test -z "$MAKE" && MAKE=make
test -z "$libs" && libs=.libs
stat=0
if which nm 2>/dev/null >/dev/null; then
@ -15,26 +15,36 @@ else
fi
defs="harfbuzz.def"
$MAKE $defs > /dev/null
if ! test -f "$defs"; then
echo "check-defs.sh: '$defs' not found; skipping test"
exit 77
fi
tested=false
for def in $defs; do
lib=`echo "$def" | sed 's/[.]def$//;s@.*/@@'`
so=.libs/lib${lib}.so
for suffix in so dylib; do
so=$libs/lib${lib}.$suffix
if ! test -f "$so"; then continue; fi
EXPORTED_SYMBOLS="`nm "$so" | grep ' [BCDGINRSTVW] .' | grep -v ' _fini\>\| _init\>\| _fdata\>\| _ftext\>\| _fbss\>\| __bss_start\>\| __bss_start__\>\| __bss_end__\>\| _edata\>\| _end\>\| _bss_end__\>\| __end__\>\| __gcov_flush\>\| llvm_' | cut -d' ' -f3`"
# On mac, C symbols are prefixed with _
if test $suffix = dylib; then prefix="_"; fi
if test -f "$so"; then
EXPORTED_SYMBOLS="`nm "$so" | grep ' [BCDGINRSTVW] .' | grep -v " $prefix"'\(_fini\>\|_init\>\|_fdata\>\|_ftext\>\|_fbss\>\|__bss_start\>\|__bss_start__\>\|__bss_end__\>\|_edata\>\|_end\>\|_bss_end__\>\|__end__\>\|__gcov_flush\>\|llvm_\)' | cut -d' ' -f3`"
echo "Checking that $so has the same symbol list as $def"
{
echo EXPORTS
echo "$EXPORTED_SYMBOLS"
# cheat: copy the last line from the def file!
tail -n1 "$def"
} | diff "$def" - >&2 || stat=1
if test -f "$so"; then
tested=true
fi
echo "Checking that $so has the same symbol list as $def"
{
echo EXPORTS
echo "$EXPORTED_SYMBOLS" | sed -e "s/^${prefix}hb/hb/g"
# cheat: copy the last line from the def file!
tail -n1 "$def"
} | diff "$def" - >&2 || stat=1
tested=true
fi
done
done
if ! $tested; then
echo "check-defs.sh: libharfbuzz shared library not found; skipping test"

Просмотреть файл

@ -6,7 +6,7 @@ export LC_ALL
test -z "$srcdir" && srcdir=.
stat=0
test "x$HBHEADERS" = x && HBHEADERS=`cd "$srcdir"; find . -maxdepth 1 -name 'hb*.h'`
test "x$HBHEADERS" = x && HBHEADERS=`cd "$srcdir"; find . -maxdepth 1 -name 'hb*.h' ! -name 'hb-gobject-structs.h'`
test "x$HBSOURCES" = x && HBSOURCES=`cd "$srcdir"; find . -maxdepth 1 -name 'hb-*.cc' -or -name 'hb-*.hh'`
for x in $HBHEADERS $HBSOURCES; do

Просмотреть файл

@ -4,23 +4,29 @@ LC_ALL=C
export LC_ALL
test -z "$srcdir" && srcdir=.
test -z "$libs" && libs=.libs
stat=0
if which ldd 2>/dev/null >/dev/null; then
:
LDD=ldd
else
echo "check-libstdc++.sh: 'ldd' not found; skipping test"
exit 77
# macOS specific tool
if which otool 2>/dev/null >/dev/null; then
LDD="otool -L"
else
echo "check-libstdc++.sh: 'ldd' not found; skipping test"
exit 77
fi
fi
tested=false
for suffix in so dylib; do
so=.libs/libharfbuzz.$suffix
so=$libs/libharfbuzz.$suffix
if ! test -f "$so"; then continue; fi
echo "Checking that we are not linking to libstdc++ or libc++"
if ldd $so | grep 'libstdc[+][+]\|libc[+][+]'; then
if $LDD $so | grep 'libstdc[+][+]\|libc[+][+]'; then
echo "Ouch, linked to libstdc++ or libc++"
stat=1
fi

Просмотреть файл

@ -4,6 +4,7 @@ LC_ALL=C
export LC_ALL
test -z "$srcdir" && srcdir=.
test -z "$libs" && libs=.libs
stat=0
@ -14,7 +15,7 @@ else
exit 77
fi
OBJS=.libs/*.o
OBJS=$libs/*.o
if test "x`echo $OBJS`" = "x$OBJS" 2>/dev/null >/dev/null; then
echo "check-static-inits.sh: object files not found; skipping test"
exit 77

Просмотреть файл

@ -4,6 +4,7 @@ LC_ALL=C
export LC_ALL
test -z "$srcdir" && srcdir=.
test -z "$libs" && libs=.libs
stat=0
@ -17,7 +18,7 @@ fi
echo "Checking that we are not exposing internal symbols"
tested=false
for suffix in so dylib; do
so=.libs/libharfbuzz.$suffix
so=$libs/libharfbuzz.$suffix
if ! test -f "$so"; then continue; fi
EXPORTED_SYMBOLS="`nm "$so" | grep ' [BCDGINRSTVW] .' | grep -v ' _fini\>\| _init\>\| _fdata\>\| _ftext\>\| _fbss\>\| __bss_start\>\| __bss_start__\>\| __bss_end__\>\| _edata\>\| _end\>\| _bss_end__\>\| __end__\>\| __gcov_flush\>\| ___gcov_flush\>\| llvm_\| _llvm_' | cut -d' ' -f3`"

16
gfx/harfbuzz/src/gen-def.py Executable file
Просмотреть файл

@ -0,0 +1,16 @@
#!/usr/bin/env python
from __future__ import print_function
import io, os, re, sys
headers_content = []
for h in os.environ["headers"].split (' '):
if h.endswith (".h"):
with io.open(h, encoding='utf8') as f: headers_content.append (f.read ())
result = ("EXPORTS\n" +
"\n".join (sorted (re.findall (r"^hb_\w+(?= \()", "\n".join (headers_content), re.M))) +
"\nLIBRARY libharfbuzz-0.dll")
with open (sys.argv[1], "w") as f: f.write (result)

Просмотреть файл

@ -229,13 +229,13 @@ print " {"
pages = set([u>>page_bits for u in starts+ends+singles.keys()])
for p in sorted(pages):
print " case 0x%0Xu:" % p
for u,d in singles.items ():
if p != u>>page_bits: continue
print " if (unlikely (u == 0x%04Xu)) return _(%s,%s);" % (u, short[0][d[0]], short[1][d[1]])
for (start,end) in zip (starts, ends):
if p not in [start>>page_bits, end>>page_bits]: continue
offset = "indic_offset_0x%04xu" % start
print " if (hb_in_range<hb_codepoint_t> (u, 0x%04Xu, 0x%04Xu)) return indic_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset)
for u,d in singles.items ():
if p != u>>page_bits: continue
print " if (unlikely (u == 0x%04Xu)) return _(%s,%s);" % (u, short[0][d[0]], short[1][d[1]])
print " break;"
print ""
print " default:"

Просмотреть файл

@ -297,6 +297,9 @@ def map_to_use(data):
if U == 0x17DD: UISC = Vowel_Dependent
if 0x1CE2 <= U <= 0x1CE8: UISC = Cantillation_Mark
# TODO: https://github.com/harfbuzz/harfbuzz/pull/627
if 0x1BF2 <= U <= 0x1BF3: UISC = Nukta; UIPC = Bottom
# TODO: U+1CED should only be allowed after some of
# the nasalization marks, maybe only for U+1CE9..U+1CF1.
if U == 0x1CED: UISC = Tone_Mark
@ -349,12 +352,6 @@ def map_to_use(data):
defaults = ('O', 'No_Block')
data = map_to_use(data)
# Remove the outliers
singles = {}
for u in [0x034F, 0x25CC, 0x1107F]:
singles[u] = data[u]
del data[u]
print "/* == Start of generated table == */"
print "/*"
print " * The following table is generated by running:"
@ -456,16 +453,13 @@ print "hb_use_get_categories (hb_codepoint_t u)"
print "{"
print " switch (u >> %d)" % page_bits
print " {"
pages = set([u>>page_bits for u in starts+ends+singles.keys()])
pages = set([u>>page_bits for u in starts+ends])
for p in sorted(pages):
print " case 0x%0Xu:" % p
for (start,end) in zip (starts, ends):
if p not in [start>>page_bits, end>>page_bits]: continue
offset = "use_offset_0x%04xu" % start
print " if (hb_in_range<hb_codepoint_t> (u, 0x%04Xu, 0x%04Xu)) return use_table[u - 0x%04Xu + %s];" % (start, end-1, start, offset)
for u,d in singles.items ():
if p != u>>page_bits: continue
print " if (unlikely (u == 0x%04Xu)) return %s;" % (u, d[0])
print " break;"
print ""
print " default:"

Просмотреть файл

@ -5,7 +5,7 @@ includedir=/usr/local/include
Name: harfbuzz
Description: HarfBuzz text shaping library ICU integration
Version: 1.7.4
Version: 1.7.5
Requires: harfbuzz
Requires.private: icu-uc

Просмотреть файл

@ -5,7 +5,7 @@ includedir=/usr/local/include
Name: harfbuzz
Description: HarfBuzz text shaping library
Version: 1.7.4
Version: 1.7.5
Libs: -L${libdir} -lharfbuzz
Libs.private: -lm

Просмотреть файл

@ -0,0 +1,708 @@
/*
* Copyright © 2017 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_AAT_LAYOUT_COMMON_PRIVATE_HH
#define HB_AAT_LAYOUT_COMMON_PRIVATE_HH
#include "hb-aat-layout-private.hh"
namespace AAT {
using namespace OT;
/*
* Binary Searching Tables
*/
struct BinSearchHeader
{
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
HBUINT16 unitSize; /* Size of a lookup unit for this search in bytes. */
HBUINT16 nUnits; /* Number of units of the preceding size to be searched. */
HBUINT16 searchRange; /* The value of unitSize times the largest power of 2
* that is less than or equal to the value of nUnits. */
HBUINT16 entrySelector; /* The log base 2 of the largest power of 2 less than
* or equal to the value of nUnits. */
HBUINT16 rangeShift; /* The value of unitSize times the difference of the
* value of nUnits minus the largest power of 2 less
* than or equal to the value of nUnits. */
public:
DEFINE_SIZE_STATIC (10);
};
template <typename Type>
struct BinSearchArrayOf
{
inline const Type& operator [] (unsigned int i) const
{
if (unlikely (i >= header.nUnits)) return Null(Type);
return StructAtOffset<Type> (bytes, i * header.unitSize);
}
inline Type& operator [] (unsigned int i)
{
return StructAtOffset<Type> (bytes, i * header.unitSize);
}
inline unsigned int get_size (void) const
{ return header.static_size + header.nUnits * header.unitSize; }
inline 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(), ie. they do not
* reference other structs via offsets.
*/
(void) (false && StructAtOffset<Type> (bytes, 0).sanitize (c));
return_trace (true);
}
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c))) return_trace (false);
unsigned int count = header.nUnits;
for (unsigned int i = 0; i < count; i++)
if (unlikely (!(*this)[i].sanitize (c, base)))
return_trace (false);
return_trace (true);
}
template <typename T>
inline const Type *bsearch (const T &key) const
{
unsigned int size = header.unitSize;
int min = 0, max = (int) header.nUnits - 1;
while (min <= max)
{
int mid = (min + max) / 2;
const Type *p = (const Type *) (((const char *) bytes) + (mid * size));
int c = p->cmp (key);
if (c < 0)
max = mid - 1;
else if (c > 0)
min = mid + 1;
else
return p;
}
return NULL;
}
private:
inline bool sanitize_shallow (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (header.sanitize (c) &&
Type::static_size >= header.unitSize &&
c->check_array (bytes, header.unitSize, header.nUnits));
}
protected:
BinSearchHeader header;
HBUINT8 bytes[VAR];
public:
DEFINE_SIZE_ARRAY (10, bytes);
};
/* TODO Move this to hb-open-type-private.hh and use it in ArrayOf, HeadlessArrayOf,
* and other places around the code base?? */
template <typename Type>
struct UnsizedArrayOf
{
inline const Type& operator [] (unsigned int i) const { return arrayZ[i]; }
inline Type& operator [] (unsigned int i) { return arrayZ[i]; }
inline 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(), ie. they do not
* reference other structs via offsets.
*/
(void) (false && arrayZ[0].sanitize (c));
return_trace (true);
}
inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base) const
{
TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
for (unsigned int i = 0; i < count; i++)
if (unlikely (!arrayZ[i].sanitize (c, base)))
return_trace (false);
return_trace (true);
}
template <typename T>
inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, const void *base, T user_data) const
{
TRACE_SANITIZE (this);
if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
for (unsigned int i = 0; i < count; i++)
if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
return_trace (false);
return_trace (true);
}
private:
inline bool sanitize_shallow (hb_sanitize_context_t *c, unsigned int count) const
{
TRACE_SANITIZE (this);
return_trace (c->check_array (arrayZ, arrayZ[0].static_size, count));
}
public:
Type arrayZ[VAR];
public:
DEFINE_SIZE_ARRAY (0, arrayZ);
};
/* Unsized array of offset's */
template <typename Type, typename OffsetType>
struct UnsizedOffsetArrayOf : UnsizedArrayOf<OffsetTo<Type, OffsetType> > {};
/* Unsized array of offsets relative to the beginning of the array itself. */
template <typename Type, typename OffsetType>
struct UnsizedOffsetListOf : UnsizedOffsetArrayOf<Type, OffsetType>
{
inline const Type& operator [] (unsigned int i) const
{
return this+this->arrayZ[i];
}
inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
{
TRACE_SANITIZE (this);
return_trace ((UnsizedOffsetArrayOf<Type, OffsetType>::sanitize (c, count, this)));
}
template <typename T>
inline bool sanitize (hb_sanitize_context_t *c, unsigned int count, T user_data) const
{
TRACE_SANITIZE (this);
return_trace ((UnsizedOffsetArrayOf<Type, OffsetType>::sanitize (c, count, this, user_data)));
}
};
/*
* Lookup Table
*/
template <typename T> struct Lookup;
template <typename T>
struct LookupFormat0
{
friend struct Lookup<T>;
private:
inline const T* get_value (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
{
if (unlikely (glyph_id >= num_glyphs)) return nullptr;
return &arrayZ[glyph_id];
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (arrayZ.sanitize (c, c->num_glyphs));
}
protected:
HBUINT16 format; /* Format identifier--format = 0 */
UnsizedArrayOf<T>
arrayZ; /* Array of lookup values, indexed by glyph index. */
public:
DEFINE_SIZE_ARRAY (2, arrayZ);
};
template <typename T>
struct LookupSegmentSingle
{
inline int cmp (hb_codepoint_t g) const {
return g < first ? -1 : g <= last ? 0 : +1 ;
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && value.sanitize (c));
}
GlyphID last; /* Last GlyphID in this segment */
GlyphID first; /* First GlyphID in this segment */
T value; /* The lookup value (only one) */
public:
DEFINE_SIZE_STATIC (4 + T::static_size);
};
template <typename T>
struct LookupFormat2
{
friend struct Lookup<T>;
private:
inline const T* get_value (hb_codepoint_t glyph_id) const
{
const LookupSegmentSingle<T> *v = segments.bsearch (glyph_id);
return v ? &v->value : nullptr;
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (segments.sanitize (c));
}
protected:
HBUINT16 format; /* Format identifier--format = 2 */
BinSearchArrayOf<LookupSegmentSingle<T> >
segments; /* The actual segments. These must already be sorted,
* according to the first word in each one (the last
* glyph in each segment). */
public:
DEFINE_SIZE_ARRAY (8, segments);
};
template <typename T>
struct LookupSegmentArray
{
inline const T* get_value (hb_codepoint_t glyph_id, const void *base) const
{
return first <= glyph_id && glyph_id <= last ? &(base+valuesZ)[glyph_id - first] : nullptr;
}
inline int cmp (hb_codepoint_t g) const {
return g < first ? -1 : g <= last ? 0 : +1 ;
}
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
first <= last &&
valuesZ.sanitize (c, base, last - first + 1));
}
GlyphID last; /* Last GlyphID in this segment */
GlyphID first; /* First GlyphID in this segment */
OffsetTo<UnsizedArrayOf<T> >
valuesZ; /* A 16-bit offset from the start of
* the table to the data. */
public:
DEFINE_SIZE_STATIC (6);
};
template <typename T>
struct LookupFormat4
{
friend struct Lookup<T>;
private:
inline const T* get_value (hb_codepoint_t glyph_id) const
{
const LookupSegmentArray<T> *v = segments.bsearch (glyph_id);
return v ? v->get_value (glyph_id, this) : nullptr;
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (segments.sanitize (c, this));
}
protected:
HBUINT16 format; /* Format identifier--format = 2 */
BinSearchArrayOf<LookupSegmentArray<T> >
segments; /* The actual segments. These must already be sorted,
* according to the first word in each one (the last
* glyph in each segment). */
public:
DEFINE_SIZE_ARRAY (8, segments);
};
template <typename T>
struct LookupSingle
{
inline int cmp (hb_codepoint_t g) const { return glyph.cmp (g); }
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && value.sanitize (c));
}
GlyphID glyph; /* Last GlyphID */
T value; /* The lookup value (only one) */
public:
DEFINE_SIZE_STATIC (4 + T::static_size);
};
template <typename T>
struct LookupFormat6
{
friend struct Lookup<T>;
private:
inline const T* get_value (hb_codepoint_t glyph_id) const
{
const LookupSingle<T> *v = entries.bsearch (glyph_id);
return v ? &v->value : nullptr;
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (entries.sanitize (c));
}
protected:
HBUINT16 format; /* Format identifier--format = 6 */
BinSearchArrayOf<LookupSingle<T> >
entries; /* The actual entries, sorted by glyph index. */
public:
DEFINE_SIZE_ARRAY (8, entries);
};
template <typename T>
struct LookupFormat8
{
friend struct Lookup<T>;
private:
inline const T* get_value (hb_codepoint_t glyph_id) const
{
return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ? &valueArrayZ[glyph_id - firstGlyph] : nullptr;
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && valueArrayZ.sanitize (c, glyphCount));
}
protected:
HBUINT16 format; /* Format identifier--format = 6 */
GlyphID firstGlyph; /* First glyph index included in the trimmed array. */
HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last
* glyph minus the value of firstGlyph plus 1). */
UnsizedArrayOf<T>
valueArrayZ; /* The lookup values (indexed by the glyph index
* minus the value of firstGlyph). */
public:
DEFINE_SIZE_ARRAY (6, valueArrayZ);
};
template <typename T>
struct Lookup
{
inline const T* get_value (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
{
switch (u.format) {
case 0: return u.format0.get_value (glyph_id, num_glyphs);
case 2: return u.format2.get_value (glyph_id);
case 4: return u.format4.get_value (glyph_id);
case 6: return u.format6.get_value (glyph_id);
case 8: return u.format8.get_value (glyph_id);
default:return nullptr;
}
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return_trace (false);
switch (u.format) {
case 0: return_trace (u.format0.sanitize (c));
case 2: return_trace (u.format2.sanitize (c));
case 4: return_trace (u.format4.sanitize (c));
case 6: return_trace (u.format6.sanitize (c));
case 8: return_trace (u.format8.sanitize (c));
default:return_trace (true);
}
}
protected:
union {
HBUINT16 format; /* Format identifier */
LookupFormat0<T> format0;
LookupFormat2<T> format2;
LookupFormat4<T> format4;
LookupFormat6<T> format6;
LookupFormat8<T> format8;
} u;
public:
DEFINE_SIZE_UNION (2, format);
};
/*
* Extended State Table
*/
template <typename T>
struct Entry
{
inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
{
TRACE_SANITIZE (this);
/* Note, we don't recurse-sanitize data because we don't access it.
* That said, in our DEFINE_SIZE_STATIC we access T::static_size,
* which ensures that data has a simple sanitize(). To be determined
* if I need to remove that as well. */
return_trace (c->check_struct (this));
}
public:
HBUINT16 newState; /* Byte offset from beginning of state table
* to the new state. Really?!?! Or just state
* number? The latter in morx for sure. */
HBUINT16 flags; /* Table specific. */
T data; /* Optional offsets to per-glyph tables. */
public:
DEFINE_SIZE_STATIC (4 + T::static_size);
};
template <>
struct Entry<void>
{
inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
public:
HBUINT16 newState; /* Byte offset from beginning of state table to the new state. */
HBUINT16 flags; /* Table specific. */
public:
DEFINE_SIZE_STATIC (4);
};
template <typename Extra>
struct StateTable
{
inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
{
const HBUINT16 *v = (this+classTable).get_value (glyph_id, num_glyphs);
return v ? *v : 1;
}
inline const Entry<Extra> *get_entries () const
{
return (this+entryTable).arrayZ;
}
inline const Entry<Extra> *get_entryZ (unsigned int state, unsigned int klass) const
{
if (unlikely (klass >= nClasses)) return nullptr;
const HBUINT16 *states = (this+stateArrayTable).arrayZ;
const Entry<Extra> *entries = (this+entryTable).arrayZ;
unsigned int entry = states[state * nClasses + klass];
return &entries[entry];
}
inline bool sanitize (hb_sanitize_context_t *c,
unsigned int *num_entries_out = nullptr) const
{
TRACE_SANITIZE (this);
if (unlikely (!(c->check_struct (this) &&
classTable.sanitize (c, this)))) return_trace (false);
const HBUINT16 *states = (this+stateArrayTable).arrayZ;
const Entry<Extra> *entries = (this+entryTable).arrayZ;
unsigned int num_states = 1;
unsigned int num_entries = 0;
unsigned int state = 0;
unsigned int entry = 0;
while (state < num_states)
{
if (unlikely (!c->check_array (states + state * nClasses,
states[0].static_size,
nClasses * (num_states - state))))
return_trace (false);
{ /* Sweep new states. */
const HBUINT16 *stop = &states[num_states * nClasses];
for (const HBUINT16 *p = &states[state * nClasses]; p < stop; p++)
num_entries = MAX<unsigned int> (num_entries, *p + 1);
state = num_states;
}
if (unlikely (!c->check_array (entries + entry,
entries[0].static_size,
num_entries - entry)))
return_trace (false);
{ /* Sweep new entries. */
const Entry<Extra> *stop = &entries[num_entries];
for (const Entry<Extra> *p = &entries[entry]; p < stop; p++)
num_states = MAX<unsigned int> (num_states, p->newState + 1);
entry = num_entries;
}
}
if (num_entries_out)
*num_entries_out = num_entries;
return_trace (true);
}
protected:
HBUINT32 nClasses; /* Number of classes, which is the number of indices
* in a single line in the state array. */
OffsetTo<Lookup<HBUINT16>, HBUINT32>
classTable; /* Offset to the class table. */
OffsetTo<UnsizedArrayOf<HBUINT16>, HBUINT32>
stateArrayTable;/* Offset to the state array. */
OffsetTo<UnsizedArrayOf<Entry<Extra> >, HBUINT32>
entryTable; /* Offset to the entry array. */
public:
DEFINE_SIZE_STATIC (16);
};
template <typename EntryData>
struct StateTableDriver
{
inline StateTableDriver (const StateTable<EntryData> &machine_,
hb_buffer_t *buffer_,
hb_face_t *face_) :
machine (machine_),
buffer (buffer_),
num_glyphs (face_->get_num_glyphs ()),
last_zero (0) {}
template <typename context_t>
inline void drive (context_t *c)
{
hb_glyph_info_t *info = buffer->info;
if (!c->in_place)
buffer->clear_output ();
unsigned int state = 0;
bool last_was_dont_advance = false;
for (buffer->idx = 0;;)
{
if (!state)
last_zero = buffer->idx;
unsigned int klass = buffer->idx < buffer->len ?
machine.get_class (info[buffer->idx].codepoint, num_glyphs) :
0 /* End of text */;
const Entry<EntryData> *entry = machine.get_entryZ (state, klass);
if (unlikely (!entry))
break;
if (unlikely (!c->transition (this, entry)))
break;
last_was_dont_advance = (entry->flags & context_t::DontAdvance) && buffer->max_ops--;
state = entry->newState;
if (buffer->idx == buffer->len)
break;
if (!last_was_dont_advance)
buffer->next_glyph ();
}
if (!c->in_place)
{
for (; buffer->idx < buffer->len;)
buffer->next_glyph ();
buffer->swap_buffers ();
}
}
public:
const StateTable<EntryData> &machine;
hb_buffer_t *buffer;
unsigned int num_glyphs;
unsigned int last_zero;
};
struct hb_aat_apply_context_t :
hb_dispatch_context_t<hb_aat_apply_context_t, bool, HB_DEBUG_APPLY>
{
inline const char *get_name (void) { return "APPLY"; }
template <typename T>
inline return_t dispatch (const T &obj) { return obj.apply (this); }
static return_t default_return_value (void) { return false; }
bool stop_sublookup_iteration (return_t r) const { return r; }
hb_font_t *font;
hb_face_t *face;
hb_buffer_t *buffer;
hb_sanitize_context_t sanitizer;
inline hb_aat_apply_context_t (hb_font_t *font_,
hb_buffer_t *buffer_,
hb_blob_t *table) :
font (font_), face (font->face), buffer (buffer_),
sanitizer ()
{
sanitizer.init (table);
sanitizer.num_glyphs = face->get_num_glyphs ();
sanitizer.start_processing ();
}
inline ~hb_aat_apply_context_t (void)
{
sanitizer.end_processing ();
}
};
} /* namespace AAT */
#endif /* HB_AAT_LAYOUT_COMMON_PRIVATE_HH */

Просмотреть файл

@ -0,0 +1,694 @@
/*
* Copyright © 2017 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_AAT_LAYOUT_MORX_TABLE_HH
#define HB_AAT_LAYOUT_MORX_TABLE_HH
#include "hb-open-type-private.hh"
#include "hb-aat-layout-common-private.hh"
#define HB_AAT_TAG_MORX HB_TAG('m','o','r','x')
namespace AAT {
using namespace OT;
struct RearrangementSubtable
{
struct driver_context_t
{
static const bool in_place = true;
enum Flags {
MarkFirst = 0x8000, /* If set, make the current glyph the first
* glyph to be rearranged. */
DontAdvance = 0x4000, /* If set, don't advance to the next glyph
* before going to the new state. This means
* that the glyph index doesn't change, even
* if the glyph at that index has changed. */
MarkLast = 0x2000, /* If set, make the current glyph the last
* glyph to be rearranged. */
Reserved = 0x1FF0, /* These bits are reserved and should be set to 0. */
Verb = 0x000F, /* The type of rearrangement specified. */
};
inline driver_context_t (const RearrangementSubtable *table) :
ret (false),
start (0), end (0),
last_zero_before_start (0) {}
inline bool transition (StateTableDriver<void> *driver,
const Entry<void> *entry)
{
hb_buffer_t *buffer = driver->buffer;
unsigned int flags = entry->flags;
if (flags & MarkFirst)
{
start = buffer->idx;
last_zero_before_start = driver->last_zero;
}
if (flags & MarkLast)
end = MIN (buffer->idx + 1, buffer->len);
if ((flags & Verb) && start < end)
{
/* The following map has two nibbles, for start-side
* and end-side. Values of 0,1,2 mean move that many
* to the other side. Value of 3 means move 2 and
* flip them. */
const unsigned char map[16] =
{
0x00, /* 0 no change */
0x10, /* 1 Ax => xA */
0x01, /* 2 xD => Dx */
0x11, /* 3 AxD => DxA */
0x20, /* 4 ABx => xAB */
0x30, /* 5 ABx => xBA */
0x02, /* 6 xCD => CDx */
0x03, /* 7 xCD => DCx */
0x12, /* 8 AxCD => CDxA */
0x13, /* 9 AxCD => DCxA */
0x21, /* 10 ABxD => DxAB */
0x31, /* 11 ABxD => DxBA */
0x22, /* 12 ABxCD => CDxAB */
0x32, /* 13 ABxCD => CDxBA */
0x23, /* 14 ABxCD => DCxAB */
0x33, /* 15 ABxCD => DCxBA */
};
unsigned int m = map[flags & Verb];
unsigned int l = MIN<unsigned int> (2, m >> 4);
unsigned int r = MIN<unsigned int> (2, m & 0x0F);
bool reverse_l = 3 == (m >> 4);
bool reverse_r = 3 == (m & 0x0F);
if (end - start >= l + r)
{
buffer->unsafe_to_break (last_zero_before_start, MIN (buffer->idx + 1, buffer->len));
buffer->merge_clusters (start, end);
hb_glyph_info_t *info = buffer->info;
hb_glyph_info_t buf[4];
memcpy (buf, info + start, l * sizeof (buf[0]));
memcpy (buf + 2, info + end - r, r * sizeof (buf[0]));
if (l != r)
memmove (info + start + r, info + start + l, (end - start - l - r) * sizeof (buf[0]));
memcpy (info + start, buf + 2, r * sizeof (buf[0]));
memcpy (info + end - l, buf, l * sizeof (buf[0]));
if (reverse_l)
{
buf[0] = info[end - 1];
info[end - 1] = info[end - 2];
info[end - 2] = buf[0];
}
if (reverse_r)
{
buf[0] = info[start];
info[start] = info[start + 1];
info[start + 1] = buf[0];
}
}
}
return true;
}
public:
bool ret;
private:
unsigned int start;
unsigned int end;
unsigned int last_zero_before_start;
};
inline bool apply (hb_aat_apply_context_t *c) const
{
TRACE_APPLY (this);
driver_context_t dc (this);
StateTableDriver<void> driver (machine, c->buffer, c->face);
driver.drive (&dc);
return_trace (dc.ret);
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (machine.sanitize (c));
}
protected:
StateTable<void> machine;
public:
DEFINE_SIZE_STATIC (16);
};
struct ContextualSubtable
{
struct EntryData
{
HBUINT16 markIndex; /* Index of the substitution table for the
* marked glyph (use 0xFFFF for none). */
HBUINT16 currentIndex; /* Index of the substitution table for the
* current glyph (use 0xFFFF for none). */
public:
DEFINE_SIZE_STATIC (4);
};
struct driver_context_t
{
static const bool in_place = true;
enum Flags {
SetMark = 0x8000, /* If set, make the current glyph the marked glyph. */
DontAdvance = 0x4000, /* If set, don't advance to the next glyph before
* going to the new state. */
Reserved = 0x3FFF, /* These bits are reserved and should be set to 0. */
};
inline driver_context_t (const ContextualSubtable *table) :
ret (false),
mark (0),
last_zero_before_mark (0),
subs (table+table->substitutionTables) {}
inline bool transition (StateTableDriver<EntryData> *driver,
const Entry<EntryData> *entry)
{
hb_buffer_t *buffer = driver->buffer;
if (entry->flags & SetMark)
{
mark = buffer->idx;
last_zero_before_mark = driver->last_zero;
}
if (entry->data.markIndex != 0xFFFF)
{
const Lookup<GlyphID> &lookup = subs[entry->data.markIndex];
hb_glyph_info_t *info = buffer->info;
const GlyphID *replacement = lookup.get_value (info[mark].codepoint, driver->num_glyphs);
if (replacement)
{
buffer->unsafe_to_break (last_zero_before_mark, MIN (buffer->idx + 1, buffer->len));
info[mark].codepoint = *replacement;
ret = true;
}
}
if (entry->data.currentIndex != 0xFFFF)
{
const Lookup<GlyphID> &lookup = subs[entry->data.currentIndex];
hb_glyph_info_t *info = buffer->info;
const GlyphID *replacement = lookup.get_value (info[buffer->idx].codepoint, driver->num_glyphs);
if (replacement)
{
buffer->unsafe_to_break (driver->last_zero, MIN (buffer->idx + 1, buffer->len));
info[buffer->idx].codepoint = *replacement;
ret = true;
}
}
return true;
}
public:
bool ret;
private:
unsigned int mark;
unsigned int last_zero_before_mark;
const UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32> &subs;
};
inline bool apply (hb_aat_apply_context_t *c) const
{
TRACE_APPLY (this);
driver_context_t dc (this);
StateTableDriver<EntryData> driver (machine, c->buffer, c->face);
driver.drive (&dc);
return_trace (dc.ret);
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
unsigned int num_entries;
if (unlikely (!machine.sanitize (c, &num_entries))) return false;
unsigned int num_lookups = 0;
const Entry<EntryData> *entries = machine.get_entries ();
for (unsigned int i = 0; i < num_entries; i++)
{
const EntryData &data = entries[i].data;
num_lookups = MAX<unsigned int> (num_lookups, 1 + data.markIndex);
num_lookups = MAX<unsigned int> (num_lookups, 1 + data.currentIndex);
}
return_trace (substitutionTables.sanitize (c, this, num_lookups));
}
protected:
StateTable<EntryData> machine;
OffsetTo<UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32>, HBUINT32>
substitutionTables;
public:
DEFINE_SIZE_STATIC (20);
};
struct LigatureSubtable
{
struct EntryData
{
HBUINT16 ligActionIndex; /* Index to the first ligActionTable entry
* for processing this group, if indicated
* by the flags. */
public:
DEFINE_SIZE_STATIC (2);
};
struct driver_context_t
{
static const bool in_place = false;
enum Flags {
SetComponent = 0x8000, /* Push this glyph onto the component stack for
* eventual processing. */
DontAdvance = 0x4000, /* Leave the glyph pointer at this glyph for the
next iteration. */
PerformAction = 0x2000, /* Use the ligActionIndex to process a ligature
* group. */
Reserved = 0x1FFF, /* These bits are reserved and should be set to 0. */
};
enum LigActionFlags {
LigActionLast = 0x80000000, /* This is the last action in the list. This also
* implies storage. */
LigActionStore = 0x40000000, /* Store the ligature at the current cumulated index
* in the ligature table in place of the marked
* (i.e. currently-popped) glyph. */
LigActionOffset = 0x3FFFFFFF, /* A 30-bit value which is sign-extended to 32-bits
* and added to the glyph ID, resulting in an index
* into the component table. */
};
inline driver_context_t (const LigatureSubtable *table,
hb_aat_apply_context_t *c_) :
ret (false),
c (c_),
ligAction (table+table->ligAction),
component (table+table->component),
ligature (table+table->ligature),
match_length (0) {}
inline bool transition (StateTableDriver<EntryData> *driver,
const Entry<EntryData> *entry)
{
hb_buffer_t *buffer = driver->buffer;
unsigned int flags = entry->flags;
if (flags & SetComponent)
{
if (unlikely (match_length >= ARRAY_LENGTH (match_positions)))
return false;
/* Never mark same index twice, in case DontAdvance was used... */
if (match_length && match_positions[match_length - 1] == buffer->out_len)
match_length--;
match_positions[match_length++] = buffer->out_len;
}
if (flags & PerformAction)
{
unsigned int end = buffer->out_len;
unsigned int action_idx = entry->data.ligActionIndex;
unsigned int action;
unsigned int ligature_idx = 0;
do
{
if (unlikely (!match_length))
return false;
buffer->move_to (match_positions[--match_length]);
const HBUINT32 &actionData = ligAction[action_idx];
if (unlikely (!actionData.sanitize (&c->sanitizer))) return false;
action = actionData;
uint32_t uoffset = action & LigActionOffset;
if (uoffset & 0x20000000)
uoffset += 0xC0000000;
int32_t offset = (int32_t) uoffset;
unsigned int component_idx = buffer->cur().codepoint + offset;
const HBUINT16 &componentData = component[component_idx];
if (unlikely (!componentData.sanitize (&c->sanitizer))) return false;
ligature_idx += componentData;
if (action & (LigActionStore | LigActionLast))
{
const GlyphID &ligatureData = ligature[ligature_idx];
if (unlikely (!ligatureData.sanitize (&c->sanitizer))) return false;
hb_codepoint_t lig = ligatureData;
match_positions[match_length++] = buffer->out_len;
buffer->replace_glyph (lig);
//ligature_idx = 0; // XXX Yes or no?
}
else
{
buffer->skip_glyph ();
end--;
}
/* TODO merge_clusters / unsafe_to_break */
action_idx++;
}
while (!(action & LigActionLast));
buffer->move_to (end);
}
return true;
}
public:
bool ret;
private:
hb_aat_apply_context_t *c;
const UnsizedArrayOf<HBUINT32> &ligAction;
const UnsizedArrayOf<HBUINT16> &component;
const UnsizedArrayOf<GlyphID> &ligature;
unsigned int match_length;
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH];
};
inline bool apply (hb_aat_apply_context_t *c) const
{
TRACE_APPLY (this);
driver_context_t dc (this, c);
StateTableDriver<EntryData> driver (machine, c->buffer, c->face);
driver.drive (&dc);
return_trace (dc.ret);
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
/* The rest of array sanitizations are done at run-time. */
return c->check_struct (this) && machine.sanitize (c) &&
ligAction && component && ligature;
return_trace (true);
}
protected:
StateTable<EntryData> machine;
OffsetTo<UnsizedArrayOf<HBUINT32>, HBUINT32>
ligAction; /* Offset to the ligature action table. */
OffsetTo<UnsizedArrayOf<HBUINT16>, HBUINT32>
component; /* Offset to the component table. */
OffsetTo<UnsizedArrayOf<GlyphID>, HBUINT32>
ligature; /* Offset to the actual ligature lists. */
public:
DEFINE_SIZE_STATIC (28);
};
struct NoncontextualSubtable
{
inline bool apply (hb_aat_apply_context_t *c) const
{
TRACE_APPLY (this);
bool ret = false;
unsigned int num_glyphs = c->face->get_num_glyphs ();
hb_glyph_info_t *info = c->buffer->info;
unsigned int count = c->buffer->len;
for (unsigned int i = 0; i < count; i++)
{
const GlyphID *replacement = substitute.get_value (info[i].codepoint, num_glyphs);
if (replacement)
{
info[i].codepoint = *replacement;
ret = true;
}
}
return_trace (ret);
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (substitute.sanitize (c));
}
protected:
Lookup<GlyphID> substitute;
public:
DEFINE_SIZE_MIN (2);
};
struct InsertionSubtable
{
inline bool apply (hb_aat_apply_context_t *c) const
{
TRACE_APPLY (this);
/* TODO */
return_trace (false);
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
/* TODO */
return_trace (true);
}
};
struct Feature
{
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
public:
HBUINT16 featureType; /* The type of feature. */
HBUINT16 featureSetting; /* The feature's setting (aka selector). */
HBUINT32 enableFlags; /* Flags for the settings that this feature
* and setting enables. */
HBUINT32 disableFlags; /* Complement of flags for the settings that this
* feature and setting disable. */
public:
DEFINE_SIZE_STATIC (12);
};
struct ChainSubtable
{
friend struct Chain;
inline unsigned int get_size (void) const { return length; }
inline unsigned int get_type (void) const { return coverage & 0xFF; }
enum Type {
Rearrangement = 0,
Contextual = 1,
Ligature = 2,
Noncontextual = 4,
Insertion = 5
};
inline void apply (hb_aat_apply_context_t *c) const
{
dispatch (c);
}
template <typename context_t>
inline typename context_t::return_t dispatch (context_t *c) const
{
unsigned int subtable_type = get_type ();
TRACE_DISPATCH (this, subtable_type);
switch (subtable_type) {
case Rearrangement: return_trace (c->dispatch (u.rearrangement));
case Contextual: return_trace (c->dispatch (u.contextual));
case Ligature: return_trace (c->dispatch (u.ligature));
case Noncontextual: return_trace (c->dispatch (u.noncontextual));
case Insertion: return_trace (c->dispatch (u.insertion));
default: return_trace (c->default_return_value ());
}
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (!length.sanitize (c) ||
length < min_size ||
!c->check_range (this, length))
return_trace (false);
return_trace (dispatch (c));
}
protected:
HBUINT32 length; /* Total subtable length, including this header. */
HBUINT32 coverage; /* Coverage flags and subtable type. */
HBUINT32 subFeatureFlags;/* The 32-bit mask identifying which subtable this is. */
union {
RearrangementSubtable rearrangement;
ContextualSubtable contextual;
LigatureSubtable ligature;
NoncontextualSubtable noncontextual;
InsertionSubtable insertion;
} u;
public:
DEFINE_SIZE_MIN (12);
};
struct Chain
{
inline void apply (hb_aat_apply_context_t *c) const
{
const ChainSubtable *subtable = &StructAtOffset<ChainSubtable> (featureZ, featureZ[0].static_size * featureCount);
unsigned int count = subtableCount;
for (unsigned int i = 0; i < count; i++)
{
subtable->apply (c);
subtable = &StructAfter<ChainSubtable> (*subtable);
}
}
inline unsigned int get_size (void) const { return length; }
inline bool sanitize (hb_sanitize_context_t *c, unsigned int major) const
{
TRACE_SANITIZE (this);
if (!length.sanitize (c) ||
length < min_size ||
!c->check_range (this, length))
return_trace (false);
if (!c->check_array (featureZ, featureZ[0].static_size, featureCount))
return_trace (false);
const ChainSubtable *subtable = &StructAtOffset<ChainSubtable> (featureZ, featureZ[0].static_size * featureCount);
unsigned int count = subtableCount;
for (unsigned int i = 0; i < count; i++)
{
if (!subtable->sanitize (c))
return_trace (false);
subtable = &StructAfter<ChainSubtable> (*subtable);
}
return_trace (true);
}
protected:
HBUINT32 defaultFlags; /* The default specification for subtables. */
HBUINT32 length; /* Total byte count, including this header. */
HBUINT32 featureCount; /* Number of feature subtable entries. */
HBUINT32 subtableCount; /* The number of subtables in the chain. */
Feature featureZ[VAR]; /* Features. */
ChainSubtable subtableX[VAR]; /* Subtables. */
// subtableGlyphCoverageArray if major == 3
public:
DEFINE_SIZE_MIN (16);
};
/*
* The 'mort'/'morx' Tables
*/
struct morx
{
static const hb_tag_t tableTag = HB_AAT_TAG_MORX;
inline void apply (hb_aat_apply_context_t *c) const
{
const Chain *chain = chains;
unsigned int count = chainCount;
for (unsigned int i = 0; i < count; i++)
{
chain->apply (c);
chain = &StructAfter<Chain> (*chain);
}
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (!version.sanitize (c) ||
(version.major >> (sizeof (HBUINT32) == 4 ? 1 : 0)) != 1 ||
!chainCount.sanitize (c))
return_trace (false);
const Chain *chain = chains;
unsigned int count = chainCount;
for (unsigned int i = 0; i < count; i++)
{
if (!chain->sanitize (c, version.major))
return_trace (false);
chain = &StructAfter<Chain> (*chain);
}
return_trace (true);
}
protected:
FixedVersion<>version; /* Version number of the glyph metamorphosis table.
* 1 for mort, 2 or 3 for morx. */
HBUINT32 chainCount; /* Number of metamorphosis chains contained in this
* table. */
Chain chains[VAR]; /* Chains. */
public:
DEFINE_SIZE_MIN (8);
};
} /* namespace AAT */
#endif /* HB_AAT_LAYOUT_MORX_TABLE_HH */

Просмотреть файл

@ -0,0 +1,40 @@
/*
* Copyright © 2017 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_AAT_LAYOUT_PRIVATE_HH
#define HB_AAT_LAYOUT_PRIVATE_HH
#include "hb-private.hh"
#include "hb-font-private.hh"
#include "hb-buffer-private.hh"
#include "hb-open-type-private.hh"
HB_INTERNAL void
hb_aat_layout_substitute (hb_font_t *font, hb_buffer_t *buffer);
#endif /* HB_AAT_LAYOUT_PRIVATE_HH */

Просмотреть файл

@ -0,0 +1,78 @@
/*
* Copyright © 2017 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Google Author(s): Behdad Esfahbod
*/
#include "hb-open-type-private.hh"
#include "hb-ot-layout-private.hh"
#include "hb-ot-layout-gsubgpos-private.hh"
#include "hb-aat-layout-private.hh"
#include "hb-aat-layout-morx-table.hh"
/*
* mort/morx
*/
static inline const AAT::morx&
_get_morx (hb_face_t *face, hb_blob_t **blob = nullptr)
{
if (unlikely (!hb_ot_shaper_face_data_ensure (face)))
{
if (blob)
*blob = hb_blob_get_empty ();
return OT::Null(AAT::morx);
}
hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
/* XXX this doesn't call set_num_glyphs on sanitizer. */
const AAT::morx& morx = *(layout->morx.get ());
if (blob)
*blob = layout->morx.blob;
return morx;
}
static inline void
_hb_aat_layout_create (hb_face_t *face)
{
OT::Sanitizer<AAT::morx> sanitizer;
sanitizer.set_num_glyphs (face->get_num_glyphs ());
hb_blob_t *morx_blob = sanitizer.sanitize (face->reference_table (HB_AAT_TAG_MORX));
OT::Sanitizer<AAT::morx>::lock_instance (morx_blob);
if (0)
{
OT::Sanitizer<AAT::Lookup<OT::GlyphID> >::lock_instance (morx_blob)->get_value (1, face->get_num_glyphs ());
}
}
void
hb_aat_layout_substitute (hb_font_t *font, hb_buffer_t *buffer)
{
hb_blob_t *blob;
const AAT::morx& morx = _get_morx (font->face, &blob);
AAT::hb_aat_apply_context_t c (font, buffer, blob);
morx.apply (&c);
}

Просмотреть файл

@ -70,6 +70,29 @@ typedef LONG hb_atomic_int_impl_t;
#define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O))
#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
typedef int hb_atomic_int_impl_t;
#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
#define hb_atomic_int_impl_add(AI, V) __sync_fetch_and_add (&(AI), (V))
#define hb_atomic_ptr_impl_get(P) (void *) (__sync_synchronize (), *(P))
#define hb_atomic_ptr_impl_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N))
#elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS)
#include <atomic.h>
#include <mbarrier.h>
typedef unsigned int hb_atomic_int_impl_t;
#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
#define hb_atomic_int_impl_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V))
#define hb_atomic_ptr_impl_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P))
#define hb_atomic_ptr_impl_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false)
#elif !defined(HB_NO_MT) && defined(__APPLE__)
#include <libkern/OSAtomic.h>
@ -96,29 +119,6 @@ typedef int32_t hb_atomic_int_impl_t;
#endif
#elif !defined(HB_NO_MT) && defined(HAVE_INTEL_ATOMIC_PRIMITIVES)
typedef int hb_atomic_int_impl_t;
#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
#define hb_atomic_int_impl_add(AI, V) __sync_fetch_and_add (&(AI), (V))
#define hb_atomic_ptr_impl_get(P) (void *) (__sync_synchronize (), *(P))
#define hb_atomic_ptr_impl_cmpexch(P,O,N) __sync_bool_compare_and_swap ((P), (O), (N))
#elif !defined(HB_NO_MT) && defined(HAVE_SOLARIS_ATOMIC_OPS)
#include <atomic.h>
#include <mbarrier.h>
typedef unsigned int hb_atomic_int_impl_t;
#define HB_ATOMIC_INT_IMPL_INIT(V) (V)
#define hb_atomic_int_impl_add(AI, V) ( ({__machine_rw_barrier ();}), atomic_add_int_nv (&(AI), (V)) - (V))
#define hb_atomic_ptr_impl_get(P) ( ({__machine_rw_barrier ();}), (void *) *(P))
#define hb_atomic_ptr_impl_cmpexch(P,O,N) ( ({__machine_rw_barrier ();}), atomic_cas_ptr ((void **) (P), (void *) (O), (void *) (N)) == (void *) (O) ? true : false)
#elif !defined(HB_NO_MT) && defined(_AIX) && defined(__IBMCPP__)
#include <builtins.h>

Просмотреть файл

@ -26,7 +26,7 @@
/* http://www.oracle.com/technetwork/articles/servers-storage-dev/standardheaderfiles-453865.html */
#ifndef _POSIX_C_SOURCE
#define _POSIX_C_SOURCE 199309L
#define _POSIX_C_SOURCE 200809L
#endif
#include "hb-private.hh"

Просмотреть файл

@ -44,7 +44,7 @@ HB_BEGIN_DECLS
* any such possibility, MODE_DUPLICATE should be used
* such that HarfBuzz makes a copy immediately,
*
* - Use MODE_READONLY otherse, unless you really really
* - Use MODE_READONLY otherwise, unless you really really
* really know what you are doing,
*
* - MODE_WRITABLE is appropriate if you really made a

Просмотреть файл

@ -69,6 +69,7 @@ enum hb_buffer_scratch_flags_t {
HB_BUFFER_SCRATCH_FLAG_HAS_SPACE_FALLBACK = 0x00000004u,
HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT = 0x00000008u,
HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK = 0x00000010u,
HB_BUFFER_SCRATCH_FLAG_HAS_CGJ = 0x00000020u,
/* Reserved for complex shapers' internal use. */
HB_BUFFER_SCRATCH_FLAG_COMPLEX0 = 0x01000000u,
@ -306,37 +307,37 @@ struct hb_buffer_t {
HB_INTERNAL bool message_impl (hb_font_t *font, const char *fmt, va_list ap) HB_PRINTF_FUNC(3, 0);
static inline void
set_cluster (hb_glyph_info_t &info, unsigned int cluster, unsigned int mask = 0)
set_cluster (hb_glyph_info_t &inf, unsigned int cluster, unsigned int mask = 0)
{
if (info.cluster != cluster)
if (inf.cluster != cluster)
{
if (mask & HB_GLYPH_FLAG_UNSAFE_TO_BREAK)
info.mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
inf.mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
else
info.mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
inf.mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
}
info.cluster = cluster;
inf.cluster = cluster;
}
inline int
_unsafe_to_break_find_min_cluster (const hb_glyph_info_t *info,
_unsafe_to_break_find_min_cluster (const hb_glyph_info_t *infos,
unsigned int start, unsigned int end,
unsigned int cluster) const
{
for (unsigned int i = start; i < end; i++)
cluster = MIN<unsigned int> (cluster, info[i].cluster);
cluster = MIN<unsigned int> (cluster, infos[i].cluster);
return cluster;
}
inline void
_unsafe_to_break_set_mask (hb_glyph_info_t *info,
_unsafe_to_break_set_mask (hb_glyph_info_t *infos,
unsigned int start, unsigned int end,
unsigned int cluster)
{
for (unsigned int i = start; i < end; i++)
if (cluster != info[i].cluster)
if (cluster != infos[i].cluster)
{
scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_UNSAFE_TO_BREAK;
info[i].mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
infos[i].mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
}
}

Просмотреть файл

@ -109,6 +109,7 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
nullptr : hb_buffer_get_glyph_positions (buffer, nullptr);
*buf_consumed = 0;
hb_position_t x = 0, y = 0;
for (unsigned int i = start; i < end; i++)
{
char b[1024];
@ -146,9 +147,10 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
{
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"dx\":%d,\"dy\":%d",
pos[i].x_offset, pos[i].y_offset));
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d",
pos[i].x_advance, pos[i].y_advance));
x+pos[i].x_offset, y+pos[i].y_offset));
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",\"ax\":%d,\"ay\":%d",
pos[i].x_advance, pos[i].y_advance));
}
if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS)
@ -179,6 +181,12 @@ _hb_buffer_serialize_glyphs_json (hb_buffer_t *buffer,
*buf = '\0';
} else
return i - start;
if (pos && (flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))
{
x += pos[i].x_advance;
y += pos[i].y_advance;
}
}
return end - start;
@ -199,6 +207,7 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
nullptr : hb_buffer_get_glyph_positions (buffer, nullptr);
*buf_consumed = 0;
hb_position_t x = 0, y = 0;
for (unsigned int i = start; i < end; i++)
{
char b[1024];
@ -223,13 +232,16 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS))
{
if (pos[i].x_offset || pos[i].y_offset)
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", pos[i].x_offset, pos[i].y_offset));
if (x+pos[i].x_offset || y+pos[i].y_offset)
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "@%d,%d", x+pos[i].x_offset, y+pos[i].y_offset));
*p++ = '+';
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance));
if (pos[i].y_advance)
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance));
if (!(flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))
{
*p++ = '+';
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), "%d", pos[i].x_advance));
if (pos[i].y_advance)
p += MAX (0, snprintf (p, ARRAY_LENGTH (b) - (p - b), ",%d", pos[i].y_advance));
}
}
if (flags & HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS)
@ -255,6 +267,12 @@ _hb_buffer_serialize_glyphs_text (hb_buffer_t *buffer,
*buf = '\0';
} else
return i - start;
if (pos && (flags & HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES))
{
x += pos[i].x_advance;
y += pos[i].y_advance;
}
}
return end - start;

Просмотреть файл

@ -247,13 +247,21 @@ hb_buffer_guess_segment_properties (hb_buffer_t *buffer);
* of the text without the full context.
* @HB_BUFFER_FLAG_EOT: flag indicating that special handling of the end of text
* paragraph can be applied to this buffer, similar to
* @HB_BUFFER_FLAG_EOT.
* @HB_BUFFER_FLAG_BOT.
* @HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES:
* flag indication that character with Default_Ignorable
* Unicode property should use the corresponding glyph
* from the font, instead of hiding them (currently done
* by replacing them with the space glyph and zeroing the
* advance width.)
* from the font, instead of hiding them (done by
* replacing them with the space glyph and zeroing the
* advance width.) This flag takes precedence over
* @HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES.
* @HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES:
* flag indication that character with Default_Ignorable
* Unicode property should be removed from glyph string
* instead of hiding them (done by replacing them with the
* space glyph and zeroing the advance width.)
* @HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES takes
* precedence over this flag. Since: 1.8.0
*
* Since: 0.9.20
*/
@ -261,7 +269,8 @@ typedef enum { /*< flags >*/
HB_BUFFER_FLAG_DEFAULT = 0x00000000u,
HB_BUFFER_FLAG_BOT = 0x00000001u, /* Beginning-of-text */
HB_BUFFER_FLAG_EOT = 0x00000002u, /* End-of-text */
HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004u
HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES = 0x00000004u,
HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES = 0x00000008u
} hb_buffer_flags_t;
HB_EXTERN void
@ -412,6 +421,9 @@ hb_buffer_normalize_glyphs (hb_buffer_t *buffer);
* @HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS: do not serialize glyph position information.
* @HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES: do no serialize glyph name.
* @HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS: serialize glyph extents.
* @HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS: serialize glyph flags. Since: 1.5.0
* @HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES: do not serialize glyph advances,
* glyph offsets will reflect absolute glyph positions. Since: 1.8.0
*
* Flags that control what glyph information are serialized in hb_buffer_serialize_glyphs().
*
@ -423,7 +435,8 @@ typedef enum { /*< flags >*/
HB_BUFFER_SERIALIZE_FLAG_NO_POSITIONS = 0x00000002u,
HB_BUFFER_SERIALIZE_FLAG_NO_GLYPH_NAMES = 0x00000004u,
HB_BUFFER_SERIALIZE_FLAG_GLYPH_EXTENTS = 0x00000008u,
HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS = 0x00000010u
HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS = 0x00000010u,
HB_BUFFER_SERIALIZE_FLAG_NO_ADVANCES = 0x00000020u
} hb_buffer_serialize_flags_t;
/**

Просмотреть файл

@ -524,6 +524,7 @@ hb_script_get_horizontal_direction (hb_script_t script)
case HB_SCRIPT_PSALTER_PAHLAVI:
/* Unicode-8.0 additions */
case HB_SCRIPT_HATRAN:
case HB_SCRIPT_OLD_HUNGARIAN:
/* Unicode-9.0 additions */

Просмотреть файл

@ -164,7 +164,7 @@ hb_face_create (hb_blob_t *blob,
if (unlikely (!blob))
blob = hb_blob_get_empty ();
hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index);
hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>().sanitize (hb_blob_reference (blob)), index);
if (unlikely (!closure))
return hb_face_get_empty ();
@ -424,7 +424,7 @@ hb_face_get_upem (hb_face_t *face)
void
hb_face_t::load_upem (void) const
{
hb_blob_t *head_blob = OT::Sanitizer<OT::head>::sanitize (reference_table (HB_OT_TAG_head));
hb_blob_t *head_blob = OT::Sanitizer<OT::head>().sanitize (reference_table (HB_OT_TAG_head));
const OT::head *head_table = OT::Sanitizer<OT::head>::lock_instance (head_blob);
upem = head_table->get_upem ();
hb_blob_destroy (head_blob);
@ -468,7 +468,7 @@ hb_face_get_glyph_count (hb_face_t *face)
void
hb_face_t::load_num_glyphs (void) const
{
hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>::sanitize (reference_table (HB_OT_TAG_maxp));
hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>().sanitize (reference_table (HB_OT_TAG_maxp));
const OT::maxp *maxp_table = OT::Sanitizer<OT::maxp>::lock_instance (maxp_blob);
num_glyphs = maxp_table->get_num_glyphs ();
hb_blob_destroy (maxp_blob);

Просмотреть файл

@ -128,6 +128,8 @@ struct hb_font_t {
inline hb_position_t em_scale_y (int16_t v) { return em_scale (v, y_scale); }
inline hb_position_t em_scalef_x (float v) { return em_scalef (v, this->x_scale); }
inline hb_position_t em_scalef_y (float v) { return em_scalef (v, this->y_scale); }
inline float em_fscale_x (int16_t v) { return em_fscale (v, x_scale); }
inline float em_fscale_y (int16_t v) { return em_fscale (v, y_scale); }
inline hb_position_t em_scale_dir (int16_t v, hb_direction_t direction)
{ return em_scale (v, dir_scale (direction)); }
@ -541,7 +543,11 @@ struct hb_font_t {
}
inline hb_position_t em_scalef (float v, int scale)
{
return (hb_position_t) (v * scale / face->get_upem ());
return (hb_position_t) round (v * scale / face->get_upem ());
}
inline float em_fscale (int16_t v, int scale)
{
return (float) v * scale / face->get_upem ();
}
};

Просмотреть файл

@ -456,7 +456,7 @@ hb_font_get_glyph_from_name (hb_font_t *font,
/* high-level funcs, with fallback */
/* Calls either hb_font_get_nominal_glyph() if variation_selector is 0,
* otherwise callse hb_font_get_variation_glyph(). */
* otherwise calls hb_font_get_variation_glyph(). */
HB_EXTERN hb_bool_t
hb_font_get_glyph (hb_font_t *font,
hb_codepoint_t unicode, hb_codepoint_t variation_selector,

Просмотреть файл

@ -635,15 +635,27 @@ hb_ft_font_changed (hb_font_t *font)
{
if (!FT_Get_Var_Blend_Coordinates (ft_face, mm_var->num_axis, ft_coords))
{
for (unsigned int i = 0; i < mm_var->num_axis; ++i)
coords[i] = ft_coords[i] >>= 2;
bool nonzero = false;
hb_font_set_var_coords_normalized (font, coords, mm_var->num_axis);
for (unsigned int i = 0; i < mm_var->num_axis; ++i)
{
coords[i] = ft_coords[i] >>= 2;
nonzero = nonzero || coords[i];
}
if (nonzero)
hb_font_set_var_coords_normalized (font, coords, mm_var->num_axis);
else
hb_font_set_var_coords_normalized (font, nullptr, 0);
}
}
free (coords);
free (ft_coords);
#ifdef HAVE_FT_DONE_MM_VAR
FT_Done_MM_Var (ft_face->glyph->library, mm_var);
#else
free (mm_var);
#endif
}
#endif
}

Просмотреть файл

@ -64,9 +64,9 @@ typedef struct TableRecord
Tag tag; /* 4-byte identifier. */
CheckSum checkSum; /* CheckSum for this table. */
UINT32 offset; /* Offset from beginning of TrueType font
HBUINT32 offset; /* Offset from beginning of TrueType font
* file. */
UINT32 length; /* Length of this table. */
HBUINT32 length; /* Length of this table. */
public:
DEFINE_SIZE_STATIC (16);
} OpenTypeTable;
@ -154,7 +154,7 @@ struct TTCHeaderVersion1
Tag ttcTag; /* TrueType Collection ID string: 'ttcf' */
FixedVersion<>version; /* Version of the TTC Header (1.0),
* 0x00010000u */
ArrayOf<LOffsetTo<OffsetTable>, UINT32>
ArrayOf<LOffsetTo<OffsetTable>, HBUINT32>
table; /* Array of offsets to the OffsetTable for each font
* from the beginning of the file */
public:

Просмотреть файл

@ -187,7 +187,8 @@ struct hb_sanitize_context_t :
debug_depth (0),
start (nullptr), end (nullptr),
writable (false), edit_count (0),
blob (nullptr) {}
blob (nullptr),
num_glyphs (0) {}
inline const char *get_name (void) { return "SANITIZE"; }
template <typename T, typename F>
@ -298,6 +299,7 @@ struct hb_sanitize_context_t :
bool writable;
unsigned int edit_count;
hb_blob_t *blob;
unsigned int num_glyphs;
};
@ -306,8 +308,9 @@ struct hb_sanitize_context_t :
template <typename Type>
struct Sanitizer
{
static hb_blob_t *sanitize (hb_blob_t *blob) {
hb_sanitize_context_t c[1];
inline Sanitizer (void) {}
inline hb_blob_t *sanitize (hb_blob_t *blob) {
bool sane;
/* TODO is_sane() stuff */
@ -370,6 +373,11 @@ struct Sanitizer
const char *base = hb_blob_get_data (blob, nullptr);
return unlikely (!base) ? &Null(Type) : CastP<Type> (base);
}
inline void set_num_glyphs (unsigned int num_glyphs) { c->num_glyphs = num_glyphs; }
private:
hb_sanitize_context_t c[1];
};
@ -519,8 +527,6 @@ struct Supplier
};
/*
*
* The OpenType Font File: Data Types
@ -635,22 +641,22 @@ struct IntType
DEFINE_SIZE_STATIC (Size);
};
typedef IntType<uint8_t, 1> UINT8; /* 8-bit unsigned integer. */
typedef IntType<int8_t, 1> INT8; /* 8-bit signed integer. */
typedef IntType<uint16_t, 2> UINT16; /* 16-bit unsigned integer. */
typedef IntType<int16_t, 2> INT16; /* 16-bit signed integer. */
typedef IntType<uint32_t, 4> UINT32; /* 32-bit unsigned integer. */
typedef IntType<int32_t, 4> INT32; /* 32-bit signed integer. */
typedef IntType<uint8_t, 1> HBUINT8; /* 8-bit unsigned integer. */
typedef IntType<int8_t, 1> HBINT8; /* 8-bit signed integer. */
typedef IntType<uint16_t, 2> HBUINT16; /* 16-bit unsigned integer. */
typedef IntType<int16_t, 2> HBINT16; /* 16-bit signed integer. */
typedef IntType<uint32_t, 4> HBUINT32; /* 32-bit unsigned integer. */
typedef IntType<int32_t, 4> HBINT32; /* 32-bit signed integer. */
typedef IntType<uint32_t, 3> UINT24; /* 24-bit unsigned integer. */
/* 16-bit signed integer (INT16) that describes a quantity in FUnits. */
typedef INT16 FWORD;
/* 16-bit signed integer (HBINT16) that describes a quantity in FUnits. */
typedef HBINT16 FWORD;
/* 16-bit unsigned integer (UINT16) that describes a quantity in FUnits. */
typedef UINT16 UFWORD;
/* 16-bit unsigned integer (HBUINT16) that describes a quantity in FUnits. */
typedef HBUINT16 UFWORD;
/* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
struct F2DOT14 : INT16
struct F2DOT14 : HBINT16
{
//inline float to_float (void) const { return ???; }
//inline void set_float (float f) { v.set (f * ???); }
@ -659,7 +665,7 @@ struct F2DOT14 : INT16
};
/* 32-bit signed fixed-point number (16.16). */
struct Fixed: INT32
struct Fixed: HBINT32
{
//inline float to_float (void) const { return ???; }
//inline void set_float (float f) { v.set (f * ???); }
@ -677,15 +683,15 @@ struct LONGDATETIME
return_trace (likely (c->check_struct (this)));
}
protected:
INT32 major;
UINT32 minor;
HBINT32 major;
HBUINT32 minor;
public:
DEFINE_SIZE_STATIC (8);
};
/* Array of four uint8s (length = 32 bits) used to identify a script, language
* system, feature, or baseline */
struct Tag : UINT32
struct Tag : HBUINT32
{
/* What the char* converters return is NOT nul-terminated. Print using "%.4s" */
inline operator const char* (void) const { return reinterpret_cast<const char *> (&this->v); }
@ -696,10 +702,10 @@ struct Tag : UINT32
DEFINE_NULL_DATA (Tag, " ");
/* Glyph index number, same as uint16 (length = 16 bits) */
typedef UINT16 GlyphID;
typedef HBUINT16 GlyphID;
/* Script/language-system/feature index */
struct Index : UINT16 {
struct Index : HBUINT16 {
static const unsigned int NOT_FOUND_INDEX = 0xFFFFu;
};
DEFINE_NULL_DATA (Index, "\xff\xff");
@ -713,18 +719,18 @@ struct Offset : Type
DEFINE_SIZE_STATIC (sizeof(Type));
};
typedef Offset<UINT16> Offset16;
typedef Offset<UINT32> Offset32;
typedef Offset<HBUINT16> Offset16;
typedef Offset<HBUINT32> Offset32;
/* CheckSum */
struct CheckSum : UINT32
struct CheckSum : HBUINT32
{
/* This is reference implementation from the spec. */
static inline uint32_t CalcTableChecksum (const UINT32 *Table, uint32_t Length)
static inline uint32_t CalcTableChecksum (const HBUINT32 *Table, uint32_t Length)
{
uint32_t Sum = 0L;
const UINT32 *EndPtr = Table+((Length+3) & ~3) / UINT32::static_size;
const HBUINT32 *EndPtr = Table+((Length+3) & ~3) / HBUINT32::static_size;
while (Table < EndPtr)
Sum += *Table++;
@ -733,7 +739,7 @@ struct CheckSum : UINT32
/* Note: data should be 4byte aligned and have 4byte padding at the end. */
inline void set_for_data (const void *data, unsigned int length)
{ set (CalcTableChecksum ((const UINT32 *) data, length)); }
{ set (CalcTableChecksum ((const HBUINT32 *) data, length)); }
public:
DEFINE_SIZE_STATIC (4);
@ -744,7 +750,7 @@ struct CheckSum : UINT32
* Version Numbers
*/
template <typename FixedType=UINT16>
template <typename FixedType=HBUINT16>
struct FixedVersion
{
inline uint32_t to_int (void) const { return (major << (sizeof(FixedType) * 8)) + minor; }
@ -768,7 +774,7 @@ struct FixedVersion
* Use: (base+offset)
*/
template <typename Type, typename OffsetType=UINT16>
template <typename Type, typename OffsetType=HBUINT16>
struct OffsetTo : Offset<OffsetType>
{
inline const Type& operator () (const void *base) const
@ -813,7 +819,7 @@ struct OffsetTo : Offset<OffsetType>
}
DEFINE_SIZE_STATIC (sizeof(OffsetType));
};
template <typename Type> struct LOffsetTo : OffsetTo<Type, UINT32> {};
template <typename Type> struct LOffsetTo : OffsetTo<Type, HBUINT32> {};
template <typename Base, typename OffsetType, typename Type>
static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType> &offset) { return offset (base); }
template <typename Base, typename OffsetType, typename Type>
@ -825,7 +831,7 @@ static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset)
*/
/* An array with a number of elements. */
template <typename Type, typename LenType=UINT16>
template <typename Type, typename LenType=HBUINT16>
struct ArrayOf
{
const Type *sub_array (unsigned int start_offset, unsigned int *pcount /* IN/OUT */) const
@ -935,10 +941,10 @@ struct ArrayOf
public:
DEFINE_SIZE_ARRAY (sizeof (LenType), array);
};
template <typename Type> struct LArrayOf : ArrayOf<Type, UINT32> {};
template <typename Type> struct LArrayOf : ArrayOf<Type, HBUINT32> {};
/* Array of Offset's */
template <typename Type, typename OffsetType=UINT16>
template <typename Type, typename OffsetType=HBUINT16>
struct OffsetArrayOf : ArrayOf<OffsetTo<Type, OffsetType> > {};
/* Array of offsets relative to the beginning of the array itself. */
@ -966,7 +972,7 @@ struct OffsetListOf : OffsetArrayOf<Type>
/* An array starting at second element. */
template <typename Type, typename LenType=UINT16>
template <typename Type, typename LenType=HBUINT16>
struct HeadlessArrayOf
{
inline const Type& operator [] (unsigned int i) const
@ -1028,19 +1034,19 @@ struct HeadlessArrayOf
/*
* An array with sorted elements. Supports binary searching.
*/
template <typename Type, typename LenType=UINT16>
template <typename Type, typename LenType=HBUINT16>
struct SortedArrayOf : ArrayOf<Type, LenType>
{
template <typename SearchType>
inline int bsearch (const SearchType &x) const
{
/* Hand-coded bsearch here since this is in the hot inner loop. */
const Type *array = this->array;
const Type *arr = this->array;
int min = 0, max = (int) this->len - 1;
while (min <= max)
{
int mid = (min + max) / 2;
int c = array[mid].cmp (x);
int c = arr[mid].cmp (x);
if (c < 0)
max = mid - 1;
else if (c > 0)
@ -1067,10 +1073,10 @@ struct BinSearchHeader
}
protected:
UINT16 len;
UINT16 searchRangeZ;
UINT16 entrySelectorZ;
UINT16 rangeShiftZ;
HBUINT16 len;
HBUINT16 searchRangeZ;
HBUINT16 entrySelectorZ;
HBUINT16 rangeShiftZ;
public:
DEFINE_SIZE_STATIC (8);
@ -1139,8 +1145,8 @@ struct hb_lazy_table_loader_t
inline void init (hb_face_t *face_)
{
face = face_;
instance = nullptr;
blob = nullptr;
instance = nullptr;
}
inline void fini (void)
@ -1154,7 +1160,7 @@ struct hb_lazy_table_loader_t
T *p = (T *) hb_atomic_ptr_get (&instance);
if (unlikely (!p))
{
hb_blob_t *blob_ = OT::Sanitizer<T>::sanitize (face->reference_table (T::tableTag));
hb_blob_t *blob_ = OT::Sanitizer<T>().sanitize (face->reference_table (T::tableTag));
p = const_cast<T *>(OT::Sanitizer<T>::lock_instance (blob_));
if (!hb_atomic_ptr_cmpexch (const_cast<T **>(&instance), nullptr, p))
{
@ -1171,10 +1177,10 @@ struct hb_lazy_table_loader_t
return get();
}
private:
hb_face_t *face;
T *instance;
mutable hb_blob_t *blob;
private:
mutable T *instance;
};

Просмотреть файл

@ -47,20 +47,20 @@ struct SmallGlyphMetrics
extents->height = -height;
}
UINT8 height;
UINT8 width;
INT8 bearingX;
INT8 bearingY;
UINT8 advance;
HBUINT8 height;
HBUINT8 width;
HBINT8 bearingX;
HBINT8 bearingY;
HBUINT8 advance;
DEFINE_SIZE_STATIC(5);
};
struct BigGlyphMetrics : SmallGlyphMetrics
{
INT8 vertBearingX;
INT8 vertBearingY;
UINT8 vertAdvance;
HBINT8 vertBearingX;
HBINT8 vertBearingY;
HBUINT8 vertAdvance;
DEFINE_SIZE_STATIC(8);
};
@ -73,18 +73,18 @@ struct SBitLineMetrics
return_trace (c->check_struct (this));
}
INT8 ascender;
INT8 decender;
UINT8 widthMax;
INT8 caretSlopeNumerator;
INT8 caretSlopeDenominator;
INT8 caretOffset;
INT8 minOriginSB;
INT8 minAdvanceSB;
INT8 maxBeforeBL;
INT8 minAfterBL;
INT8 padding1;
INT8 padding2;
HBINT8 ascender;
HBINT8 decender;
HBUINT8 widthMax;
HBINT8 caretSlopeNumerator;
HBINT8 caretSlopeDenominator;
HBINT8 caretOffset;
HBINT8 minOriginSB;
HBINT8 minAdvanceSB;
HBINT8 maxBeforeBL;
HBINT8 minAfterBL;
HBINT8 padding1;
HBINT8 padding2;
DEFINE_SIZE_STATIC(12);
};
@ -102,9 +102,9 @@ struct IndexSubtableHeader
return_trace (c->check_struct (this));
}
UINT16 indexFormat;
UINT16 imageFormat;
UINT32 imageDataOffset;
HBUINT16 indexFormat;
HBUINT16 imageFormat;
HBUINT32 imageDataOffset;
DEFINE_SIZE_STATIC(8);
};
@ -137,8 +137,8 @@ struct IndexSubtableFormat1Or3
DEFINE_SIZE_ARRAY(8, offsetArrayZ);
};
struct IndexSubtableFormat1 : IndexSubtableFormat1Or3<UINT32> {};
struct IndexSubtableFormat3 : IndexSubtableFormat1Or3<UINT16> {};
struct IndexSubtableFormat1 : IndexSubtableFormat1Or3<HBUINT32> {};
struct IndexSubtableFormat3 : IndexSubtableFormat1Or3<HBUINT16> {};
struct IndexSubtable
{
@ -214,8 +214,8 @@ struct IndexSubtableRecord
offset, length, format);
}
UINT16 firstGlyphIndex;
UINT16 lastGlyphIndex;
HBUINT16 firstGlyphIndex;
HBUINT16 lastGlyphIndex;
LOffsetTo<IndexSubtable> offsetToSubtable;
DEFINE_SIZE_STATIC(8);
@ -276,17 +276,17 @@ struct BitmapSizeTable
protected:
LOffsetTo<IndexSubtableArray> indexSubtableArrayOffset;
UINT32 indexTablesSize;
UINT32 numberOfIndexSubtables;
UINT32 colorRef;
HBUINT32 indexTablesSize;
HBUINT32 numberOfIndexSubtables;
HBUINT32 colorRef;
SBitLineMetrics horizontal;
SBitLineMetrics vertical;
UINT16 startGlyphIndex;
UINT16 endGlyphIndex;
UINT8 ppemX;
UINT8 ppemY;
UINT8 bitDepth;
INT8 flags;
HBUINT16 startGlyphIndex;
HBUINT16 endGlyphIndex;
HBUINT8 ppemX;
HBUINT8 ppemY;
HBUINT8 bitDepth;
HBINT8 flags;
public:
DEFINE_SIZE_STATIC(48);
@ -300,8 +300,8 @@ struct BitmapSizeTable
struct GlyphBitmapDataFormat17
{
SmallGlyphMetrics glyphMetrics;
UINT32 dataLen;
UINT8 dataZ[VAR];
HBUINT32 dataLen;
HBUINT8 dataZ[VAR];
DEFINE_SIZE_ARRAY(9, dataZ);
};
@ -379,8 +379,8 @@ struct CBDT
{
upem = face->get_upem();
cblc_blob = Sanitizer<CBLC>::sanitize (face->reference_table (HB_OT_TAG_CBLC));
cbdt_blob = Sanitizer<CBDT>::sanitize (face->reference_table (HB_OT_TAG_CBDT));
cblc_blob = Sanitizer<CBLC>().sanitize (face->reference_table (HB_OT_TAG_CBLC));
cbdt_blob = Sanitizer<CBDT>().sanitize (face->reference_table (HB_OT_TAG_CBDT));
cbdt_len = hb_blob_get_length (cbdt_blob);
if (hb_blob_get_length (cblc_blob) == 0) {
@ -460,7 +460,7 @@ struct CBDT
protected:
FixedVersion<>version;
UINT8 dataZ[VAR];
HBUINT8 dataZ[VAR];
public:
DEFINE_SIZE_ARRAY(4, dataZ);

Просмотреть файл

@ -58,10 +58,10 @@ struct CmapSubtableFormat0
}
protected:
UINT16 format; /* Format number is set to 0. */
UINT16 lengthZ; /* Byte length of this subtable. */
UINT16 languageZ; /* Ignore. */
UINT8 glyphIdArray[256];/* An array that maps character
HBUINT16 format; /* Format number is set to 0. */
HBUINT16 lengthZ; /* Byte length of this subtable. */
HBUINT16 languageZ; /* Ignore. */
HBUINT8 glyphIdArray[256];/* An array that maps character
* code to glyph index values. */
public:
DEFINE_SIZE_STATIC (6 + 256);
@ -88,8 +88,8 @@ struct CmapSubtableFormat4
/* Custom two-array bsearch. */
int min = 0, max = (int) thiz->segCount - 1;
const UINT16 *startCount = thiz->startCount;
const UINT16 *endCount = thiz->endCount;
const HBUINT16 *startCount = thiz->startCount;
const HBUINT16 *endCount = thiz->endCount;
unsigned int i;
while (min <= max)
{
@ -127,11 +127,11 @@ struct CmapSubtableFormat4
return true;
}
const UINT16 *endCount;
const UINT16 *startCount;
const UINT16 *idDelta;
const UINT16 *idRangeOffset;
const UINT16 *glyphIdArray;
const HBUINT16 *endCount;
const HBUINT16 *startCount;
const HBUINT16 *idDelta;
const HBUINT16 *idRangeOffset;
const HBUINT16 *glyphIdArray;
unsigned int segCount;
unsigned int glyphIdArrayLength;
};
@ -165,24 +165,24 @@ struct CmapSubtableFormat4
}
protected:
UINT16 format; /* Format number is set to 4. */
UINT16 length; /* This is the length in bytes of the
HBUINT16 format; /* Format number is set to 4. */
HBUINT16 length; /* This is the length in bytes of the
* subtable. */
UINT16 languageZ; /* Ignore. */
UINT16 segCountX2; /* 2 x segCount. */
UINT16 searchRangeZ; /* 2 * (2**floor(log2(segCount))) */
UINT16 entrySelectorZ; /* log2(searchRange/2) */
UINT16 rangeShiftZ; /* 2 x segCount - searchRange */
HBUINT16 languageZ; /* Ignore. */
HBUINT16 segCountX2; /* 2 x segCount. */
HBUINT16 searchRangeZ; /* 2 * (2**floor(log2(segCount))) */
HBUINT16 entrySelectorZ; /* log2(searchRange/2) */
HBUINT16 rangeShiftZ; /* 2 x segCount - searchRange */
UINT16 values[VAR];
HBUINT16 values[VAR];
#if 0
UINT16 endCount[segCount]; /* End characterCode for each segment,
HBUINT16 endCount[segCount]; /* End characterCode for each segment,
* last=0xFFFFu. */
UINT16 reservedPad; /* Set to 0. */
UINT16 startCount[segCount]; /* Start character code for each segment. */
INT16 idDelta[segCount]; /* Delta for all character codes in segment. */
UINT16 idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */
UINT16 glyphIdArray[VAR]; /* Glyph index array (arbitrary length) */
HBUINT16 reservedPad; /* Set to 0. */
HBUINT16 startCount[segCount]; /* Start character code for each segment. */
HBINT16 idDelta[segCount]; /* Delta for all character codes in segment. */
HBUINT16 idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */
HBUINT16 glyphIdArray[VAR]; /* Glyph index array (arbitrary length) */
#endif
public:
@ -208,9 +208,9 @@ struct CmapSubtableLongGroup
}
private:
UINT32 startCharCode; /* First character code in this group. */
UINT32 endCharCode; /* Last character code in this group. */
UINT32 glyphID; /* Glyph index; interpretation depends on
HBUINT32 startCharCode; /* First character code in this group. */
HBUINT32 endCharCode; /* Last character code in this group. */
HBUINT32 glyphID; /* Glyph index; interpretation depends on
* subtable format. */
public:
DEFINE_SIZE_STATIC (12);
@ -247,8 +247,8 @@ struct CmapSubtableTrimmed
DEFINE_SIZE_ARRAY (5 * sizeof (UINT), glyphIdArray);
};
struct CmapSubtableFormat6 : CmapSubtableTrimmed<UINT16> {};
struct CmapSubtableFormat10 : CmapSubtableTrimmed<UINT32 > {};
struct CmapSubtableFormat6 : CmapSubtableTrimmed<HBUINT16> {};
struct CmapSubtableFormat10 : CmapSubtableTrimmed<HBUINT32 > {};
template <typename T>
struct CmapSubtableLongSegmented
@ -269,11 +269,11 @@ struct CmapSubtableLongSegmented
}
protected:
UINT16 format; /* Subtable format; set to 12. */
UINT16 reservedZ; /* Reserved; set to 0. */
UINT32 lengthZ; /* Byte length of this subtable. */
UINT32 languageZ; /* Ignore. */
SortedArrayOf<CmapSubtableLongGroup, UINT32>
HBUINT16 format; /* Subtable format; set to 12. */
HBUINT16 reservedZ; /* Reserved; set to 0. */
HBUINT32 lengthZ; /* Byte length of this subtable. */
HBUINT32 languageZ; /* Ignore. */
SortedArrayOf<CmapSubtableLongGroup, HBUINT32>
groups; /* Groupings. */
public:
DEFINE_SIZE_ARRAY (16, groups);
@ -316,13 +316,13 @@ struct UnicodeValueRange
}
UINT24 startUnicodeValue; /* First value in this range. */
UINT8 additionalCount; /* Number of additional values in this
HBUINT8 additionalCount; /* Number of additional values in this
* range. */
public:
DEFINE_SIZE_STATIC (4);
};
typedef SortedArrayOf<UnicodeValueRange, UINT32> DefaultUVS;
typedef SortedArrayOf<UnicodeValueRange, HBUINT32> DefaultUVS;
struct UVSMapping
{
@ -343,7 +343,7 @@ struct UVSMapping
DEFINE_SIZE_STATIC (5);
};
typedef SortedArrayOf<UVSMapping, UINT32> NonDefaultUVS;
typedef SortedArrayOf<UVSMapping, HBUINT32> NonDefaultUVS;
struct VariationSelectorRecord
{
@ -405,9 +405,9 @@ struct CmapSubtableFormat14
}
protected:
UINT16 format; /* Format number is set to 14. */
UINT32 lengthZ; /* Byte length of this subtable. */
SortedArrayOf<VariationSelectorRecord, UINT32>
HBUINT16 format; /* Format number is set to 14. */
HBUINT32 lengthZ; /* Byte length of this subtable. */
SortedArrayOf<VariationSelectorRecord, HBUINT32>
record; /* Variation selector records; sorted
* in increasing order of `varSelector'. */
public:
@ -451,7 +451,7 @@ struct CmapSubtable
public:
union {
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
CmapSubtableFormat0 format0;
CmapSubtableFormat4 format4;
CmapSubtableFormat6 format6;
@ -484,8 +484,8 @@ struct EncodingRecord
subtable.sanitize (c, base));
}
UINT16 platformID; /* Platform ID. */
UINT16 encodingID; /* Platform-specific encoding ID. */
HBUINT16 platformID; /* Platform ID. */
HBUINT16 encodingID; /* Platform-specific encoding ID. */
LOffsetTo<CmapSubtable>
subtable; /* Byte offset from beginning of table to the subtable for this encoding. */
public:
@ -508,7 +508,7 @@ struct cmap
{
inline void init (hb_face_t *face)
{
this->blob = OT::Sanitizer<OT::cmap>::sanitize (face->reference_table (HB_OT_TAG_cmap));
this->blob = OT::Sanitizer<OT::cmap>().sanitize (face->reference_table (HB_OT_TAG_cmap));
const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (this->blob);
const OT::CmapSubtable *subtable = nullptr;
const OT::CmapSubtableFormat14 *subtable_uvs = nullptr;
@ -654,7 +654,7 @@ struct cmap
}
protected:
UINT16 version; /* Table version number (0). */
HBUINT16 version; /* Table version number (0). */
SortedArrayOf<EncodingRecord>
encodingRecord; /* Encoding tables. */
public:

Просмотреть файл

@ -54,7 +54,7 @@ struct loca
}
protected:
UINT8 dataX[VAR]; /* Location data. */
HBUINT8 dataX[VAR]; /* Location data. */
DEFINE_SIZE_ARRAY (0, dataX);
};
@ -80,7 +80,7 @@ struct glyf
struct GlyphHeader
{
INT16 numberOfContours; /* If the number of contours is
HBINT16 numberOfContours; /* If the number of contours is
* greater than or equal to zero,
* this is a simple glyph; if negative,
* this is a composite glyph. */
@ -96,7 +96,7 @@ struct glyf
{
inline void init (hb_face_t *face)
{
hb_blob_t *head_blob = Sanitizer<head>::sanitize (face->reference_table (HB_OT_TAG_head));
hb_blob_t *head_blob = Sanitizer<head>().sanitize (face->reference_table (HB_OT_TAG_head));
const head *head_table = Sanitizer<head>::lock_instance (head_blob);
if ((unsigned int) head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0)
{
@ -107,9 +107,9 @@ struct glyf
short_offset = 0 == head_table->indexToLocFormat;
hb_blob_destroy (head_blob);
loca_blob = Sanitizer<loca>::sanitize (face->reference_table (HB_OT_TAG_loca));
loca_blob = Sanitizer<loca>().sanitize (face->reference_table (HB_OT_TAG_loca));
loca_table = Sanitizer<loca>::lock_instance (loca_blob);
glyf_blob = Sanitizer<glyf>::sanitize (face->reference_table (HB_OT_TAG_glyf));
glyf_blob = Sanitizer<glyf>().sanitize (face->reference_table (HB_OT_TAG_glyf));
glyf_table = Sanitizer<glyf>::lock_instance (glyf_blob);
num_glyphs = MAX (1u, hb_blob_get_length (loca_blob) / (short_offset ? 2 : 4)) - 1;
@ -131,13 +131,13 @@ struct glyf
unsigned int start_offset, end_offset;
if (short_offset)
{
const UINT16 *offsets = (const UINT16 *) loca_table->dataX;
const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataX;
start_offset = 2 * offsets[glyph];
end_offset = 2 * offsets[glyph + 1];
}
else
{
const UINT32 *offsets = (const UINT32 *) loca_table->dataX;
const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataX;
start_offset = offsets[glyph];
end_offset = offsets[glyph + 1];
}
@ -169,7 +169,7 @@ struct glyf
};
protected:
UINT8 dataX[VAR]; /* Glyphs data. */
HBUINT8 dataX[VAR]; /* Glyphs data. */
DEFINE_SIZE_ARRAY (0, dataX);
};

Просмотреть файл

@ -64,11 +64,11 @@ struct head
FixedVersion<>version; /* Version of the head table--currently
* 0x00010000u for version 1.0. */
FixedVersion<>fontRevision; /* Set by font manufacturer. */
UINT32 checkSumAdjustment; /* To compute: set it to 0, sum the
* entire font as UINT32, then store
HBUINT32 checkSumAdjustment; /* To compute: set it to 0, sum the
* entire font as HBUINT32, then store
* 0xB1B0AFBAu - sum. */
UINT32 magicNumber; /* Set to 0x5F0F3CF5u. */
UINT16 flags; /* Bit 0: Baseline for font at y=0;
HBUINT32 magicNumber; /* Set to 0x5F0F3CF5u. */
HBUINT16 flags; /* Bit 0: Baseline for font at y=0;
* Bit 1: Left sidebearing point at x=0;
* Bit 2: Instructions may depend on point size;
* Bit 3: Force ppem to integer values for all
@ -76,7 +76,6 @@ struct head
* ppem sizes if this bit is clear;
* Bit 4: Instructions may alter advance width
* (the advance widths might not scale linearly);
* Bits 5-10: These should be set according to
* Apple's specification. However, they are not
* implemented in OpenType.
@ -96,7 +95,6 @@ struct head
* contains any strong right-to-left glyphs.
* Bit 10: This bit should be set if the font
* contains Indic-style rearrangement effects.
* Bit 11: Font data is 'lossless,' as a result
* of having been compressed and decompressed
* with the Agfa MicroType Express engine.
@ -114,18 +112,18 @@ struct head
* encoded in the cmap subtables represent proper
* support for those code points.
* Bit 15: Reserved, set to 0. */
UINT16 unitsPerEm; /* Valid range is from 16 to 16384. This value
HBUINT16 unitsPerEm; /* Valid range is from 16 to 16384. This value
* should be a power of 2 for fonts that have
* TrueType outlines. */
LONGDATETIME created; /* Number of seconds since 12:00 midnight,
January 1, 1904. 64-bit integer */
LONGDATETIME modified; /* Number of seconds since 12:00 midnight,
January 1, 1904. 64-bit integer */
INT16 xMin; /* For all glyph bounding boxes. */
INT16 yMin; /* For all glyph bounding boxes. */
INT16 xMax; /* For all glyph bounding boxes. */
INT16 yMax; /* For all glyph bounding boxes. */
UINT16 macStyle; /* Bit 0: Bold (if set to 1);
HBINT16 xMin; /* For all glyph bounding boxes. */
HBINT16 yMin; /* For all glyph bounding boxes. */
HBINT16 xMax; /* For all glyph bounding boxes. */
HBINT16 yMax; /* For all glyph bounding boxes. */
HBUINT16 macStyle; /* Bit 0: Bold (if set to 1);
* Bit 1: Italic (if set to 1)
* Bit 2: Underline (if set to 1)
* Bit 3: Outline (if set to 1)
@ -133,16 +131,16 @@ struct head
* Bit 5: Condensed (if set to 1)
* Bit 6: Extended (if set to 1)
* Bits 7-15: Reserved (set to 0). */
UINT16 lowestRecPPEM; /* Smallest readable size in pixels. */
INT16 fontDirectionHint; /* Deprecated (Set to 2).
HBUINT16 lowestRecPPEM; /* Smallest readable size in pixels. */
HBINT16 fontDirectionHint; /* Deprecated (Set to 2).
* 0: Fully mixed directional glyphs;
* 1: Only strongly left to right;
* 2: Like 1 but also contains neutrals;
* -1: Only strongly right to left;
* -2: Like -1 but also contains neutrals. */
public:
INT16 indexToLocFormat; /* 0 for short offsets, 1 for long. */
INT16 glyphDataFormat; /* 0 for current format. */
HBINT16 indexToLocFormat; /* 0 for short offsets, 1 for long. */
HBINT16 glyphDataFormat; /* 0 for current format. */
DEFINE_SIZE_STATIC (54);
};

Просмотреть файл

@ -64,21 +64,21 @@ struct _hea
* (xMax - xMin)) for horizontal. */
FWORD maxExtent; /* horizontal: Max(lsb + (xMax - xMin)),
* vertical: minLeadingBearing+(yMax-yMin). */
INT16 caretSlopeRise; /* Used to calculate the slope of the
HBINT16 caretSlopeRise; /* Used to calculate the slope of the
* cursor (rise/run); 1 for vertical caret,
* 0 for horizontal.*/
INT16 caretSlopeRun; /* 0 for vertical caret, 1 for horizontal. */
INT16 caretOffset; /* The amount by which a slanted
HBINT16 caretSlopeRun; /* 0 for vertical caret, 1 for horizontal. */
HBINT16 caretOffset; /* The amount by which a slanted
* highlight on a glyph needs
* to be shifted to produce the
* best appearance. Set to 0 for
* non-slanted fonts. */
INT16 reserved1; /* Set to 0. */
INT16 reserved2; /* Set to 0. */
INT16 reserved3; /* Set to 0. */
INT16 reserved4; /* Set to 0. */
INT16 metricDataFormat; /* 0 for current format. */
UINT16 numberOfLongMetrics; /* Number of LongMetric entries in metric
HBINT16 reserved1; /* Set to 0. */
HBINT16 reserved2; /* Set to 0. */
HBINT16 reserved3; /* Set to 0. */
HBINT16 reserved4; /* Set to 0. */
HBINT16 metricDataFormat; /* 0 for current format. */
HBUINT16 numberOfLongMetrics; /* Number of LongMetric entries in metric
* table. */
public:
DEFINE_SIZE_STATIC (36);

Просмотреть файл

@ -74,7 +74,7 @@ struct hmtxvmtx
bool got_font_extents = false;
if (T::os2Tag)
{
hb_blob_t *os2_blob = Sanitizer<os2>::sanitize (face->reference_table (T::os2Tag));
hb_blob_t *os2_blob = Sanitizer<os2>().sanitize (face->reference_table (T::os2Tag));
const os2 *os2_table = Sanitizer<os2>::lock_instance (os2_blob);
#define USE_TYPO_METRICS (1u<<7)
if (0 != (os2_table->fsSelection & USE_TYPO_METRICS))
@ -87,7 +87,7 @@ struct hmtxvmtx
hb_blob_destroy (os2_blob);
}
hb_blob_t *_hea_blob = Sanitizer<_hea>::sanitize (face->reference_table (T::headerTag));
hb_blob_t *_hea_blob = Sanitizer<_hea>().sanitize (face->reference_table (T::headerTag));
const _hea *_hea_table = Sanitizer<_hea>::lock_instance (_hea_blob);
num_advances = _hea_table->numberOfLongMetrics;
if (!got_font_extents)
@ -101,7 +101,7 @@ struct hmtxvmtx
has_font_extents = got_font_extents;
blob = Sanitizer<hmtxvmtx>::sanitize (face->reference_table (T::tableTag));
blob = Sanitizer<hmtxvmtx>().sanitize (face->reference_table (T::tableTag));
/* Cap num_metrics() and num_advances() based on table length. */
unsigned int len = hb_blob_get_length (blob);
@ -119,7 +119,7 @@ struct hmtxvmtx
}
table = Sanitizer<hmtxvmtx>::lock_instance (blob);
var_blob = Sanitizer<HVARVVAR>::sanitize (face->reference_table (T::variationsTag));
var_blob = Sanitizer<HVARVVAR>().sanitize (face->reference_table (T::variationsTag));
var_table = Sanitizer<HVARVVAR>::lock_instance (var_blob);
}
@ -144,7 +144,7 @@ struct hmtxvmtx
}
return table->longMetric[MIN (glyph, (uint32_t) num_advances - 1)].advance
+ var_table->get_advance_var (glyph, font->coords, font->num_coords); // TODO Optimize?!
+ (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?!
}
public:

Просмотреть файл

@ -104,8 +104,8 @@ struct KernClassTable
}
protected:
UINT16 firstGlyph; /* First glyph in class range. */
ArrayOf<UINT16> classes; /* Glyph classes. */
HBUINT16 firstGlyph; /* First glyph in class range. */
ArrayOf<HBUINT16> classes; /* Glyph classes. */
public:
DEFINE_SIZE_ARRAY (4, classes);
};
@ -115,7 +115,7 @@ struct KernSubTableFormat2
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
{
unsigned int l = (this+leftClassTable).get_class (left);
unsigned int r = (this+leftClassTable).get_class (left);
unsigned int r = (this+rightClassTable).get_class (right);
unsigned int offset = l * rowWidth + r * sizeof (FWORD);
const FWORD *arr = &(this+array);
if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end))
@ -136,7 +136,7 @@ struct KernSubTableFormat2
}
protected:
UINT16 rowWidth; /* The width, in bytes, of a row in the table. */
HBUINT16 rowWidth; /* The width, in bytes, of a row in the table. */
OffsetTo<KernClassTable>
leftClassTable; /* Offset from beginning of this subtable to
* left-hand class table. */
@ -275,19 +275,19 @@ struct KernOT : KernTable<KernOT>
};
protected:
UINT16 versionZ; /* Unused. */
UINT16 length; /* Length of the subtable (including this header). */
UINT8 format; /* Subtable format. */
UINT8 coverage; /* Coverage bits. */
HBUINT16 versionZ; /* Unused. */
HBUINT16 length; /* Length of the subtable (including this header). */
HBUINT8 format; /* Subtable format. */
HBUINT8 coverage; /* Coverage bits. */
KernSubTable subtable; /* Subtable data. */
public:
DEFINE_SIZE_MIN (6);
};
protected:
UINT16 version; /* Version--0x0000u */
UINT16 nTables; /* Number of subtables in the kerning table. */
UINT8 data[VAR];
HBUINT16 version; /* Version--0x0000u */
HBUINT16 nTables; /* Number of subtables in the kerning table. */
HBUINT8 data[VAR];
public:
DEFINE_SIZE_ARRAY (4, data);
};
@ -314,10 +314,10 @@ struct KernAAT : KernTable<KernAAT>
};
protected:
UINT32 length; /* Length of the subtable (including this header). */
UINT8 coverage; /* Coverage bits. */
UINT8 format; /* Subtable format. */
UINT16 tupleIndex; /* The tuple index (used for variations fonts).
HBUINT32 length; /* Length of the subtable (including this header). */
HBUINT8 coverage; /* Coverage bits. */
HBUINT8 format; /* Subtable format. */
HBUINT16 tupleIndex; /* The tuple index (used for variations fonts).
* This value specifies which tuple this subtable covers. */
KernSubTable subtable; /* Subtable data. */
public:
@ -325,9 +325,9 @@ struct KernAAT : KernTable<KernAAT>
};
protected:
UINT32 version; /* Version--0x00010000u */
UINT32 nTables; /* Number of subtables in the kerning table. */
UINT8 data[VAR];
HBUINT32 version; /* Version--0x00010000u */
HBUINT32 nTables; /* Number of subtables in the kerning table. */
HBUINT8 data[VAR];
public:
DEFINE_SIZE_ARRAY (8, data);
};
@ -360,7 +360,7 @@ struct kern
{
inline void init (hb_face_t *face)
{
blob = Sanitizer<kern>::sanitize (face->reference_table (HB_OT_TAG_kern));
blob = Sanitizer<kern>().sanitize (face->reference_table (HB_OT_TAG_kern));
table = Sanitizer<kern>::lock_instance (blob);
table_length = hb_blob_get_length (blob);
}
@ -380,7 +380,7 @@ struct kern
protected:
union {
UINT16 major;
HBUINT16 major;
KernOT ot;
KernAAT aat;
} u;

Просмотреть файл

@ -161,7 +161,7 @@ struct RangeRecord
GlyphID start; /* First GlyphID in the range */
GlyphID end; /* Last GlyphID in the range */
UINT16 value; /* Value */
HBUINT16 value; /* Value */
public:
DEFINE_SIZE_STATIC (6);
};
@ -175,7 +175,7 @@ struct IndexArray : ArrayOf<Index>
unsigned int *_indexes /* OUT */) const
{
if (_count) {
const UINT16 *arr = this->sub_array (start_offset, _count);
const HBUINT16 *arr = this->sub_array (start_offset, _count);
unsigned int count = *_count;
for (unsigned int i = 0; i < count; i++)
_indexes[i] = arr[i];
@ -218,7 +218,7 @@ struct LangSys
Offset16 lookupOrderZ; /* = Null (reserved for an offset to a
* reordering table) */
UINT16 reqFeatureIndex;/* Index of a feature required for this
HBUINT16 reqFeatureIndex;/* Index of a feature required for this
* language system--if no required features
* = 0xFFFFu */
IndexArray featureIndex; /* Array of indices into the FeatureList */
@ -343,12 +343,12 @@ struct FeatureParamsSize
return_trace (true);
}
UINT16 designSize; /* Represents the design size in 720/inch
HBUINT16 designSize; /* Represents the design size in 720/inch
* units (decipoints). The design size entry
* must be non-zero. When there is a design
* size but no recommended size range, the
* rest of the array will consist of zeros. */
UINT16 subfamilyID; /* Has no independent meaning, but serves
HBUINT16 subfamilyID; /* Has no independent meaning, but serves
* as an identifier that associates fonts
* in a subfamily. All fonts which share a
* Preferred or Font Family name and which
@ -358,7 +358,7 @@ struct FeatureParamsSize
* same subfamily value. If this value is
* zero, the remaining fields in the array
* will be ignored. */
UINT16 subfamilyNameID;/* If the preceding value is non-zero, this
HBUINT16 subfamilyNameID;/* If the preceding value is non-zero, this
* value must be set in the range 256 - 32767
* (inclusive). It records the value of a
* field in the name table, which must
@ -372,10 +372,10 @@ struct FeatureParamsSize
* subfamily in a menu. Applications will
* choose the appropriate version based on
* their selection criteria. */
UINT16 rangeStart; /* Large end of the recommended usage range
HBUINT16 rangeStart; /* Large end of the recommended usage range
* (inclusive), stored in 720/inch units
* (decipoints). */
UINT16 rangeEnd; /* Small end of the recommended usage range
HBUINT16 rangeEnd; /* Small end of the recommended usage range
(exclusive), stored in 720/inch units
* (decipoints). */
public:
@ -393,12 +393,12 @@ struct FeatureParamsStylisticSet
return_trace (c->check_struct (this));
}
UINT16 version; /* (set to 0): This corresponds to a “minor”
HBUINT16 version; /* (set to 0): This corresponds to a “minor”
* version number. Additional data may be
* added to the end of this Feature Parameters
* table in the future. */
UINT16 uiNameID; /* The 'name' table name ID that specifies a
HBUINT16 uiNameID; /* The 'name' table name ID that specifies a
* string (or strings, for multiple languages)
* for a user-interface label for this
* feature. The values of uiLabelNameId and
@ -426,25 +426,25 @@ struct FeatureParamsCharacterVariants
characters.sanitize (c));
}
UINT16 format; /* Format number is set to 0. */
UINT16 featUILableNameID; /* The name table name ID that
HBUINT16 format; /* Format number is set to 0. */
HBUINT16 featUILableNameID; /* The name table name ID that
* specifies a string (or strings,
* for multiple languages) for a
* user-interface label for this
* feature. (May be nullptr.) */
UINT16 featUITooltipTextNameID;/* The name table name ID that
HBUINT16 featUITooltipTextNameID;/* The name table name ID that
* specifies a string (or strings,
* for multiple languages) that an
* application can use for tooltip
* text for this feature. (May be
* nullptr.) */
UINT16 sampleTextNameID; /* The name table name ID that
HBUINT16 sampleTextNameID; /* The name table name ID that
* specifies sample text that
* illustrates the effect of this
* feature. (May be nullptr.) */
UINT16 numNamedParameters; /* Number of named parameters. (May
HBUINT16 numNamedParameters; /* Number of named parameters. (May
* be zero.) */
UINT16 firstParamUILabelNameID;/* The first name table name ID
HBUINT16 firstParamUILabelNameID;/* The first name table name ID
* used to specify strings for
* user-interface labels for the
* feature parameters. (Must be zero
@ -562,7 +562,7 @@ struct Feature
typedef RecordListOf<Feature> FeatureList;
struct LookupFlag : UINT16
struct LookupFlag : HBUINT16
{
enum Flags {
RightToLeft = 0x0001u,
@ -608,7 +608,7 @@ struct Lookup
unsigned int flag = lookupFlag;
if (unlikely (flag & LookupFlag::UseMarkFilteringSet))
{
const UINT16 &markFilteringSet = StructAfter<UINT16> (subTable);
const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
flag += (markFilteringSet << 16);
}
return flag;
@ -640,7 +640,7 @@ struct Lookup
if (unlikely (!subTable.serialize (c, num_subtables))) return_trace (false);
if (lookupFlag & LookupFlag::UseMarkFilteringSet)
{
UINT16 &markFilteringSet = StructAfter<UINT16> (subTable);
HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
markFilteringSet.set (lookup_props >> 16);
}
return_trace (true);
@ -653,18 +653,18 @@ struct Lookup
if (!(c->check_struct (this) && subTable.sanitize (c))) return_trace (false);
if (lookupFlag & LookupFlag::UseMarkFilteringSet)
{
const UINT16 &markFilteringSet = StructAfter<UINT16> (subTable);
const HBUINT16 &markFilteringSet = StructAfter<HBUINT16> (subTable);
if (!markFilteringSet.sanitize (c)) return_trace (false);
}
return_trace (true);
}
private:
UINT16 lookupType; /* Different enumerations for GSUB and GPOS */
UINT16 lookupFlag; /* Lookup qualifiers */
HBUINT16 lookupType; /* Different enumerations for GSUB and GPOS */
HBUINT16 lookupFlag; /* Lookup qualifiers */
ArrayOf<Offset16>
subTable; /* Array of SubTables */
UINT16 markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets
HBUINT16 markFilteringSetX[VAR]; /* Index (base 0) into GDEF mark glyph sets
* structure. This field is only present if bit
* UseMarkFilteringSet of lookup flags is set. */
public:
@ -735,7 +735,7 @@ struct CoverageFormat1
private:
protected:
UINT16 coverageFormat; /* Format identifier--format = 1 */
HBUINT16 coverageFormat; /* Format identifier--format = 1 */
SortedArrayOf<GlyphID>
glyphArray; /* Array of GlyphIDs--in numerical order */
public:
@ -860,7 +860,7 @@ struct CoverageFormat2
private:
protected:
UINT16 coverageFormat; /* Format identifier--format = 2 */
HBUINT16 coverageFormat; /* Format identifier--format = 2 */
SortedArrayOf<RangeRecord>
rangeRecord; /* Array of glyph ranges--ordered by
* Start GlyphID. rangeCount entries
@ -874,8 +874,8 @@ struct Coverage
inline unsigned int get_coverage (hb_codepoint_t glyph_id) const
{
switch (u.format) {
case 1: return u.format1.get_coverage(glyph_id);
case 2: return u.format2.get_coverage(glyph_id);
case 1: return u.format1.get_coverage (glyph_id);
case 2: return u.format2.get_coverage (glyph_id);
default:return NOT_COVERED;
}
}
@ -987,7 +987,7 @@ struct Coverage
protected:
union {
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
CoverageFormat1 format1;
CoverageFormat2 format2;
} u;
@ -1074,9 +1074,9 @@ struct ClassDefFormat1
}
protected:
UINT16 classFormat; /* Format identifier--format = 1 */
HBUINT16 classFormat; /* Format identifier--format = 1 */
GlyphID startGlyph; /* First GlyphID of the classValueArray */
ArrayOf<UINT16>
ArrayOf<HBUINT16>
classValue; /* Array of Class Values--one per GlyphID */
public:
DEFINE_SIZE_ARRAY (6, classValue);
@ -1148,7 +1148,7 @@ struct ClassDefFormat2
}
protected:
UINT16 classFormat; /* Format identifier--format = 2 */
HBUINT16 classFormat; /* Format identifier--format = 2 */
SortedArrayOf<RangeRecord>
rangeRecord; /* Array of glyph ranges--ordered by
* Start GlyphID */
@ -1161,8 +1161,8 @@ struct ClassDef
inline unsigned int get_class (hb_codepoint_t glyph_id) const
{
switch (u.format) {
case 1: return u.format1.get_class(glyph_id);
case 2: return u.format2.get_class(glyph_id);
case 1: return u.format1.get_class (glyph_id);
case 2: return u.format2.get_class (glyph_id);
default:return 0;
}
}
@ -1210,7 +1210,7 @@ struct ClassDef
protected:
union {
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
ClassDefFormat1 format1;
ClassDefFormat2 format2;
} u;
@ -1275,10 +1275,11 @@ struct VarRegionList
const VarRegionAxis *axes = axesZ + (region_index * axisCount);
float v = 1.;
unsigned int count = MIN (coord_len, (unsigned int) axisCount);
unsigned int count = axisCount;
for (unsigned int i = 0; i < count; i++)
{
float factor = axes[i].evaluate (coords[i]);
int coord = i < coord_len ? coords[i] : 0;
float factor = axes[i].evaluate (coord);
if (factor == 0.)
return 0.;
v *= factor;
@ -1295,8 +1296,8 @@ struct VarRegionList
}
protected:
UINT16 axisCount;
UINT16 regionCount;
HBUINT16 axisCount;
HBUINT16 regionCount;
VarRegionAxis axesZ[VAR];
public:
DEFINE_SIZE_ARRAY (4, axesZ);
@ -1320,19 +1321,19 @@ struct VarData
unsigned int count = regionIndices.len;
unsigned int scount = shortCount;
const UINT8 *bytes = &StructAfter<UINT8> (regionIndices);
const UINT8 *row = bytes + inner * (scount + count);
const HBUINT8 *bytes = &StructAfter<HBUINT8> (regionIndices);
const HBUINT8 *row = bytes + inner * (scount + count);
float delta = 0.;
unsigned int i = 0;
const INT16 *scursor = reinterpret_cast<const INT16 *> (row);
const HBINT16 *scursor = reinterpret_cast<const HBINT16 *> (row);
for (; i < scount; i++)
{
float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count);
delta += scalar * *scursor++;
}
const INT8 *bcursor = reinterpret_cast<const INT8 *> (scursor);
const HBINT8 *bcursor = reinterpret_cast<const HBINT8 *> (scursor);
for (; i < count; i++)
{
float scalar = regions.evaluate (regionIndices.array[i], coords, coord_count);
@ -1348,15 +1349,15 @@ struct VarData
return_trace (c->check_struct (this) &&
regionIndices.sanitize(c) &&
shortCount <= regionIndices.len &&
c->check_array (&StructAfter<UINT8> (regionIndices),
c->check_array (&StructAfter<HBUINT8> (regionIndices),
get_row_size (), itemCount));
}
protected:
UINT16 itemCount;
UINT16 shortCount;
ArrayOf<UINT16> regionIndices;
UINT8 bytesX[VAR];
HBUINT16 itemCount;
HBUINT16 shortCount;
ArrayOf<HBUINT16> regionIndices;
HBUINT8 bytesX[VAR];
public:
DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX);
};
@ -1392,9 +1393,9 @@ struct VariationStore
}
protected:
UINT16 format;
HBUINT16 format;
LOffsetTo<VarRegionList> regions;
OffsetArrayOf<VarData, UINT32> dataSets;
OffsetArrayOf<VarData, HBUINT32> dataSets;
public:
DEFINE_SIZE_ARRAY (8, dataSets);
};
@ -1421,8 +1422,8 @@ struct ConditionFormat1
}
protected:
UINT16 format; /* Format identifier--format = 1 */
UINT16 axisIndex;
HBUINT16 format; /* Format identifier--format = 1 */
HBUINT16 axisIndex;
F2DOT14 filterRangeMinValue;
F2DOT14 filterRangeMaxValue;
public:
@ -1451,7 +1452,7 @@ struct Condition
protected:
union {
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
ConditionFormat1 format1;
} u;
public:
@ -1476,7 +1477,7 @@ struct ConditionSet
}
protected:
OffsetArrayOf<Condition, UINT32> conditions;
OffsetArrayOf<Condition, HBUINT32> conditions;
public:
DEFINE_SIZE_ARRAY (2, conditions);
};
@ -1492,7 +1493,7 @@ struct FeatureTableSubstitutionRecord
}
protected:
UINT16 featureIndex;
HBUINT16 featureIndex;
LOffsetTo<Feature> feature;
public:
DEFINE_SIZE_STATIC (6);
@ -1612,8 +1613,8 @@ struct HintingDevice
inline unsigned int get_size (void) const
{
unsigned int f = deltaFormat;
if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * UINT16::static_size;
return UINT16::static_size * (4 + ((endSize - startSize) >> (4 - f)));
if (unlikely (f < 1 || f > 3 || startSize > endSize)) return 3 * HBUINT16::static_size;
return HBUINT16::static_size * (4 + ((endSize - startSize) >> (4 - f)));
}
inline bool sanitize (hb_sanitize_context_t *c) const
@ -1658,14 +1659,14 @@ struct HintingDevice
}
protected:
UINT16 startSize; /* Smallest size to correct--in ppem */
UINT16 endSize; /* Largest size to correct--in ppem */
UINT16 deltaFormat; /* Format of DeltaValue array data: 1, 2, or 3
HBUINT16 startSize; /* Smallest size to correct--in ppem */
HBUINT16 endSize; /* Largest size to correct--in ppem */
HBUINT16 deltaFormat; /* Format of DeltaValue array data: 1, 2, or 3
* 1 Signed 2-bit value, 8 values per uint16
* 2 Signed 4-bit value, 4 values per uint16
* 3 Signed 8-bit value, 2 values per uint16
*/
UINT16 deltaValue[VAR]; /* Array of compressed data */
HBUINT16 deltaValue[VAR]; /* Array of compressed data */
public:
DEFINE_SIZE_ARRAY (6, deltaValue);
};
@ -1696,9 +1697,9 @@ struct VariationDevice
}
protected:
UINT16 outerIndex;
UINT16 innerIndex;
UINT16 deltaFormat; /* Format identifier for this table: 0x0x8000 */
HBUINT16 outerIndex;
HBUINT16 innerIndex;
HBUINT16 deltaFormat; /* Format identifier for this table: 0x0x8000 */
public:
DEFINE_SIZE_STATIC (6);
};
@ -1706,10 +1707,10 @@ struct VariationDevice
struct DeviceHeader
{
protected:
UINT16 reserved1;
UINT16 reserved2;
HBUINT16 reserved1;
HBUINT16 reserved2;
public:
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
public:
DEFINE_SIZE_STATIC (6);
};

Просмотреть файл

@ -41,7 +41,7 @@ namespace OT {
* Attachment List Table
*/
typedef ArrayOf<UINT16> AttachPoint; /* Array of contour point indices--in
typedef ArrayOf<HBUINT16> AttachPoint; /* Array of contour point indices--in
* increasing numerical order */
struct AttachList
@ -62,7 +62,7 @@ struct AttachList
const AttachPoint &points = this+attachPoint[index];
if (point_count) {
const UINT16 *array = points.sub_array (start_offset, point_count);
const HBUINT16 *array = points.sub_array (start_offset, point_count);
unsigned int count = *point_count;
for (unsigned int i = 0; i < count; i++)
point_array[i] = array[i];
@ -109,8 +109,8 @@ struct CaretValueFormat1
}
protected:
UINT16 caretValueFormat; /* Format identifier--format = 1 */
INT16 coordinate; /* X or Y value, in design units */
HBUINT16 caretValueFormat; /* Format identifier--format = 1 */
HBINT16 coordinate; /* X or Y value, in design units */
public:
DEFINE_SIZE_STATIC (4);
};
@ -136,8 +136,8 @@ struct CaretValueFormat2
}
protected:
UINT16 caretValueFormat; /* Format identifier--format = 2 */
UINT16 caretValuePoint; /* Contour point index on glyph */
HBUINT16 caretValueFormat; /* Format identifier--format = 2 */
HBUINT16 caretValuePoint; /* Contour point index on glyph */
public:
DEFINE_SIZE_STATIC (4);
};
@ -160,8 +160,8 @@ struct CaretValueFormat3
}
protected:
UINT16 caretValueFormat; /* Format identifier--format = 3 */
INT16 coordinate; /* X or Y value, in design units */
HBUINT16 caretValueFormat; /* Format identifier--format = 3 */
HBINT16 coordinate; /* X or Y value, in design units */
OffsetTo<Device>
deviceTable; /* Offset to Device table for X or Y
* value--from beginning of CaretValue
@ -199,7 +199,7 @@ struct CaretValue
protected:
union {
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
CaretValueFormat1 format1;
CaretValueFormat2 format2;
CaretValueFormat3 format3;
@ -294,7 +294,7 @@ struct MarkGlyphSetsFormat1
}
protected:
UINT16 format; /* Format identifier--format = 1 */
HBUINT16 format; /* Format identifier--format = 1 */
ArrayOf<LOffsetTo<Coverage> >
coverage; /* Array of long offsets to mark set
* coverage tables */
@ -324,7 +324,7 @@ struct MarkGlyphSets
protected:
union {
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
MarkGlyphSetsFormat1 format1;
} u;
public:

Просмотреть файл

@ -51,11 +51,11 @@ enum attach_type_t {
/* Shared Tables: ValueRecord, Anchor Table, and MarkArray */
typedef UINT16 Value;
typedef HBUINT16 Value;
typedef Value ValueRecord[VAR];
struct ValueFormat : UINT16
struct ValueFormat : HBUINT16
{
enum Flags {
xPlacement = 0x0001u, /* Includes horizontal adjustment for placement */
@ -74,14 +74,14 @@ struct ValueFormat : UINT16
/* All fields are options. Only those available advance the value pointer. */
#if 0
INT16 xPlacement; /* Horizontal adjustment for
HBINT16 xPlacement; /* Horizontal adjustment for
* placement--in design units */
INT16 yPlacement; /* Vertical adjustment for
HBINT16 yPlacement; /* Vertical adjustment for
* placement--in design units */
INT16 xAdvance; /* Horizontal adjustment for
HBINT16 xAdvance; /* Horizontal adjustment for
* advance--in design units (only used
* for horizontal writing) */
INT16 yAdvance; /* Vertical adjustment for advance--in
HBINT16 yAdvance; /* Vertical adjustment for advance--in
* design units (only used for vertical
* writing) */
Offset xPlaDevice; /* Offset to Device table for
@ -103,7 +103,7 @@ struct ValueFormat : UINT16
inline unsigned int get_size (void) const
{ return get_len () * Value::static_size; }
void apply_value (hb_apply_context_t *c,
void apply_value (hb_ot_apply_context_t *c,
const void *base,
const Value *values,
hb_glyph_position_t &glyph_pos) const
@ -178,8 +178,8 @@ struct ValueFormat : UINT16
static inline const OffsetTo<Device>& get_device (const Value* value)
{ return *CastP<OffsetTo<Device> > (value); }
static inline const INT16& get_short (const Value* value)
{ return *CastP<INT16> (value); }
static inline const HBINT16& get_short (const Value* value)
{ return *CastP<HBINT16> (value); }
public:
@ -232,12 +232,12 @@ struct ValueFormat : UINT16
struct AnchorFormat1
{
inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
hb_position_t *x, hb_position_t *y) const
inline void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
float *x, float *y) const
{
hb_font_t *font = c->font;
*x = font->em_scale_x (xCoordinate);
*y = font->em_scale_y (yCoordinate);
*x = font->em_fscale_x (xCoordinate);
*y = font->em_fscale_y (yCoordinate);
}
inline bool sanitize (hb_sanitize_context_t *c) const
@ -247,17 +247,17 @@ struct AnchorFormat1
}
protected:
UINT16 format; /* Format identifier--format = 1 */
INT16 xCoordinate; /* Horizontal value--in design units */
INT16 yCoordinate; /* Vertical value--in design units */
HBUINT16 format; /* Format identifier--format = 1 */
HBINT16 xCoordinate; /* Horizontal value--in design units */
HBINT16 yCoordinate; /* Vertical value--in design units */
public:
DEFINE_SIZE_STATIC (6);
};
struct AnchorFormat2
{
inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id,
hb_position_t *x, hb_position_t *y) const
inline void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id,
float *x, float *y) const
{
hb_font_t *font = c->font;
unsigned int x_ppem = font->x_ppem;
@ -267,8 +267,8 @@ struct AnchorFormat2
ret = (x_ppem || y_ppem) &&
font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy);
*x = ret && x_ppem ? cx : font->em_scale_x (xCoordinate);
*y = ret && y_ppem ? cy : font->em_scale_y (yCoordinate);
*x = ret && x_ppem ? cx : font->em_fscale_x (xCoordinate);
*y = ret && y_ppem ? cy : font->em_fscale_y (yCoordinate);
}
inline bool sanitize (hb_sanitize_context_t *c) const
@ -278,22 +278,22 @@ struct AnchorFormat2
}
protected:
UINT16 format; /* Format identifier--format = 2 */
INT16 xCoordinate; /* Horizontal value--in design units */
INT16 yCoordinate; /* Vertical value--in design units */
UINT16 anchorPoint; /* Index to glyph contour point */
HBUINT16 format; /* Format identifier--format = 2 */
HBINT16 xCoordinate; /* Horizontal value--in design units */
HBINT16 yCoordinate; /* Vertical value--in design units */
HBUINT16 anchorPoint; /* Index to glyph contour point */
public:
DEFINE_SIZE_STATIC (8);
};
struct AnchorFormat3
{
inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
hb_position_t *x, hb_position_t *y) const
inline void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
float *x, float *y) const
{
hb_font_t *font = c->font;
*x = font->em_scale_x (xCoordinate);
*y = font->em_scale_y (yCoordinate);
*x = font->em_fscale_x (xCoordinate);
*y = font->em_fscale_y (yCoordinate);
if (font->x_ppem || font->num_coords)
*x += (this+xDeviceTable).get_x_delta (font, c->var_store);
@ -308,9 +308,9 @@ struct AnchorFormat3
}
protected:
UINT16 format; /* Format identifier--format = 3 */
INT16 xCoordinate; /* Horizontal value--in design units */
INT16 yCoordinate; /* Vertical value--in design units */
HBUINT16 format; /* Format identifier--format = 3 */
HBINT16 xCoordinate; /* Horizontal value--in design units */
HBINT16 yCoordinate; /* Vertical value--in design units */
OffsetTo<Device>
xDeviceTable; /* Offset to Device table for X
* coordinate-- from beginning of
@ -325,15 +325,15 @@ struct AnchorFormat3
struct Anchor
{
inline void get_anchor (hb_apply_context_t *c, hb_codepoint_t glyph_id,
hb_position_t *x, hb_position_t *y) const
inline void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id,
float *x, float *y) const
{
*x = *y = 0;
switch (u.format) {
case 1: u.format1.get_anchor (c, glyph_id, x, y); return;
case 2: u.format2.get_anchor (c, glyph_id, x, y); return;
case 3: u.format3.get_anchor (c, glyph_id, x, y); return;
default: return;
default: return;
}
}
@ -351,7 +351,7 @@ struct Anchor
protected:
union {
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
AnchorFormat1 format1;
AnchorFormat2 format2;
AnchorFormat3 format3;
@ -382,7 +382,7 @@ struct AnchorMatrix
return_trace (true);
}
UINT16 rows; /* Number of rows */
HBUINT16 rows; /* Number of rows */
protected:
OffsetTo<Anchor>
matrixZ[VAR]; /* Matrix of offsets to Anchor tables--
@ -403,7 +403,7 @@ struct MarkRecord
}
protected:
UINT16 klass; /* Class defined for this mark */
HBUINT16 klass; /* Class defined for this mark */
OffsetTo<Anchor>
markAnchor; /* Offset to Anchor table--from
* beginning of MarkArray table */
@ -413,7 +413,7 @@ struct MarkRecord
struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage order */
{
inline bool apply (hb_apply_context_t *c,
inline bool apply (hb_ot_apply_context_t *c,
unsigned int mark_index, unsigned int glyph_index,
const AnchorMatrix &anchors, unsigned int class_count,
unsigned int glyph_pos) const
@ -430,15 +430,15 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde
* return false such that the subsequent subtables have a chance at it. */
if (unlikely (!found)) return_trace (false);
hb_position_t mark_x, mark_y, base_x, base_y;
float mark_x, mark_y, base_x, base_y;
buffer->unsafe_to_break (glyph_pos, buffer->idx);
mark_anchor.get_anchor (c, buffer->cur().codepoint, &mark_x, &mark_y);
glyph_anchor.get_anchor (c, buffer->info[glyph_pos].codepoint, &base_x, &base_y);
hb_glyph_position_t &o = buffer->cur_pos();
o.x_offset = base_x - mark_x;
o.y_offset = base_y - mark_y;
o.x_offset = round (base_x - mark_x);
o.y_offset = round (base_y - mark_y);
o.attach_type() = ATTACH_TYPE_MARK;
o.attach_chain() = (int) glyph_pos - (int) buffer->idx;
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
@ -470,7 +470,7 @@ struct SinglePosFormat1
return this+coverage;
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
@ -492,7 +492,7 @@ struct SinglePosFormat1
}
protected:
UINT16 format; /* Format identifier--format = 1 */
HBUINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of subtable */
@ -518,7 +518,7 @@ struct SinglePosFormat2
return this+coverage;
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
@ -544,13 +544,13 @@ struct SinglePosFormat2
}
protected:
UINT16 format; /* Format identifier--format = 2 */
HBUINT16 format; /* Format identifier--format = 2 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of subtable */
ValueFormat valueFormat; /* Defines the types of data in the
* ValueRecord */
UINT16 valueCount; /* Number of ValueRecords */
HBUINT16 valueCount; /* Number of ValueRecords */
ValueRecord values; /* Array of ValueRecords--positioning
* values applied to glyphs */
public:
@ -573,7 +573,7 @@ struct SinglePos
protected:
union {
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
SinglePosFormat1 format1;
SinglePosFormat2 format2;
} u;
@ -604,13 +604,13 @@ struct PairSet
TRACE_COLLECT_GLYPHS (this);
unsigned int len1 = valueFormats[0].get_len ();
unsigned int len2 = valueFormats[1].get_len ();
unsigned int record_size = UINT16::static_size * (1 + len1 + len2);
unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
const PairValueRecord *record = CastP<PairValueRecord> (arrayZ);
c->input->add_array (&record->secondGlyph, len, record_size);
}
inline bool apply (hb_apply_context_t *c,
inline bool apply (hb_ot_apply_context_t *c,
const ValueFormat *valueFormats,
unsigned int pos) const
{
@ -618,7 +618,7 @@ struct PairSet
hb_buffer_t *buffer = c->buffer;
unsigned int len1 = valueFormats[0].get_len ();
unsigned int len2 = valueFormats[1].get_len ();
unsigned int record_size = UINT16::static_size * (1 + len1 + len2);
unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
const PairValueRecord *record_array = CastP<PairValueRecord> (arrayZ);
unsigned int count = len;
@ -663,7 +663,7 @@ struct PairSet
{
TRACE_SANITIZE (this);
if (!(c->check_struct (this)
&& c->check_array (arrayZ, UINT16::static_size * closure->stride, len))) return_trace (false);
&& c->check_array (arrayZ, HBUINT16::static_size * closure->stride, len))) return_trace (false);
unsigned int count = len;
const PairValueRecord *record = CastP<PairValueRecord> (arrayZ);
@ -672,8 +672,8 @@ struct PairSet
}
protected:
UINT16 len; /* Number of PairValueRecords */
UINT16 arrayZ[VAR]; /* Array of PairValueRecords--ordered
HBUINT16 len; /* Number of PairValueRecords */
HBUINT16 arrayZ[VAR]; /* Array of PairValueRecords--ordered
* by GlyphID of the second glyph */
public:
DEFINE_SIZE_ARRAY (2, arrayZ);
@ -695,14 +695,14 @@ struct PairPosFormat1
return this+coverage;
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return_trace (false);
hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
skippy_iter.reset (buffer->idx, 1);
if (!skippy_iter.next ()) return_trace (false);
@ -728,7 +728,7 @@ struct PairPosFormat1
}
protected:
UINT16 format; /* Format identifier--format = 1 */
HBUINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of subtable */
@ -759,14 +759,14 @@ struct PairPosFormat2
return this+coverage;
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return_trace (false);
hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
skippy_iter.reset (buffer->idx, 1);
if (!skippy_iter.next ()) return_trace (false);
@ -809,7 +809,7 @@ struct PairPosFormat2
}
protected:
UINT16 format; /* Format identifier--format = 2 */
HBUINT16 format; /* Format identifier--format = 2 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of subtable */
@ -827,9 +827,9 @@ struct PairPosFormat2
classDef2; /* Offset to ClassDef table--from
* beginning of PairPos subtable--for
* the second glyph of the pair */
UINT16 class1Count; /* Number of classes in ClassDef1
HBUINT16 class1Count; /* Number of classes in ClassDef1
* table--includes Class0 */
UINT16 class2Count; /* Number of classes in ClassDef2
HBUINT16 class2Count; /* Number of classes in ClassDef2
* table--includes Class0 */
ValueRecord values; /* Matrix of value pairs:
* class1-major, class2-minor,
@ -854,7 +854,7 @@ struct PairPos
protected:
union {
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
PairPosFormat1 format1;
PairPosFormat2 format2;
} u;
@ -900,7 +900,7 @@ struct CursivePosFormat1
return this+coverage;
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
@ -908,7 +908,7 @@ struct CursivePosFormat1
const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)];
if (!this_record.exitAnchor) return_trace (false);
hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
skippy_iter.reset (buffer->idx, 1);
if (!skippy_iter.next ()) return_trace (false);
@ -919,7 +919,7 @@ struct CursivePosFormat1
unsigned int j = skippy_iter.idx;
buffer->unsafe_to_break (i, j);
hb_position_t entry_x, entry_y, exit_x, exit_y;
float entry_x, entry_y, exit_x, exit_y;
(this+this_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y);
(this+next_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y);
@ -929,32 +929,32 @@ struct CursivePosFormat1
/* Main-direction adjustment */
switch (c->direction) {
case HB_DIRECTION_LTR:
pos[i].x_advance = exit_x + pos[i].x_offset;
pos[i].x_advance = round (exit_x) + pos[i].x_offset;
d = entry_x + pos[j].x_offset;
d = round (entry_x) + pos[j].x_offset;
pos[j].x_advance -= d;
pos[j].x_offset -= d;
break;
case HB_DIRECTION_RTL:
d = exit_x + pos[i].x_offset;
d = round (exit_x) + pos[i].x_offset;
pos[i].x_advance -= d;
pos[i].x_offset -= d;
pos[j].x_advance = entry_x + pos[j].x_offset;
pos[j].x_advance = round (entry_x) + pos[j].x_offset;
break;
case HB_DIRECTION_TTB:
pos[i].y_advance = exit_y + pos[i].y_offset;
pos[i].y_advance = round (exit_y) + pos[i].y_offset;
d = entry_y + pos[j].y_offset;
d = round (entry_y) + pos[j].y_offset;
pos[j].y_advance -= d;
pos[j].y_offset -= d;
break;
case HB_DIRECTION_BTT:
d = exit_y + pos[i].y_offset;
d = round (exit_y) + pos[i].y_offset;
pos[i].y_advance -= d;
pos[i].y_offset -= d;
pos[j].y_advance = entry_y;
pos[j].y_advance = round (entry_y);
break;
case HB_DIRECTION_INVALID:
default:
@ -1008,7 +1008,7 @@ struct CursivePosFormat1
}
protected:
UINT16 format; /* Format identifier--format = 1 */
HBUINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of subtable */
@ -1034,7 +1034,7 @@ struct CursivePos
protected:
union {
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
CursivePosFormat1 format1;
} u;
};
@ -1059,7 +1059,7 @@ struct MarkBasePosFormat1
return this+markCoverage;
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
@ -1067,7 +1067,7 @@ struct MarkBasePosFormat1
if (likely (mark_index == NOT_COVERED)) return_trace (false);
/* Now we search backwards for a non-mark glyph */
hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
skippy_iter.reset (buffer->idx, 1);
skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
do {
@ -1099,14 +1099,14 @@ struct MarkBasePosFormat1
}
protected:
UINT16 format; /* Format identifier--format = 1 */
HBUINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
markCoverage; /* Offset to MarkCoverage table--from
* beginning of MarkBasePos subtable */
OffsetTo<Coverage>
baseCoverage; /* Offset to BaseCoverage table--from
* beginning of MarkBasePos subtable */
UINT16 classCount; /* Number of classes defined for marks */
HBUINT16 classCount; /* Number of classes defined for marks */
OffsetTo<MarkArray>
markArray; /* Offset to MarkArray table--from
* beginning of MarkBasePos subtable */
@ -1132,7 +1132,7 @@ struct MarkBasePos
protected:
union {
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
MarkBasePosFormat1 format1;
} u;
};
@ -1162,7 +1162,7 @@ struct MarkLigPosFormat1
return this+markCoverage;
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
@ -1170,7 +1170,7 @@ struct MarkLigPosFormat1
if (likely (mark_index == NOT_COVERED)) return_trace (false);
/* Now we search backwards for a non-mark glyph */
hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
skippy_iter.reset (buffer->idx, 1);
skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
if (!skippy_iter.prev ()) return_trace (false);
@ -1216,7 +1216,7 @@ struct MarkLigPosFormat1
}
protected:
UINT16 format; /* Format identifier--format = 1 */
HBUINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
markCoverage; /* Offset to Mark Coverage table--from
* beginning of MarkLigPos subtable */
@ -1224,7 +1224,7 @@ struct MarkLigPosFormat1
ligatureCoverage; /* Offset to Ligature Coverage
* table--from beginning of MarkLigPos
* subtable */
UINT16 classCount; /* Number of defined mark classes */
HBUINT16 classCount; /* Number of defined mark classes */
OffsetTo<MarkArray>
markArray; /* Offset to MarkArray table--from
* beginning of MarkLigPos subtable */
@ -1250,7 +1250,7 @@ struct MarkLigPos
protected:
union {
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
MarkLigPosFormat1 format1;
} u;
};
@ -1275,7 +1275,7 @@ struct MarkMarkPosFormat1
return this+mark1Coverage;
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
hb_buffer_t *buffer = c->buffer;
@ -1283,7 +1283,7 @@ struct MarkMarkPosFormat1
if (likely (mark1_index == NOT_COVERED)) return_trace (false);
/* now we search backwards for a suitable mark glyph until a non-mark glyph */
hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
skippy_iter.reset (buffer->idx, 1);
skippy_iter.set_lookup_props (c->lookup_props & ~LookupFlag::IgnoreFlags);
if (!skippy_iter.prev ()) return_trace (false);
@ -1330,7 +1330,7 @@ struct MarkMarkPosFormat1
}
protected:
UINT16 format; /* Format identifier--format = 1 */
HBUINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
mark1Coverage; /* Offset to Combining Mark1 Coverage
* table--from beginning of MarkMarkPos
@ -1339,7 +1339,7 @@ struct MarkMarkPosFormat1
mark2Coverage; /* Offset to Combining Mark2 Coverage
* table--from beginning of MarkMarkPos
* subtable */
UINT16 classCount; /* Number of defined mark classes */
HBUINT16 classCount; /* Number of defined mark classes */
OffsetTo<MarkArray>
mark1Array; /* Offset to Mark1Array table--from
* beginning of MarkMarkPos subtable */
@ -1365,7 +1365,7 @@ struct MarkMarkPos
protected:
union {
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
MarkMarkPosFormat1 format1;
} u;
};
@ -1424,7 +1424,7 @@ struct PosLookupSubTable
protected:
union {
UINT16 sub_format;
HBUINT16 sub_format;
SinglePos single;
PairPos pair;
CursivePos cursive;
@ -1450,7 +1450,7 @@ struct PosLookup : Lookup
return false;
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
return_trace (dispatch (c));
@ -1469,7 +1469,7 @@ struct PosLookup : Lookup
dispatch (&c);
}
static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index);
static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
template <typename context_t>
static inline typename context_t::return_t dispatch_recurse_func (context_t *c, unsigned int lookup_index);
@ -1621,7 +1621,7 @@ template <typename context_t>
return l.dispatch (c);
}
/*static*/ inline bool PosLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index)
/*static*/ inline bool PosLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index)
{
const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos);
const PosLookup &l = gpos.get_lookup (lookup_index);

Просмотреть файл

@ -76,7 +76,7 @@ struct SingleSubstFormat1
return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
@ -110,11 +110,11 @@ struct SingleSubstFormat1
}
protected:
UINT16 format; /* Format identifier--format = 1 */
HBUINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of Substitution table */
INT16 deltaGlyphID; /* Add to original GlyphID to get
HBINT16 deltaGlyphID; /* Add to original GlyphID to get
* substitute GlyphID */
public:
DEFINE_SIZE_STATIC (6);
@ -161,7 +161,7 @@ struct SingleSubstFormat2
return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
@ -195,7 +195,7 @@ struct SingleSubstFormat2
}
protected:
UINT16 format; /* Format identifier--format = 2 */
HBUINT16 format; /* Format identifier--format = 2 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of Substitution table */
@ -249,7 +249,7 @@ struct SingleSubst
protected:
union {
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
SingleSubstFormat1 format1;
SingleSubstFormat2 format2;
} u;
@ -272,7 +272,7 @@ struct Sequence
c->output->add_array (substitute.array, substitute.len);
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
unsigned int count = substitute.len;
@ -363,7 +363,7 @@ struct MultipleSubstFormat1
return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
@ -398,7 +398,7 @@ struct MultipleSubstFormat1
}
protected:
UINT16 format; /* Format identifier--format = 1 */
HBUINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of Substitution table */
@ -440,7 +440,7 @@ struct MultipleSubst
protected:
union {
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
MultipleSubstFormat1 format1;
} u;
};
@ -495,7 +495,7 @@ struct AlternateSubstFormat1
return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
@ -548,7 +548,7 @@ struct AlternateSubstFormat1
}
protected:
UINT16 format; /* Format identifier--format = 1 */
HBUINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of Substitution table */
@ -590,7 +590,7 @@ struct AlternateSubst
protected:
union {
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
AlternateSubstFormat1 format1;
} u;
};
@ -628,7 +628,7 @@ struct Ligature
return_trace (true);
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
unsigned int count = component.len;
@ -730,7 +730,7 @@ struct LigatureSet
return_trace (false);
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
unsigned int num_ligs = ligature.len;
@ -821,7 +821,7 @@ struct LigatureSubstFormat1
return_trace (lig_set.would_apply (c));
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
hb_codepoint_t glyph_id = c->buffer->cur().codepoint;
@ -862,7 +862,7 @@ struct LigatureSubstFormat1
}
protected:
UINT16 format; /* Format identifier--format = 1 */
HBUINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of Substitution table */
@ -912,7 +912,7 @@ struct LigatureSubst
protected:
union {
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
LigatureSubstFormat1 format1;
} u;
};
@ -993,7 +993,7 @@ struct ReverseChainSingleSubstFormat1
return_trace (c->len == 1 && (this+coverage).get_coverage (c->glyphs[0]) != NOT_COVERED);
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
if (unlikely (c->nesting_level_left != HB_MAX_NESTING_LEVEL))
@ -1007,11 +1007,11 @@ struct ReverseChainSingleSubstFormat1
unsigned int start_index = 0, end_index = 0;
if (match_backtrack (c,
backtrack.len, (UINT16 *) backtrack.array,
backtrack.len, (HBUINT16 *) backtrack.array,
match_coverage, this,
&start_index) &&
match_lookahead (c,
lookahead.len, (UINT16 *) lookahead.array,
lookahead.len, (HBUINT16 *) lookahead.array,
match_coverage, this,
1, &end_index))
{
@ -1039,7 +1039,7 @@ struct ReverseChainSingleSubstFormat1
}
protected:
UINT16 format; /* Format identifier--format = 1 */
HBUINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of table */
@ -1073,7 +1073,7 @@ struct ReverseChainSingleSubst
protected:
union {
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
ReverseChainSingleSubstFormat1 format1;
} u;
};
@ -1119,7 +1119,7 @@ struct SubstLookupSubTable
protected:
union {
UINT16 sub_format;
HBUINT16 sub_format;
SingleSubst single;
MultipleSubst multiple;
AlternateSubst alternate;
@ -1150,7 +1150,7 @@ struct SubstLookup : Lookup
return lookup_type_is_reverse (type);
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
return_trace (dispatch (c));
@ -1186,7 +1186,7 @@ struct SubstLookup : Lookup
return_trace (dispatch (c));
}
static bool apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index);
static bool apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index);
inline SubstLookupSubTable& serialize_subtable (hb_serialize_context_t *c,
unsigned int i)
@ -1272,10 +1272,9 @@ struct SubstLookup : Lookup
{
/* The spec says all subtables of an Extension lookup should
* have the same type, which shall not be the Extension type
* itself. This is specially important if one has a reverse type! */
* itself (but we already checked for that).
* This is specially important if one has a reverse type! */
unsigned int type = get_subtable (0).u.extension.get_type ();
if (unlikely (type == SubstLookupSubTable::Extension))
return_trace (false);
unsigned int count = get_subtable_count ();
for (unsigned int i = 1; i < count; i++)
if (get_subtable (i).u.extension.get_type () != type)
@ -1344,7 +1343,7 @@ template <typename context_t>
return l.dispatch (c);
}
/*static*/ inline bool SubstLookup::apply_recurse_func (hb_apply_context_t *c, unsigned int lookup_index)
/*static*/ inline bool SubstLookup::apply_recurse_func (hb_ot_apply_context_t *c, unsigned int lookup_index)
{
const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub);
const SubstLookup &l = gsub.get_lookup (lookup_index);

Просмотреть файл

@ -218,8 +218,8 @@ struct hb_add_coverage_context_t :
};
struct hb_apply_context_t :
hb_dispatch_context_t<hb_apply_context_t, bool, HB_DEBUG_APPLY>
struct hb_ot_apply_context_t :
hb_dispatch_context_t<hb_ot_apply_context_t, bool, HB_DEBUG_APPLY>
{
struct matcher_t
{
@ -234,7 +234,7 @@ struct hb_apply_context_t :
match_func (nullptr),
match_data (nullptr) {};
typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const UINT16 &value, const void *data);
typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data);
inline void set_ignore_zwnj (bool ignore_zwnj_) { ignore_zwnj = ignore_zwnj_; }
inline void set_ignore_zwj (bool ignore_zwj_) { ignore_zwj = ignore_zwj_; }
@ -252,7 +252,7 @@ struct hb_apply_context_t :
};
inline may_match_t may_match (const hb_glyph_info_t &info,
const UINT16 *glyph_data) const
const HBUINT16 *glyph_data) const
{
if (!(info.mask & mask) ||
(syllable && syllable != info.syllable ()))
@ -271,7 +271,7 @@ struct hb_apply_context_t :
};
inline may_skip_t
may_skip (const hb_apply_context_t *c,
may_skip (const hb_ot_apply_context_t *c,
const hb_glyph_info_t &info) const
{
if (!c->check_glyph_property (&info, lookup_props))
@ -297,7 +297,7 @@ struct hb_apply_context_t :
struct skipping_iterator_t
{
inline void init (hb_apply_context_t *c_, bool context_match = false)
inline void init (hb_ot_apply_context_t *c_, bool context_match = false)
{
c = c_;
match_glyph_data = nullptr;
@ -315,7 +315,7 @@ struct hb_apply_context_t :
}
inline void set_match_func (matcher_t::match_func_t match_func_,
const void *match_data_,
const UINT16 glyph_data[])
const HBUINT16 glyph_data[])
{
matcher.set_match_func (match_func_, match_data_);
match_glyph_data = glyph_data;
@ -333,8 +333,7 @@ struct hb_apply_context_t :
inline void reject (void) { num_items++; match_glyph_data--; }
inline matcher_t::may_skip_t
may_skip (const hb_apply_context_t *c,
const hb_glyph_info_t &info) const
may_skip (const hb_glyph_info_t &info) const
{
return matcher.may_skip (c, info);
}
@ -396,9 +395,9 @@ struct hb_apply_context_t :
unsigned int idx;
protected:
hb_apply_context_t *c;
hb_ot_apply_context_t *c;
matcher_t matcher;
const UINT16 *match_glyph_data;
const HBUINT16 *match_glyph_data;
unsigned int num_items;
unsigned int end;
@ -406,18 +405,18 @@ struct hb_apply_context_t :
inline const char *get_name (void) { return "APPLY"; }
typedef return_t (*recurse_func_t) (hb_apply_context_t *c, unsigned int lookup_index);
typedef return_t (*recurse_func_t) (hb_ot_apply_context_t *c, unsigned int lookup_index);
template <typename T>
inline return_t dispatch (const T &obj) { return obj.apply (this); }
static return_t default_return_value (void) { return false; }
bool stop_sublookup_iteration (return_t r) const { return r; }
return_t recurse (unsigned int lookup_index)
return_t recurse (unsigned int sub_lookup_index)
{
if (unlikely (nesting_level_left == 0 || !recurse_func || buffer->max_ops-- <= 0))
return default_return_value ();
nesting_level_left--;
bool ret = recurse_func (this, lookup_index);
bool ret = recurse_func (this, sub_lookup_index);
nesting_level_left++;
return ret;
}
@ -444,7 +443,7 @@ struct hb_apply_context_t :
bool has_glyph_classes;
hb_apply_context_t (unsigned int table_index_,
hb_ot_apply_context_t (unsigned int table_index_,
hb_font_t *font_,
hb_buffer_t *buffer_) :
iter_input (), iter_context (),
@ -568,9 +567,9 @@ struct hb_apply_context_t :
typedef bool (*intersects_func_t) (hb_set_t *glyphs, const UINT16 &value, const void *data);
typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const UINT16 &value, const void *data);
typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const UINT16 &value, const void *data);
typedef bool (*intersects_func_t) (hb_set_t *glyphs, const HBUINT16 &value, const void *data);
typedef void (*collect_glyphs_func_t) (hb_set_t *glyphs, const HBUINT16 &value, const void *data);
typedef bool (*match_func_t) (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data);
struct ContextClosureFuncs
{
@ -586,16 +585,16 @@ struct ContextApplyFuncs
};
static inline bool intersects_glyph (hb_set_t *glyphs, const UINT16 &value, const void *data HB_UNUSED)
static inline bool intersects_glyph (hb_set_t *glyphs, const HBUINT16 &value, const void *data HB_UNUSED)
{
return glyphs->has (value);
}
static inline bool intersects_class (hb_set_t *glyphs, const UINT16 &value, const void *data)
static inline bool intersects_class (hb_set_t *glyphs, const HBUINT16 &value, const void *data)
{
const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
return class_def.intersects_class (glyphs, value);
}
static inline bool intersects_coverage (hb_set_t *glyphs, const UINT16 &value, const void *data)
static inline bool intersects_coverage (hb_set_t *glyphs, const HBUINT16 &value, const void *data)
{
const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
return (data+coverage).intersects (glyphs);
@ -603,7 +602,7 @@ static inline bool intersects_coverage (hb_set_t *glyphs, const UINT16 &value, c
static inline bool intersects_array (hb_closure_context_t *c,
unsigned int count,
const UINT16 values[],
const HBUINT16 values[],
intersects_func_t intersects_func,
const void *intersects_data)
{
@ -614,16 +613,16 @@ static inline bool intersects_array (hb_closure_context_t *c,
}
static inline void collect_glyph (hb_set_t *glyphs, const UINT16 &value, const void *data HB_UNUSED)
static inline void collect_glyph (hb_set_t *glyphs, const HBUINT16 &value, const void *data HB_UNUSED)
{
glyphs->add (value);
}
static inline void collect_class (hb_set_t *glyphs, const UINT16 &value, const void *data)
static inline void collect_class (hb_set_t *glyphs, const HBUINT16 &value, const void *data)
{
const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
class_def.add_class (glyphs, value);
}
static inline void collect_coverage (hb_set_t *glyphs, const UINT16 &value, const void *data)
static inline void collect_coverage (hb_set_t *glyphs, const HBUINT16 &value, const void *data)
{
const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
(data+coverage).add_coverage (glyphs);
@ -631,7 +630,7 @@ static inline void collect_coverage (hb_set_t *glyphs, const UINT16 &value, cons
static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED,
hb_set_t *glyphs,
unsigned int count,
const UINT16 values[],
const HBUINT16 values[],
collect_glyphs_func_t collect_func,
const void *collect_data)
{
@ -640,16 +639,16 @@ static inline void collect_array (hb_collect_glyphs_context_t *c HB_UNUSED,
}
static inline bool match_glyph (hb_codepoint_t glyph_id, const UINT16 &value, const void *data HB_UNUSED)
static inline bool match_glyph (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data HB_UNUSED)
{
return glyph_id == value;
}
static inline bool match_class (hb_codepoint_t glyph_id, const UINT16 &value, const void *data)
static inline bool match_class (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data)
{
const ClassDef &class_def = *reinterpret_cast<const ClassDef *>(data);
return class_def.get_class (glyph_id) == value;
}
static inline bool match_coverage (hb_codepoint_t glyph_id, const UINT16 &value, const void *data)
static inline bool match_coverage (hb_codepoint_t glyph_id, const HBUINT16 &value, const void *data)
{
const OffsetTo<Coverage> &coverage = (const OffsetTo<Coverage>&)value;
return (data+coverage).get_coverage (glyph_id) != NOT_COVERED;
@ -657,7 +656,7 @@ static inline bool match_coverage (hb_codepoint_t glyph_id, const UINT16 &value,
static inline bool would_match_input (hb_would_apply_context_t *c,
unsigned int count, /* Including the first glyph (not matched) */
const UINT16 input[], /* Array of input values--start with second glyph */
const HBUINT16 input[], /* Array of input values--start with second glyph */
match_func_t match_func,
const void *match_data)
{
@ -670,9 +669,9 @@ static inline bool would_match_input (hb_would_apply_context_t *c,
return true;
}
static inline bool match_input (hb_apply_context_t *c,
static inline bool match_input (hb_ot_apply_context_t *c,
unsigned int count, /* Including the first glyph (not matched) */
const UINT16 input[], /* Array of input values--start with second glyph */
const HBUINT16 input[], /* Array of input values--start with second glyph */
match_func_t match_func,
const void *match_data,
unsigned int *end_offset,
@ -686,7 +685,7 @@ static inline bool match_input (hb_apply_context_t *c,
hb_buffer_t *buffer = c->buffer;
hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
skippy_iter.reset (buffer->idx, count - 1);
skippy_iter.set_match_func (match_func, match_data, input);
@ -763,7 +762,7 @@ static inline bool match_input (hb_apply_context_t *c,
j--;
}
if (found && skippy_iter.may_skip (c, out[j]) == hb_apply_context_t::matcher_t::SKIP_YES)
if (found && skippy_iter.may_skip (out[j]) == hb_ot_apply_context_t::matcher_t::SKIP_YES)
ligbase = LIGBASE_MAY_SKIP;
else
ligbase = LIGBASE_MAY_NOT_SKIP;
@ -796,7 +795,7 @@ static inline bool match_input (hb_apply_context_t *c,
return_trace (true);
}
static inline bool ligate_input (hb_apply_context_t *c,
static inline bool ligate_input (hb_ot_apply_context_t *c,
unsigned int count, /* Including the first glyph */
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */
unsigned int match_length,
@ -894,16 +893,16 @@ static inline bool ligate_input (hb_apply_context_t *c,
return_trace (true);
}
static inline bool match_backtrack (hb_apply_context_t *c,
static inline bool match_backtrack (hb_ot_apply_context_t *c,
unsigned int count,
const UINT16 backtrack[],
const HBUINT16 backtrack[],
match_func_t match_func,
const void *match_data,
unsigned int *match_start)
{
TRACE_APPLY (nullptr);
hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
skippy_iter.reset (c->buffer->backtrack_len (), count);
skippy_iter.set_match_func (match_func, match_data, backtrack);
@ -916,9 +915,9 @@ static inline bool match_backtrack (hb_apply_context_t *c,
return_trace (true);
}
static inline bool match_lookahead (hb_apply_context_t *c,
static inline bool match_lookahead (hb_ot_apply_context_t *c,
unsigned int count,
const UINT16 lookahead[],
const HBUINT16 lookahead[],
match_func_t match_func,
const void *match_data,
unsigned int offset,
@ -926,7 +925,7 @@ static inline bool match_lookahead (hb_apply_context_t *c,
{
TRACE_APPLY (nullptr);
hb_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_context;
skippy_iter.reset (c->buffer->idx + offset - 1, count);
skippy_iter.set_match_func (match_func, match_data, lookahead);
@ -949,9 +948,9 @@ struct LookupRecord
return_trace (c->check_struct (this));
}
UINT16 sequenceIndex; /* Index into current glyph
HBUINT16 sequenceIndex; /* Index into current glyph
* sequence--first glyph = 0 */
UINT16 lookupListIndex; /* Lookup to apply to that
HBUINT16 lookupListIndex; /* Lookup to apply to that
* position--zero--based */
public:
DEFINE_SIZE_STATIC (4);
@ -967,7 +966,7 @@ static inline void recurse_lookups (context_t *c,
c->recurse (lookupRecord[i].lookupListIndex);
}
static inline bool apply_lookup (hb_apply_context_t *c,
static inline bool apply_lookup (hb_ot_apply_context_t *c,
unsigned int count, /* Including the first glyph */
unsigned int match_positions[HB_MAX_CONTEXT_LENGTH], /* Including the first glyph */
unsigned int lookupCount,
@ -1112,7 +1111,7 @@ struct ContextApplyLookupContext
static inline void context_closure_lookup (hb_closure_context_t *c,
unsigned int inputCount, /* Including the first glyph (not matched) */
const UINT16 input[], /* Array of input values--start with second glyph */
const HBUINT16 input[], /* Array of input values--start with second glyph */
unsigned int lookupCount,
const LookupRecord lookupRecord[],
ContextClosureLookupContext &lookup_context)
@ -1126,7 +1125,7 @@ static inline void context_closure_lookup (hb_closure_context_t *c,
static inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c,
unsigned int inputCount, /* Including the first glyph (not matched) */
const UINT16 input[], /* Array of input values--start with second glyph */
const HBUINT16 input[], /* Array of input values--start with second glyph */
unsigned int lookupCount,
const LookupRecord lookupRecord[],
ContextCollectGlyphsLookupContext &lookup_context)
@ -1140,7 +1139,7 @@ static inline void context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c
static inline bool context_would_apply_lookup (hb_would_apply_context_t *c,
unsigned int inputCount, /* Including the first glyph (not matched) */
const UINT16 input[], /* Array of input values--start with second glyph */
const HBUINT16 input[], /* Array of input values--start with second glyph */
unsigned int lookupCount HB_UNUSED,
const LookupRecord lookupRecord[] HB_UNUSED,
ContextApplyLookupContext &lookup_context)
@ -1149,9 +1148,9 @@ static inline bool context_would_apply_lookup (hb_would_apply_context_t *c,
inputCount, input,
lookup_context.funcs.match, lookup_context.match_data);
}
static inline bool context_apply_lookup (hb_apply_context_t *c,
static inline bool context_apply_lookup (hb_ot_apply_context_t *c,
unsigned int inputCount, /* Including the first glyph (not matched) */
const UINT16 input[], /* Array of input values--start with second glyph */
const HBUINT16 input[], /* Array of input values--start with second glyph */
unsigned int lookupCount,
const LookupRecord lookupRecord[],
ContextApplyLookupContext &lookup_context)
@ -1198,7 +1197,7 @@ struct Rule
return_trace (context_would_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context));
}
inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
inline bool apply (hb_ot_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
{
TRACE_APPLY (this);
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
@ -1217,11 +1216,11 @@ struct Rule
}
protected:
UINT16 inputCount; /* Total number of glyphs in input
HBUINT16 inputCount; /* Total number of glyphs in input
* glyph sequence--includes the first
* glyph */
UINT16 lookupCount; /* Number of LookupRecords */
UINT16 inputZ[VAR]; /* Array of match inputs--start with
HBUINT16 lookupCount; /* Number of LookupRecords */
HBUINT16 inputZ[VAR]; /* Array of match inputs--start with
* second glyph */
LookupRecord lookupRecordX[VAR]; /* Array of LookupRecords--in
* design order */
@ -1259,7 +1258,7 @@ struct RuleSet
return_trace (false);
}
inline bool apply (hb_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
inline bool apply (hb_ot_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
{
TRACE_APPLY (this);
unsigned int num_rules = rule.len;
@ -1339,7 +1338,7 @@ struct ContextFormat1
return this+coverage;
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
@ -1361,7 +1360,7 @@ struct ContextFormat1
}
protected:
UINT16 format; /* Format identifier--format = 1 */
HBUINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of table */
@ -1431,7 +1430,7 @@ struct ContextFormat2
return this+coverage;
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
@ -1454,7 +1453,7 @@ struct ContextFormat2
}
protected:
UINT16 format; /* Format identifier--format = 2 */
HBUINT16 format; /* Format identifier--format = 2 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of table */
@ -1483,7 +1482,7 @@ struct ContextFormat3
this
};
context_closure_lookup (c,
glyphCount, (const UINT16 *) (coverageZ + 1),
glyphCount, (const HBUINT16 *) (coverageZ + 1),
lookupCount, lookupRecord,
lookup_context);
}
@ -1500,7 +1499,7 @@ struct ContextFormat3
};
context_collect_glyphs_lookup (c,
glyphCount, (const UINT16 *) (coverageZ + 1),
glyphCount, (const HBUINT16 *) (coverageZ + 1),
lookupCount, lookupRecord,
lookup_context);
}
@ -1514,7 +1513,7 @@ struct ContextFormat3
{match_coverage},
this
};
return_trace (context_would_apply_lookup (c, glyphCount, (const UINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
return_trace (context_would_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
}
inline const Coverage &get_coverage (void) const
@ -1522,7 +1521,7 @@ struct ContextFormat3
return this+coverageZ[0];
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint);
@ -1533,7 +1532,7 @@ struct ContextFormat3
{match_coverage},
this
};
return_trace (context_apply_lookup (c, glyphCount, (const UINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
return_trace (context_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
}
inline bool sanitize (hb_sanitize_context_t *c) const
@ -1550,10 +1549,10 @@ struct ContextFormat3
}
protected:
UINT16 format; /* Format identifier--format = 3 */
UINT16 glyphCount; /* Number of glyphs in the input glyph
HBUINT16 format; /* Format identifier--format = 3 */
HBUINT16 glyphCount; /* Number of glyphs in the input glyph
* sequence */
UINT16 lookupCount; /* Number of LookupRecords */
HBUINT16 lookupCount; /* Number of LookupRecords */
OffsetTo<Coverage>
coverageZ[VAR]; /* Array of offsets to Coverage
* table in glyph sequence order */
@ -1580,7 +1579,7 @@ struct Context
protected:
union {
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
ContextFormat1 format1;
ContextFormat2 format2;
ContextFormat3 format3;
@ -1610,11 +1609,11 @@ struct ChainContextApplyLookupContext
static inline void chain_context_closure_lookup (hb_closure_context_t *c,
unsigned int backtrackCount,
const UINT16 backtrack[],
const HBUINT16 backtrack[],
unsigned int inputCount, /* Including the first glyph (not matched) */
const UINT16 input[], /* Array of input values--start with second glyph */
const HBUINT16 input[], /* Array of input values--start with second glyph */
unsigned int lookaheadCount,
const UINT16 lookahead[],
const HBUINT16 lookahead[],
unsigned int lookupCount,
const LookupRecord lookupRecord[],
ChainContextClosureLookupContext &lookup_context)
@ -1634,11 +1633,11 @@ static inline void chain_context_closure_lookup (hb_closure_context_t *c,
static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c,
unsigned int backtrackCount,
const UINT16 backtrack[],
const HBUINT16 backtrack[],
unsigned int inputCount, /* Including the first glyph (not matched) */
const UINT16 input[], /* Array of input values--start with second glyph */
const HBUINT16 input[], /* Array of input values--start with second glyph */
unsigned int lookaheadCount,
const UINT16 lookahead[],
const HBUINT16 lookahead[],
unsigned int lookupCount,
const LookupRecord lookupRecord[],
ChainContextCollectGlyphsLookupContext &lookup_context)
@ -1658,11 +1657,11 @@ static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_contex
static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c,
unsigned int backtrackCount,
const UINT16 backtrack[] HB_UNUSED,
const HBUINT16 backtrack[] HB_UNUSED,
unsigned int inputCount, /* Including the first glyph (not matched) */
const UINT16 input[], /* Array of input values--start with second glyph */
const HBUINT16 input[], /* Array of input values--start with second glyph */
unsigned int lookaheadCount,
const UINT16 lookahead[] HB_UNUSED,
const HBUINT16 lookahead[] HB_UNUSED,
unsigned int lookupCount HB_UNUSED,
const LookupRecord lookupRecord[] HB_UNUSED,
ChainContextApplyLookupContext &lookup_context)
@ -1673,13 +1672,13 @@ static inline bool chain_context_would_apply_lookup (hb_would_apply_context_t *c
lookup_context.funcs.match, lookup_context.match_data[1]);
}
static inline bool chain_context_apply_lookup (hb_apply_context_t *c,
static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c,
unsigned int backtrackCount,
const UINT16 backtrack[],
const HBUINT16 backtrack[],
unsigned int inputCount, /* Including the first glyph (not matched) */
const UINT16 input[], /* Array of input values--start with second glyph */
const HBUINT16 input[], /* Array of input values--start with second glyph */
unsigned int lookaheadCount,
const UINT16 lookahead[],
const HBUINT16 lookahead[],
unsigned int lookupCount,
const LookupRecord lookupRecord[],
ChainContextApplyLookupContext &lookup_context)
@ -1710,8 +1709,8 @@ struct ChainRule
inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
{
TRACE_CLOSURE (this);
const HeadlessArrayOf<UINT16> &input = StructAfter<HeadlessArrayOf<UINT16> > (backtrack);
const ArrayOf<UINT16> &lookahead = StructAfter<ArrayOf<UINT16> > (input);
const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
chain_context_closure_lookup (c,
backtrack.len, backtrack.array,
@ -1724,8 +1723,8 @@ struct ChainRule
inline void collect_glyphs (hb_collect_glyphs_context_t *c, ChainContextCollectGlyphsLookupContext &lookup_context) const
{
TRACE_COLLECT_GLYPHS (this);
const HeadlessArrayOf<UINT16> &input = StructAfter<HeadlessArrayOf<UINT16> > (backtrack);
const ArrayOf<UINT16> &lookahead = StructAfter<ArrayOf<UINT16> > (input);
const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
chain_context_collect_glyphs_lookup (c,
backtrack.len, backtrack.array,
@ -1738,8 +1737,8 @@ struct ChainRule
inline bool would_apply (hb_would_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
{
TRACE_WOULD_APPLY (this);
const HeadlessArrayOf<UINT16> &input = StructAfter<HeadlessArrayOf<UINT16> > (backtrack);
const ArrayOf<UINT16> &lookahead = StructAfter<ArrayOf<UINT16> > (input);
const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
return_trace (chain_context_would_apply_lookup (c,
backtrack.len, backtrack.array,
@ -1748,11 +1747,11 @@ struct ChainRule
lookup.array, lookup_context));
}
inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
inline bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
{
TRACE_APPLY (this);
const HeadlessArrayOf<UINT16> &input = StructAfter<HeadlessArrayOf<UINT16> > (backtrack);
const ArrayOf<UINT16> &lookahead = StructAfter<ArrayOf<UINT16> > (input);
const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
return_trace (chain_context_apply_lookup (c,
backtrack.len, backtrack.array,
@ -1765,23 +1764,23 @@ struct ChainRule
{
TRACE_SANITIZE (this);
if (!backtrack.sanitize (c)) return_trace (false);
const HeadlessArrayOf<UINT16> &input = StructAfter<HeadlessArrayOf<UINT16> > (backtrack);
const HeadlessArrayOf<HBUINT16> &input = StructAfter<HeadlessArrayOf<HBUINT16> > (backtrack);
if (!input.sanitize (c)) return_trace (false);
const ArrayOf<UINT16> &lookahead = StructAfter<ArrayOf<UINT16> > (input);
const ArrayOf<HBUINT16> &lookahead = StructAfter<ArrayOf<HBUINT16> > (input);
if (!lookahead.sanitize (c)) return_trace (false);
const ArrayOf<LookupRecord> &lookup = StructAfter<ArrayOf<LookupRecord> > (lookahead);
return_trace (lookup.sanitize (c));
}
protected:
ArrayOf<UINT16>
ArrayOf<HBUINT16>
backtrack; /* Array of backtracking values
* (to be matched before the input
* sequence) */
HeadlessArrayOf<UINT16>
HeadlessArrayOf<HBUINT16>
inputX; /* Array of input values (start with
* second glyph) */
ArrayOf<UINT16>
ArrayOf<HBUINT16>
lookaheadX; /* Array of lookahead values's (to be
* matched after the input sequence) */
ArrayOf<LookupRecord>
@ -1820,7 +1819,7 @@ struct ChainRuleSet
return_trace (false);
}
inline bool apply (hb_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
inline bool apply (hb_ot_apply_context_t *c, ChainContextApplyLookupContext &lookup_context) const
{
TRACE_APPLY (this);
unsigned int num_rules = rule.len;
@ -1897,7 +1896,7 @@ struct ChainContextFormat1
return this+coverage;
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
@ -1918,7 +1917,7 @@ struct ChainContextFormat1
}
protected:
UINT16 format; /* Format identifier--format = 1 */
HBUINT16 format; /* Format identifier--format = 1 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of table */
@ -2001,7 +2000,7 @@ struct ChainContextFormat2
return this+coverage;
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
@ -2033,7 +2032,7 @@ struct ChainContextFormat2
}
protected:
UINT16 format; /* Format identifier--format = 2 */
HBUINT16 format; /* Format identifier--format = 2 */
OffsetTo<Coverage>
coverage; /* Offset to Coverage table--from
* beginning of table */
@ -2073,9 +2072,9 @@ struct ChainContextFormat3
{this, this, this}
};
chain_context_closure_lookup (c,
backtrack.len, (const UINT16 *) backtrack.array,
input.len, (const UINT16 *) input.array + 1,
lookahead.len, (const UINT16 *) lookahead.array,
backtrack.len, (const HBUINT16 *) backtrack.array,
input.len, (const HBUINT16 *) input.array + 1,
lookahead.len, (const HBUINT16 *) lookahead.array,
lookup.len, lookup.array,
lookup_context);
}
@ -2094,9 +2093,9 @@ struct ChainContextFormat3
{this, this, this}
};
chain_context_collect_glyphs_lookup (c,
backtrack.len, (const UINT16 *) backtrack.array,
input.len, (const UINT16 *) input.array + 1,
lookahead.len, (const UINT16 *) lookahead.array,
backtrack.len, (const HBUINT16 *) backtrack.array,
input.len, (const HBUINT16 *) input.array + 1,
lookahead.len, (const HBUINT16 *) lookahead.array,
lookup.len, lookup.array,
lookup_context);
}
@ -2113,9 +2112,9 @@ struct ChainContextFormat3
{this, this, this}
};
return_trace (chain_context_would_apply_lookup (c,
backtrack.len, (const UINT16 *) backtrack.array,
input.len, (const UINT16 *) input.array + 1,
lookahead.len, (const UINT16 *) lookahead.array,
backtrack.len, (const HBUINT16 *) backtrack.array,
input.len, (const HBUINT16 *) input.array + 1,
lookahead.len, (const HBUINT16 *) lookahead.array,
lookup.len, lookup.array, lookup_context));
}
@ -2125,7 +2124,7 @@ struct ChainContextFormat3
return this+input[0];
}
inline bool apply (hb_apply_context_t *c) const
inline bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
const OffsetArrayOf<Coverage> &input = StructAfter<OffsetArrayOf<Coverage> > (backtrack);
@ -2140,9 +2139,9 @@ struct ChainContextFormat3
{this, this, this}
};
return_trace (chain_context_apply_lookup (c,
backtrack.len, (const UINT16 *) backtrack.array,
input.len, (const UINT16 *) input.array + 1,
lookahead.len, (const UINT16 *) lookahead.array,
backtrack.len, (const HBUINT16 *) backtrack.array,
input.len, (const HBUINT16 *) input.array + 1,
lookahead.len, (const HBUINT16 *) lookahead.array,
lookup.len, lookup.array, lookup_context));
}
@ -2160,7 +2159,7 @@ struct ChainContextFormat3
}
protected:
UINT16 format; /* Format identifier--format = 3 */
HBUINT16 format; /* Format identifier--format = 3 */
OffsetArrayOf<Coverage>
backtrack; /* Array of coverage tables
* in backtracking sequence, in glyph
@ -2197,7 +2196,7 @@ struct ChainContext
protected:
union {
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
ChainContextFormat1 format1;
ChainContextFormat2 format2;
ChainContextFormat3 format3;
@ -2230,15 +2229,17 @@ struct ExtensionFormat1
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && extensionOffset != 0);
return_trace (c->check_struct (this) &&
extensionOffset != 0 &&
extensionLookupType != T::LookupSubTable::Extension);
}
protected:
UINT16 format; /* Format identifier. Set to 1. */
UINT16 extensionLookupType; /* Lookup type of subtable referenced
HBUINT16 format; /* Format identifier. Set to 1. */
HBUINT16 extensionLookupType; /* Lookup type of subtable referenced
* by ExtensionOffset (i.e. the
* extension subtable). */
UINT32 extensionOffset; /* Offset to the extension subtable,
HBUINT32 extensionOffset; /* Offset to the extension subtable,
* of lookup type subtable. */
public:
DEFINE_SIZE_STATIC (8);
@ -2276,7 +2277,7 @@ struct Extension
protected:
union {
UINT16 format; /* Format identifier */
HBUINT16 format; /* Format identifier */
ExtensionFormat1<T> format1;
} u;
};

Просмотреть файл

@ -90,12 +90,12 @@ hb_ot_layout_substitute_start (hb_font_t *font,
struct hb_ot_layout_lookup_accelerator_t;
namespace OT {
struct hb_apply_context_t;
struct hb_ot_apply_context_t;
struct SubstLookup;
}
HB_INTERNAL void
hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c,
hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
const OT::SubstLookup &lookup,
const hb_ot_layout_lookup_accelerator_t &accel);
@ -130,6 +130,10 @@ namespace OT {
struct avar;
}
namespace AAT {
struct morx;
}
struct hb_ot_layout_lookup_accelerator_t
{
template <typename TLookup>
@ -165,6 +169,7 @@ struct hb_ot_layout_t
OT::hb_lazy_table_loader_t<struct OT::MATH> math;
OT::hb_lazy_table_loader_t<struct OT::fvar> fvar;
OT::hb_lazy_table_loader_t<struct OT::avar> avar;
OT::hb_lazy_table_loader_t<struct AAT::morx> morx;
unsigned int gsub_lookup_count;
unsigned int gpos_lookup_count;
@ -280,7 +285,11 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer)
else if (unlikely (hb_in_range (u, 0xE0020u, 0xE007Fu))) props |= UPROPS_MASK_HIDDEN;
/* COMBINING GRAPHEME JOINER should not be skipped; at least some times.
* https://github.com/harfbuzz/harfbuzz/issues/554 */
else if (unlikely (u == 0x034Fu)) props |= UPROPS_MASK_HIDDEN;
else if (unlikely (u == 0x034Fu))
{
buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_CGJ;
props |= UPROPS_MASK_HIDDEN;
}
}
else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK_OR_MODIFIER_SYMBOL (gen_cat)))
{
@ -388,6 +397,11 @@ _hb_glyph_info_is_default_ignorable_and_not_hidden (const hb_glyph_info_t *info)
== UPROPS_MASK_IGNORABLE) &&
!_hb_glyph_info_ligated (info);
}
static inline void
_hb_glyph_info_unhide (hb_glyph_info_t *info)
{
info->unicode_props() &= ~ UPROPS_MASK_HIDDEN;
}
static inline bool
_hb_glyph_info_is_unicode_format (const hb_glyph_info_t *info)

Просмотреть файл

@ -50,18 +50,19 @@ _hb_ot_layout_create (hb_face_t *face)
if (unlikely (!layout))
return nullptr;
layout->gdef_blob = OT::Sanitizer<OT::GDEF>::sanitize (face->reference_table (HB_OT_TAG_GDEF));
layout->gdef_blob = OT::Sanitizer<OT::GDEF>().sanitize (face->reference_table (HB_OT_TAG_GDEF));
layout->gdef = OT::Sanitizer<OT::GDEF>::lock_instance (layout->gdef_blob);
layout->gsub_blob = OT::Sanitizer<OT::GSUB>::sanitize (face->reference_table (HB_OT_TAG_GSUB));
layout->gsub_blob = OT::Sanitizer<OT::GSUB>().sanitize (face->reference_table (HB_OT_TAG_GSUB));
layout->gsub = OT::Sanitizer<OT::GSUB>::lock_instance (layout->gsub_blob);
layout->gpos_blob = OT::Sanitizer<OT::GPOS>::sanitize (face->reference_table (HB_OT_TAG_GPOS));
layout->gpos_blob = OT::Sanitizer<OT::GPOS>().sanitize (face->reference_table (HB_OT_TAG_GPOS));
layout->gpos = OT::Sanitizer<OT::GPOS>::lock_instance (layout->gpos_blob);
layout->math.init (face);
layout->fvar.init (face);
layout->avar.init (face);
layout->morx.init (face);
{
/*
@ -209,6 +210,7 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout)
layout->math.fini ();
layout->fvar.fini ();
layout->avar.fini ();
layout->morx.fini ();
free (layout);
}
@ -1055,13 +1057,13 @@ struct hb_get_subtables_context_t :
OT::hb_dispatch_context_t<hb_get_subtables_context_t, hb_void_t, HB_DEBUG_APPLY>
{
template <typename Type>
static inline bool apply_to (const void *obj, OT::hb_apply_context_t *c)
static inline bool apply_to (const void *obj, OT::hb_ot_apply_context_t *c)
{
const Type *typed_obj = (const Type *) obj;
return typed_obj->apply (c);
}
typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_apply_context_t *c);
typedef bool (*hb_apply_func_t) (const void *obj, OT::hb_ot_apply_context_t *c);
struct hb_applicable_t
{
@ -1071,7 +1073,7 @@ struct hb_get_subtables_context_t :
apply_func = apply_func_;
}
inline bool apply (OT::hb_apply_context_t *c) const { return apply_func (obj, c); }
inline bool apply (OT::hb_ot_apply_context_t *c) const { return apply_func (obj, c); }
private:
const void *obj;
@ -1102,7 +1104,7 @@ struct hb_get_subtables_context_t :
};
static inline bool
apply_forward (OT::hb_apply_context_t *c,
apply_forward (OT::hb_ot_apply_context_t *c,
const hb_ot_layout_lookup_accelerator_t &accel,
const hb_get_subtables_context_t::array_t &subtables)
{
@ -1132,7 +1134,7 @@ apply_forward (OT::hb_apply_context_t *c,
}
static inline bool
apply_backward (OT::hb_apply_context_t *c,
apply_backward (OT::hb_ot_apply_context_t *c,
const hb_ot_layout_lookup_accelerator_t &accel,
const hb_get_subtables_context_t::array_t &subtables)
{
@ -1161,7 +1163,7 @@ apply_backward (OT::hb_apply_context_t *c,
template <typename Proxy>
static inline void
apply_string (OT::hb_apply_context_t *c,
apply_string (OT::hb_ot_apply_context_t *c,
const typename Proxy::Lookup &lookup,
const hb_ot_layout_lookup_accelerator_t &accel)
{
@ -1212,7 +1214,7 @@ inline void hb_ot_map_t::apply (const Proxy &proxy,
{
const unsigned int table_index = proxy.table_index;
unsigned int i = 0;
OT::hb_apply_context_t c (table_index, font, buffer);
OT::hb_ot_apply_context_t c (table_index, font, buffer);
c.set_recurse_func (Proxy::Lookup::apply_recurse_func);
for (unsigned int stage_index = 0; stage_index < stages[table_index].len; stage_index++) {
@ -1252,7 +1254,7 @@ void hb_ot_map_t::position (const hb_ot_shape_plan_t *plan, hb_font_t *font, hb_
}
HB_INTERNAL void
hb_ot_layout_substitute_lookup (OT::hb_apply_context_t *c,
hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
const OT::SubstLookup &lookup,
const hb_ot_layout_lookup_accelerator_t &accel)
{

Просмотреть файл

@ -198,7 +198,6 @@ struct hb_ot_map_builder_t
private:
HB_INTERNAL void add_lookups (hb_ot_map_t &m,
hb_face_t *face,
unsigned int table_index,
unsigned int feature_index,
unsigned int variations_index,

Просмотреть файл

@ -80,7 +80,6 @@ void hb_ot_map_builder_t::add_feature (hb_tag_t tag, unsigned int value,
void
hb_ot_map_builder_t::add_lookups (hb_ot_map_t &m,
hb_face_t *face,
unsigned int table_index,
unsigned int feature_index,
unsigned int variations_index,
@ -289,14 +288,14 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
{
if (required_feature_index[table_index] != HB_OT_LAYOUT_NO_FEATURE_INDEX &&
required_feature_stage[table_index] == stage)
add_lookups (m, face, table_index,
add_lookups (m, table_index,
required_feature_index[table_index],
variations_index,
global_bit_mask);
for (unsigned i = 0; i < m.features.len; i++)
if (m.features[i].stage[table_index] == stage)
add_lookups (m, face, table_index,
add_lookups (m, table_index,
m.features[i].index[table_index],
variations_index,
m.features[i].mask,

Просмотреть файл

@ -48,7 +48,7 @@ struct MathValueRecord
}
protected:
INT16 value; /* The X or Y value in design units */
HBINT16 value; /* The X or Y value in design units */
OffsetTo<Device> deviceTable; /* Offset to the device table - from the
* beginning of parent table. May be nullptr.
* Suggested format for device table is 1. */
@ -154,10 +154,10 @@ struct MathConstants
}
protected:
INT16 percentScaleDown[2];
UINT16 minHeight[2];
HBINT16 percentScaleDown[2];
HBUINT16 minHeight[2];
MathValueRecord mathValueRecords[51];
INT16 radicalDegreeBottomRaisePercent;
HBINT16 radicalDegreeBottomRaisePercent;
public:
DEFINE_SIZE_STATIC (214);
@ -279,7 +279,7 @@ struct MathKern
}
protected:
UINT16 heightCount;
HBUINT16 heightCount;
MathValueRecord mathValueRecords[VAR]; /* Array of correction heights at
* which the kern value changes.
* Sorted by the height value in
@ -425,7 +425,7 @@ struct MathGlyphVariantRecord
protected:
GlyphID variantGlyph; /* Glyph ID for the variant. */
UINT16 advanceMeasurement; /* Advance width/height, in design units, of the
HBUINT16 advanceMeasurement; /* Advance width/height, in design units, of the
* variant, in the direction of requested
* glyph extension. */
@ -433,7 +433,7 @@ struct MathGlyphVariantRecord
DEFINE_SIZE_STATIC (4);
};
struct PartFlags : UINT16
struct PartFlags : HBUINT16
{
enum Flags {
Extender = 0x0001u, /* If set, the part can be skipped or repeated. */
@ -473,15 +473,15 @@ struct MathGlyphPartRecord
protected:
GlyphID glyph; /* Glyph ID for the part. */
UINT16 startConnectorLength; /* Advance width/ height of the straight bar
HBUINT16 startConnectorLength; /* Advance width/ height of the straight bar
* connector material, in design units, is at
* the beginning of the glyph, in the
* direction of the extension. */
UINT16 endConnectorLength; /* Advance width/ height of the straight bar
HBUINT16 endConnectorLength; /* Advance width/ height of the straight bar
* connector material, in design units, is at
* the end of the glyph, in the direction of
* the extension. */
UINT16 fullAdvance; /* Full advance width/height for this part,
HBUINT16 fullAdvance; /* Full advance width/height for this part,
* in the direction of the extension.
* In design units. */
PartFlags partFlags; /* Part qualifiers. */
@ -651,7 +651,7 @@ struct MathVariants
}
protected:
UINT16 minConnectorOverlap; /* Minimum overlap of connecting
HBUINT16 minConnectorOverlap; /* Minimum overlap of connecting
* glyphs during glyph construction,
* in design units. */
OffsetTo<Coverage> vertGlyphCoverage; /* Offset to Coverage table -
@ -660,10 +660,10 @@ struct MathVariants
OffsetTo<Coverage> horizGlyphCoverage; /* Offset to Coverage table -
* from the beginning of MathVariants
* table. */
UINT16 vertGlyphCount; /* Number of glyphs for which
HBUINT16 vertGlyphCount; /* Number of glyphs for which
* information is provided for
* vertically growing variants. */
UINT16 horizGlyphCount; /* Number of glyphs for which
HBUINT16 horizGlyphCount; /* Number of glyphs for which
* information is provided for
* horizontally growing variants. */

Просмотреть файл

@ -60,7 +60,7 @@ struct maxp
protected:
FixedVersion<>version; /* Version of the maxp table (0.5 or 1.0),
* 0x00005000u or 0x00010000u. */
UINT16 numGlyphs; /* The number of glyphs in the font. */
HBUINT16 numGlyphs; /* The number of glyphs in the font. */
public:
DEFINE_SIZE_STATIC (6);
};

Просмотреть файл

@ -65,12 +65,12 @@ struct NameRecord
return_trace (c->check_struct (this) && c->check_range ((char *) base, (unsigned int) length + offset));
}
UINT16 platformID; /* Platform ID. */
UINT16 encodingID; /* Platform-specific encoding ID. */
UINT16 languageID; /* Language ID. */
UINT16 nameID; /* Name ID. */
UINT16 length; /* String length (in bytes). */
UINT16 offset; /* String offset from start of storage area (in bytes). */
HBUINT16 platformID; /* Platform ID. */
HBUINT16 encodingID; /* Platform-specific encoding ID. */
HBUINT16 languageID; /* Language ID. */
HBUINT16 nameID; /* Name ID. */
HBUINT16 length; /* String length (in bytes). */
HBUINT16 offset; /* String offset from start of storage area (in bytes). */
public:
DEFINE_SIZE_STATIC (12);
};
@ -123,8 +123,8 @@ struct name
}
/* We only implement format 0 for now. */
UINT16 format; /* Format selector (=0/1). */
UINT16 count; /* Number of name records. */
HBUINT16 format; /* Format selector (=0/1). */
HBUINT16 count; /* Number of name records. */
Offset16 stringOffset; /* Offset to start of string storage (from start of table). */
NameRecord nameRecord[VAR]; /* The name records where count is the number of records. */
public:

Просмотреть файл

@ -50,50 +50,50 @@ struct os2
}
public:
UINT16 version;
HBUINT16 version;
/* Version 0 */
INT16 xAvgCharWidth;
UINT16 usWeightClass;
UINT16 usWidthClass;
UINT16 fsType;
INT16 ySubscriptXSize;
INT16 ySubscriptYSize;
INT16 ySubscriptXOffset;
INT16 ySubscriptYOffset;
INT16 ySuperscriptXSize;
INT16 ySuperscriptYSize;
INT16 ySuperscriptXOffset;
INT16 ySuperscriptYOffset;
INT16 yStrikeoutSize;
INT16 yStrikeoutPosition;
INT16 sFamilyClass;
UINT8 panose[10];
UINT32 ulUnicodeRange[4];
HBINT16 xAvgCharWidth;
HBUINT16 usWeightClass;
HBUINT16 usWidthClass;
HBUINT16 fsType;
HBINT16 ySubscriptXSize;
HBINT16 ySubscriptYSize;
HBINT16 ySubscriptXOffset;
HBINT16 ySubscriptYOffset;
HBINT16 ySuperscriptXSize;
HBINT16 ySuperscriptYSize;
HBINT16 ySuperscriptXOffset;
HBINT16 ySuperscriptYOffset;
HBINT16 yStrikeoutSize;
HBINT16 yStrikeoutPosition;
HBINT16 sFamilyClass;
HBUINT8 panose[10];
HBUINT32 ulUnicodeRange[4];
Tag achVendID;
UINT16 fsSelection;
UINT16 usFirstCharIndex;
UINT16 usLastCharIndex;
INT16 sTypoAscender;
INT16 sTypoDescender;
INT16 sTypoLineGap;
UINT16 usWinAscent;
UINT16 usWinDescent;
HBUINT16 fsSelection;
HBUINT16 usFirstCharIndex;
HBUINT16 usLastCharIndex;
HBINT16 sTypoAscender;
HBINT16 sTypoDescender;
HBINT16 sTypoLineGap;
HBUINT16 usWinAscent;
HBUINT16 usWinDescent;
/* Version 1 */
//UINT32 ulCodePageRange1;
//UINT32 ulCodePageRange2;
//HBUINT32 ulCodePageRange1;
//HBUINT32 ulCodePageRange2;
/* Version 2 */
//INT16 sxHeight;
//INT16 sCapHeight;
//UINT16 usDefaultChar;
//UINT16 usBreakChar;
//UINT16 usMaxContext;
//HBINT16 sxHeight;
//HBINT16 sCapHeight;
//HBUINT16 usDefaultChar;
//HBUINT16 usBreakChar;
//HBUINT16 usMaxContext;
/* Version 5 */
//UINT16 usLowerOpticalPointSize;
//UINT16 usUpperOpticalPointSize;
//HBUINT16 usLowerOpticalPointSize;
//HBUINT16 usUpperOpticalPointSize;
public:
DEFINE_SIZE_STATIC (78);

Просмотреть файл

@ -56,10 +56,10 @@ struct postV2Tail
return_trace (glyphNameIndex.sanitize (c));
}
ArrayOf<UINT16>glyphNameIndex; /* This is not an offset, but is the
ArrayOf<HBUINT16>glyphNameIndex; /* This is not an offset, but is the
* ordinal number of the glyph in 'post'
* string tables. */
UINT8 namesX[VAR]; /* Glyph names with length bytes [variable]
HBUINT8 namesX[VAR]; /* Glyph names with length bytes [variable]
* (a Pascal string). */
DEFINE_SIZE_ARRAY2 (2, glyphNameIndex, namesX);
@ -86,7 +86,7 @@ struct post
{
inline void init (hb_face_t *face)
{
blob = Sanitizer<post>::sanitize (face->reference_table (HB_OT_TAG_post));
blob = Sanitizer<post>().sanitize (face->reference_table (HB_OT_TAG_post));
const post *table = Sanitizer<post>::lock_instance (blob);
unsigned int table_length = hb_blob_get_length (blob);
@ -234,7 +234,7 @@ struct post
private:
hb_blob_t *blob;
uint32_t version;
const ArrayOf<UINT16> *glyphNameIndex;
const ArrayOf<HBUINT16> *glyphNameIndex;
hb_prealloced_array_t<uint32_t, 1> index_to_offset;
const uint8_t *pool;
mutable uint16_t *gids_sorted_by_name;
@ -261,16 +261,16 @@ struct post
* from the value of this field. */
FWORD underlineThickness; /* Suggested values for the underline
thickness. */
UINT32 isFixedPitch; /* Set to 0 if the font is proportionally
HBUINT32 isFixedPitch; /* Set to 0 if the font is proportionally
* spaced, non-zero if the font is not
* proportionally spaced (i.e. monospaced). */
UINT32 minMemType42; /* Minimum memory usage when an OpenType font
HBUINT32 minMemType42; /* Minimum memory usage when an OpenType font
* is downloaded. */
UINT32 maxMemType42; /* Maximum memory usage when an OpenType font
HBUINT32 maxMemType42; /* Maximum memory usage when an OpenType font
* is downloaded. */
UINT32 minMemType1; /* Minimum memory usage when an OpenType font
HBUINT32 minMemType1; /* Minimum memory usage when an OpenType font
* is downloaded as a Type 1 font. */
UINT32 maxMemType1; /* Maximum memory usage when an OpenType font
HBUINT32 maxMemType1; /* Maximum memory usage when an OpenType font
* is downloaded as a Type 1 font. */
/*postV2Tail v2[VAR];*/
DEFINE_SIZE_STATIC (32);

Просмотреть файл

@ -340,7 +340,7 @@ arabic_fallback_plan_shape (arabic_fallback_plan_t *fallback_plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
OT::hb_apply_context_t c (0, font, buffer);
OT::hb_ot_apply_context_t c (0, font, buffer);
for (unsigned int i = 0; i < fallback_plan->num_lookups; i++)
if (fallback_plan->lookup_array[i]) {
c.set_lookup_mask (fallback_plan->mask_array[i]);

Просмотреть файл

@ -644,13 +644,15 @@ reorder_marks_arabic (const hb_ot_shape_plan_t *plan,
{
hb_glyph_info_t *info = buffer->info;
DEBUG_MSG (ARABIC, buffer, "Reordering marks from %d to %d", start, end);
unsigned int i = start;
for (unsigned int cc = 220; cc <= 230; cc += 10)
{
DEBUG_MSG (ARABIC, buffer, "Looking for %d's starting at %d\n", cc, i);
DEBUG_MSG (ARABIC, buffer, "Looking for %d's starting at %d", cc, i);
while (i < end && info_cc(info[i]) < cc)
i++;
DEBUG_MSG (ARABIC, buffer, "Looking for %d's stopped at %d\n", cc, i);
DEBUG_MSG (ARABIC, buffer, "Looking for %d's stopped at %d", cc, i);
if (i == end)
break;
@ -658,20 +660,17 @@ reorder_marks_arabic (const hb_ot_shape_plan_t *plan,
if (info_cc(info[i]) > cc)
continue;
/* Technically we should also check "info_cc(info[j]) == cc"
* in the following loop. But not doing it is safe; we might
* end up moving all the 220 MCMs and 230 MCMs together in one
* move and be done. */
unsigned int j = i;
while (j < end && info_is_mcm (info[j]))
while (j < end && info_cc(info[j]) == cc && info_is_mcm (info[j]))
j++;
DEBUG_MSG (ARABIC, buffer, "Found %d's from %d to %d\n", cc, i, j);
if (i == j)
continue;
DEBUG_MSG (ARABIC, buffer, "Found %d's from %d to %d", cc, i, j);
/* Shift it! */
DEBUG_MSG (ARABIC, buffer, "Shifting %d's: %d %d\n", cc, i, j);
DEBUG_MSG (ARABIC, buffer, "Shifting %d's: %d %d", cc, i, j);
hb_glyph_info_t temp[HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS];
assert (j - i <= ARRAY_LENGTH (temp));
buffer->merge_clusters (start, j);
@ -679,7 +678,25 @@ reorder_marks_arabic (const hb_ot_shape_plan_t *plan,
memmove (&info[start + j - i], &info[start], (i - start) * sizeof (hb_glyph_info_t));
memmove (&info[start], temp, (j - i) * sizeof (hb_glyph_info_t));
start += j - i;
/* Renumber CC such that the reordered sequence is still sorted.
* 22 and 26 are chosen because they are smaller than all Arabic categories,
* and are folded back to 220/230 respectively during fallback mark positioning.
*
* We do this because the CGJ-handling logic in the normalizer relies on
* mark sequences having an increasing order even after this reordering.
* https://github.com/harfbuzz/harfbuzz/issues/554
* This, however, does break some obscure sequences, where the normalizer
* might compose a sequence that it should not. For example, in the seequence
* ALEF, HAMZAH, MADDAH, we should NOT try to compose ALEF+MADDAH, but with this
* renumbering, we will.
*/
unsigned int new_start = start + j - i;
unsigned int new_cc = cc == 220 ? HB_MODIFIED_COMBINING_CLASS_CCC22 : HB_MODIFIED_COMBINING_CLASS_CCC26;
while (start < new_start)
{
_hb_glyph_info_set_modified_combining_class (&info[start], new_cc);
start++;
}
i = j;
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -38,7 +38,6 @@
%%{
# Same order as enum indic_category_t. Not sure how to avoid duplication.
X = 0;
C = 1;
V = 2;
N = 3;
@ -47,12 +46,10 @@ ZWNJ = 5;
ZWJ = 6;
M = 7;
SM = 8;
VD = 9;
A = 10;
PLACEHOLDER = 11;
DOTTEDCIRCLE = 12;
RS = 13;
Coeng = 14;
Repha = 15;
Ra = 16;
CM = 17;
@ -62,19 +59,17 @@ CS = 19;
c = (C | Ra); # is_consonant
n = ((ZWNJ?.RS)? (N.N?)?); # is_consonant_modifier
z = ZWJ|ZWNJ; # is_joiner
h = H | Coeng; # is_halant_or_coeng
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}? VD{0,2};
place_holder = PLACEHOLDER | DOTTEDCIRCLE;
halant_group = (z?.h.(ZWJ.N?)?);
final_halant_group = halant_group | h.ZWNJ;
syllable_tail = (z?.SM.SM?.ZWNJ?)? A{0,3}?;
halant_group = (z?.H.(ZWJ.N?)?);
final_halant_group = halant_group | H.ZWNJ;
medial_group = CM?;
halant_or_matra_group = (final_halant_group | (h.ZWJ)? matra_group{0,4}) (Coeng (cn|V))?;
halant_or_matra_group = (final_halant_group | (H.ZWJ)? matra_group{0,4});
consonant_syllable = (Repha|CS)? (cn.halant_group){0,4} cn medial_group halant_or_matra_group syllable_tail;

Просмотреть файл

@ -51,7 +51,7 @@ enum indic_category_t {
OT_ZWJ = 6,
OT_M = 7,
OT_SM = 8,
OT_VD = 9,
/* OT_VD = 9, UNUSED; we use OT_A instead. */
OT_A = 10,
OT_PLACEHOLDER = 11,
OT_DOTTEDCIRCLE = 12,
@ -73,7 +73,6 @@ enum indic_category_t {
* consonant syllable logic from the vowel syllable function and get it all right! */
#define CONSONANT_FLAGS (FLAG (OT_C) | FLAG (OT_CS) | FLAG (OT_Ra) | MEDIAL_FLAGS | FLAG (OT_V) | FLAG (OT_PLACEHOLDER) | FLAG (OT_DOTTEDCIRCLE))
#define JOINER_FLAGS (FLAG (OT_ZWJ) | FLAG (OT_ZWNJ))
#define HALANT_OR_COENG_FLAGS (FLAG (OT_H) | FLAG (OT_Coeng))
/* Visual positions in a syllable from left to right. */

Просмотреть файл

@ -399,10 +399,10 @@ hb_indic_get_categories (hb_codepoint_t u)
switch (u >> 12)
{
case 0x0u:
if (unlikely (u == 0x00A0u)) return _(CP,x);
if (hb_in_range<hb_codepoint_t> (u, 0x0028u, 0x003Fu)) return indic_table[u - 0x0028u + indic_offset_0x0028u];
if (hb_in_range<hb_codepoint_t> (u, 0x00B0u, 0x00D7u)) return indic_table[u - 0x00B0u + indic_offset_0x00b0u];
if (hb_in_range<hb_codepoint_t> (u, 0x0900u, 0x0DF7u)) return indic_table[u - 0x0900u + indic_offset_0x0900u];
if (unlikely (u == 0x00A0u)) return _(CP,x);
break;
case 0x1u:
@ -412,9 +412,9 @@ hb_indic_get_categories (hb_codepoint_t u)
break;
case 0x2u:
if (unlikely (u == 0x25CCu)) return _(CP,x);
if (hb_in_range<hb_codepoint_t> (u, 0x2008u, 0x2017u)) return indic_table[u - 0x2008u + indic_offset_0x2008u];
if (hb_in_range<hb_codepoint_t> (u, 0x2070u, 0x2087u)) return indic_table[u - 0x2070u + indic_offset_0x2070u];
if (unlikely (u == 0x25CCu)) return _(CP,x);
break;
case 0xAu:

Просмотреть файл

@ -49,7 +49,6 @@
#define IS_KNDA(u) (IN_HALF_BLOCK (u, 0x0C80u))
#define IS_MLYM(u) (IN_HALF_BLOCK (u, 0x0D00u))
#define IS_SINH(u) (IN_HALF_BLOCK (u, 0x0D80u))
#define IS_KHMR(u) (IN_HALF_BLOCK (u, 0x1780u))
#define MATRA_POS_LEFT(u) POS_PRE_M
@ -64,7 +63,6 @@
IS_KNDA(u) ? (u < 0x0CC3u || u > 0xCD6u ? POS_BEFORE_SUB : POS_AFTER_SUB) : \
IS_MLYM(u) ? POS_AFTER_POST : \
IS_SINH(u) ? POS_AFTER_SUB : \
IS_KHMR(u) ? POS_AFTER_POST : \
/*default*/ POS_AFTER_SUB \
)
#define MATRA_POS_TOP(u) ( /* BENG and MLYM don't have top matras. */ \
@ -76,7 +74,6 @@
IS_TELU(u) ? POS_BEFORE_SUB : \
IS_KNDA(u) ? POS_BEFORE_SUB : \
IS_SINH(u) ? POS_AFTER_SUB : \
IS_KHMR(u) ? POS_AFTER_POST : \
/*default*/ POS_AFTER_SUB \
)
#define MATRA_POS_BOTTOM(u) ( \
@ -90,7 +87,6 @@
IS_KNDA(u) ? POS_BEFORE_SUB : \
IS_MLYM(u) ? POS_AFTER_POST : \
IS_SINH(u) ? POS_AFTER_SUB : \
IS_KHMR(u) ? POS_AFTER_POST : \
/*default*/ POS_AFTER_SUB \
)
@ -124,8 +120,6 @@ static const hb_codepoint_t ra_chars[] = {
0x0D30u, /* Malayalam */ /* No Reph, Logical Repha */
0x0DBBu, /* Sinhala */ /* Reph formed only with ZWJ */
0x179Au, /* Khmer */ /* No Reph, Visual Repha */
};
static inline bool
@ -158,9 +152,9 @@ is_consonant (const hb_glyph_info_t &info)
}
static inline bool
is_halant_or_coeng (const hb_glyph_info_t &info)
is_halant (const hb_glyph_info_t &info)
{
return is_one_of (info, HALANT_OR_COENG_FLAGS);
return is_one_of (info, FLAG (OT_H));
}
static inline void
@ -200,14 +194,6 @@ set_indic_properties (hb_glyph_info_t &info)
cat = OT_Symbol;
static_assert (((int) INDIC_SYLLABIC_CATEGORY_AVAGRAHA == OT_Symbol), "");
}
else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x17CDu, 0x17D1u) ||
u == 0x17CBu || u == 0x17D3u || u == 0x17DDu)) /* Khmer Various signs */
{
/* These can occur mid-syllable (eg. before matras), even though Unicode marks them as Syllable_Modifier.
* https://github.com/roozbehp/unicode-data/issues/5 */
cat = OT_M;
pos = POS_ABOVE_C;
}
else if (unlikely (u == 0x0A51u))
{
/* https://github.com/harfbuzz/harfbuzz/issues/524 */
@ -224,7 +210,6 @@ set_indic_properties (hb_glyph_info_t &info)
else if (unlikely (u == 0x0980u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/issues/538 */
else if (unlikely (u == 0x0C80u)) cat = OT_PLACEHOLDER; /* https://github.com/harfbuzz/harfbuzz/pull/623 */
else if (unlikely (u == 0x17C6u)) cat = OT_N; /* Khmer Bindu doesn't like to be repositioned. */
else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x2010u, 0x2011u)))
cat = OT_PLACEHOLDER;
else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE;
@ -244,7 +229,7 @@ set_indic_properties (hb_glyph_info_t &info)
{
pos = matra_position (u, pos);
}
else if ((FLAG_UNSAFE (cat) & (FLAG (OT_SM) | FLAG (OT_VD) | FLAG (OT_A) | FLAG (OT_Symbol))))
else if ((FLAG_UNSAFE (cat) & (FLAG (OT_SM) /* | FLAG (OT_VD) */ | FLAG (OT_A) | FLAG (OT_Symbol))))
{
pos = POS_SMVD;
}
@ -271,7 +256,6 @@ set_indic_properties (hb_glyph_info_t &info)
*/
enum base_position_t {
BASE_POS_FIRST,
BASE_POS_LAST_SINHALA,
BASE_POS_LAST
};
@ -280,13 +264,11 @@ enum reph_position_t {
REPH_POS_BEFORE_SUB = POS_BEFORE_SUB,
REPH_POS_AFTER_SUB = POS_AFTER_SUB,
REPH_POS_BEFORE_POST = POS_BEFORE_POST,
REPH_POS_AFTER_POST = POS_AFTER_POST,
REPH_POS_DONT_CARE = POS_RA_TO_BECOME_REPH
REPH_POS_AFTER_POST = POS_AFTER_POST
};
enum reph_mode_t {
REPH_MODE_IMPLICIT, /* Reph formed out of initial Ra,H sequence. */
REPH_MODE_EXPLICIT, /* Reph formed out of initial Ra,H,ZWJ sequence. */
REPH_MODE_VIS_REPHA, /* Encoded Repha character, no reordering needed. */
REPH_MODE_LOG_REPHA /* Encoded Repha character, needs reordering. */
};
enum blwf_mode_t {
@ -319,7 +301,6 @@ static const indic_config_t indic_configs[] =
{HB_SCRIPT_MALAYALAM, true, 0x0D4Du,BASE_POS_LAST, REPH_POS_AFTER_MAIN, REPH_MODE_LOG_REPHA,BLWF_MODE_PRE_AND_POST},
{HB_SCRIPT_SINHALA, false,0x0DCAu,BASE_POS_LAST_SINHALA,
REPH_POS_AFTER_MAIN, REPH_MODE_EXPLICIT, BLWF_MODE_PRE_AND_POST},
{HB_SCRIPT_KHMER, false,0x17D2u,BASE_POS_FIRST,REPH_POS_DONT_CARE, REPH_MODE_VIS_REPHA,BLWF_MODE_PRE_AND_POST},
};
@ -351,7 +332,6 @@ indic_features[] =
{HB_TAG('p','s','t','f'), F_NONE},
{HB_TAG('v','a','t','u'), F_GLOBAL},
{HB_TAG('c','j','c','t'), F_GLOBAL},
{HB_TAG('c','f','a','r'), F_NONE},
/*
* Other features.
* These features are applied all at once, after final_reordering.
@ -385,7 +365,6 @@ enum {
PSTF,
_VATU,
_CJCT,
CFAR,
INIT,
_PRES,
@ -452,17 +431,6 @@ collect_features_indic (hb_ot_shape_planner_t *plan)
static void
override_features_indic (hb_ot_shape_planner_t *plan)
{
/* Uniscribe does not apply 'kern' in Khmer. */
if (hb_options ().uniscribe_bug_compatible)
{
switch ((hb_tag_t) plan->props.script)
{
case HB_SCRIPT_KHMER:
plan->map.add_feature (HB_TAG('k','e','r','n'), 0, F_GLOBAL);
break;
}
}
plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
}
@ -730,8 +698,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
* and has more than one consonant, Ra is excluded from candidates for
* base consonants. */
unsigned int limit = start;
if (indic_plan->config->reph_pos != REPH_POS_DONT_CARE &&
indic_plan->mask_array[RPHF] &&
if (indic_plan->mask_array[RPHF] &&
start + 3 <= end &&
(
(indic_plan->config->reph_mode == REPH_MODE_IMPLICIT && !is_joiner (info[start + 2])) ||
@ -840,22 +807,6 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
info[i].indic_position() = POS_BELOW_C;
}
break;
case BASE_POS_FIRST:
{
/* The first consonant is always the base. */
assert (indic_plan->config->reph_mode == REPH_MODE_VIS_REPHA);
assert (!has_reph);
base = start;
/* Mark all subsequent consonants as below. */
for (unsigned int i = base + 1; i < end; i++)
if (is_consonant (info[i]))
info[i].indic_position() = POS_BELOW_C;
}
break;
}
/* -> If the syllable starts with Ra + Halant (in a script that has Reph)
@ -910,15 +861,15 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
if (base < end)
info[base].indic_position() = POS_BASE_C;
/* Mark final consonants. A final consonant is one appearing after a matra,
* like in Khmer. */
/* Mark final consonants. A final consonant is one appearing after a matra.
* Happens in Sinhala. */
for (unsigned int i = base + 1; i < end; i++)
if (info[i].indic_category() == OT_M) {
for (unsigned int j = i + 1; j < end; j++)
if (is_consonant (info[j])) {
info[j].indic_position() = POS_FINAL_C;
break;
}
if (is_consonant (info[j])) {
info[j].indic_position() = POS_FINAL_C;
break;
}
break;
}
@ -969,7 +920,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
indic_position_t last_pos = POS_START;
for (unsigned int i = start; i < end; i++)
{
if ((FLAG_UNSAFE (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | HALANT_OR_COENG_FLAGS)))
if ((FLAG_UNSAFE (info[i].indic_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | FLAG (OT_H))))
{
info[i].indic_position() = last_pos;
if (unlikely (info[i].indic_category() == OT_H &&
@ -1133,17 +1084,6 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
{
for (unsigned int j = 0; j < pref_len; j++)
info[i++].mask |= indic_plan->mask_array[PREF];
/* Mark the subsequent stuff with 'cfar'. Used in Khmer.
* Read the feature spec.
* This allows distinguishing the following cases with MS Khmer fonts:
* U+1784,U+17D2,U+179A,U+17D2,U+1782
* U+1784,U+17D2,U+1782,U+17D2,U+179A
*/
if (indic_plan->mask_array[CFAR])
for (; i < end; i++)
info[i].mask |= indic_plan->mask_array[CFAR];
break;
}
}
@ -1311,7 +1251,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
_hb_glyph_info_ligated (&info[i]) &&
_hb_glyph_info_multiplied (&info[i]))
{
/* This will make sure that this glyph passes is_halant_or_coeng() test. */
/* This will make sure that this glyph passes is_halant() test. */
info[i].indic_category() = OT_H;
_hb_glyph_info_clear_ligated_and_multiplied (&info[i]);
}
@ -1344,7 +1284,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
/* Ok, this was a 'pref' candidate but didn't form any.
* Base is around here... */
base = i;
while (base < end && is_halant_or_coeng (info[base]))
while (base < end && is_halant (info[base]))
base++;
info[base].indic_position() = POS_BASE_C;
@ -1360,7 +1300,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
{
while (i < end && is_joiner (info[i]))
i++;
if (i == end || !is_halant_or_coeng (info[i]))
if (i == end || !is_halant (info[i]))
break;
i++; /* Skip halant. */
while (i < end && is_joiner (info[i]))
@ -1382,7 +1322,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
base--;
if (base < end)
while (start < base &&
is_one_of (info[base], (FLAG (OT_N) | HALANT_OR_COENG_FLAGS)))
is_one_of (info[base], (FLAG (OT_N) | FLAG (OT_H))))
base--;
@ -1408,13 +1348,13 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL)
{
while (new_pos > start &&
!(is_one_of (info[new_pos], (FLAG (OT_M) | HALANT_OR_COENG_FLAGS))))
!(is_one_of (info[new_pos], (FLAG (OT_M) | FLAG (OT_H)))))
new_pos--;
/* If we found no Halant we are done.
* Otherwise only proceed if the Halant does
* not belong to the Matra itself! */
if (is_halant_or_coeng (info[new_pos]) &&
if (is_halant (info[new_pos]) &&
info[new_pos].indic_position() != POS_PRE_M)
{
/* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */
@ -1481,8 +1421,6 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
unsigned int new_reph_pos;
reph_position_t reph_pos = indic_plan->config->reph_pos;
assert (reph_pos != REPH_POS_DONT_CARE);
/* 1. If reph should be positioned after post-base consonant forms,
* proceed to step 5.
*/
@ -1504,10 +1442,10 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
*/
{
new_reph_pos = start + 1;
while (new_reph_pos < base && !is_halant_or_coeng (info[new_reph_pos]))
while (new_reph_pos < base && !is_halant (info[new_reph_pos]))
new_reph_pos++;
if (new_reph_pos < base && is_halant_or_coeng (info[new_reph_pos]))
if (new_reph_pos < base && is_halant (info[new_reph_pos]))
{
/* ->If ZWJ or ZWNJ are following this halant, position is moved after it. */
if (new_reph_pos + 1 < base && is_joiner (info[new_reph_pos + 1]))
@ -1556,10 +1494,10 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
{
/* Copied from step 2. */
new_reph_pos = start + 1;
while (new_reph_pos < base && !is_halant_or_coeng (info[new_reph_pos]))
while (new_reph_pos < base && !is_halant (info[new_reph_pos]))
new_reph_pos++;
if (new_reph_pos < base && is_halant_or_coeng (info[new_reph_pos]))
if (new_reph_pos < base && is_halant (info[new_reph_pos]))
{
/* ->If ZWJ or ZWNJ are following this halant, position is moved after it. */
if (new_reph_pos + 1 < base && is_joiner (info[new_reph_pos + 1]))
@ -1583,7 +1521,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
* TEST: U+0930,U+094D,U+0915,U+094B,U+094D
*/
if (!hb_options ().uniscribe_bug_compatible &&
unlikely (is_halant_or_coeng (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. */
@ -1644,24 +1582,11 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
if (buffer->props.script != HB_SCRIPT_MALAYALAM && buffer->props.script != HB_SCRIPT_TAMIL)
{
while (new_pos > start &&
!(is_one_of (info[new_pos - 1], FLAG(OT_M) | HALANT_OR_COENG_FLAGS)))
!(is_one_of (info[new_pos - 1], FLAG(OT_M) | FLAG (OT_H))))
new_pos--;
/* In Khmer coeng model, a H,Ra can go *after* matras. If it goes after a
* split matra, it should be reordered to *before* the left part of such matra. */
if (new_pos > start && info[new_pos - 1].indic_category() == OT_M)
{
unsigned int old_pos = i;
for (unsigned int j = base + 1; j < old_pos; j++)
if (info[j].indic_category() == OT_M)
{
new_pos--;
break;
}
}
}
if (new_pos > start && is_halant_or_coeng (info[new_pos - 1]))
if (new_pos > start && is_halant (info[new_pos - 1]))
{
/* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */
if (new_pos < end && is_joiner (info[new_pos]))
@ -1766,13 +1691,6 @@ decompose_indic (const hb_ot_shape_normalize_context_t *c,
* Decompose split matras that don't have Unicode decompositions.
*/
/* Khmer */
case 0x17BEu : *a = 0x17C1u; *b= 0x17BEu; return true;
case 0x17BFu : *a = 0x17C1u; *b= 0x17BFu; return true;
case 0x17C0u : *a = 0x17C1u; *b= 0x17C0u; return true;
case 0x17C4u : *a = 0x17C1u; *b= 0x17C4u; return true;
case 0x17C5u : *a = 0x17C1u; *b= 0x17C5u; return true;
#if 0
/* Gujarati */
/* This one has no decomposition in Unicode, but needs no decomposition either. */

Просмотреть файл

@ -0,0 +1,294 @@
#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
*/
#ifndef HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH
#define HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH
#include "hb-private.hh"
#line 36 "hb-ot-shape-complex-khmer-machine.hh"
static const unsigned char _khmer_syllable_machine_trans_keys[] = {
7u, 7u, 1u, 16u, 13u, 13u, 1u, 16u, 7u, 13u, 7u, 7u, 1u, 16u, 13u, 13u,
1u, 16u, 7u, 13u, 1u, 16u, 3u, 14u, 3u, 14u, 5u, 14u, 3u, 14u, 5u, 14u,
8u, 8u, 3u, 13u, 3u, 8u, 8u, 8u, 3u, 8u, 3u, 14u, 3u, 14u, 5u, 14u,
3u, 14u, 5u, 14u, 8u, 8u, 3u, 13u, 3u, 8u, 8u, 8u, 3u, 8u, 3u, 14u,
3u, 14u, 7u, 13u, 7u, 7u, 1u, 16u, 0
};
static const char _khmer_syllable_machine_key_spans[] = {
1, 16, 1, 16, 7, 1, 16, 1,
16, 7, 16, 12, 12, 10, 12, 10,
1, 11, 6, 1, 6, 12, 12, 10,
12, 10, 1, 11, 6, 1, 6, 12,
12, 7, 1, 16
};
static const short _khmer_syllable_machine_index_offsets[] = {
0, 2, 19, 21, 38, 46, 48, 65,
67, 84, 92, 109, 122, 135, 146, 159,
170, 172, 184, 191, 193, 200, 213, 226,
237, 250, 261, 263, 275, 282, 284, 291,
304, 317, 325, 327
};
static const char _khmer_syllable_machine_indicies[] = {
1, 0, 2, 2, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 2, 0, 3, 0, 4, 4, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 4, 0, 1, 0,
0, 0, 0, 0, 5, 0, 7, 6,
8, 8, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 8,
6, 9, 6, 10, 10, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 10, 6, 7, 6, 6, 6,
6, 6, 11, 6, 4, 4, 13, 12,
14, 15, 7, 16, 12, 12, 4, 4,
11, 17, 12, 4, 12, 19, 18, 20,
21, 1, 22, 18, 18, 18, 18, 5,
23, 18, 24, 18, 21, 21, 1, 22,
18, 18, 18, 18, 18, 23, 18, 21,
21, 1, 22, 18, 18, 18, 18, 18,
23, 18, 25, 18, 21, 21, 1, 22,
18, 18, 18, 18, 18, 26, 18, 21,
21, 1, 22, 18, 18, 18, 18, 18,
26, 18, 27, 18, 28, 18, 29, 18,
18, 22, 18, 18, 18, 18, 3, 18,
30, 18, 18, 18, 18, 22, 18, 22,
18, 28, 18, 18, 18, 18, 22, 18,
19, 18, 21, 21, 1, 22, 18, 18,
18, 18, 18, 23, 18, 32, 31, 33,
33, 7, 16, 31, 31, 31, 31, 31,
34, 31, 33, 33, 7, 16, 31, 31,
31, 31, 31, 34, 31, 35, 31, 33,
33, 7, 16, 31, 31, 31, 31, 31,
36, 31, 33, 33, 7, 16, 31, 31,
31, 31, 31, 36, 31, 37, 31, 38,
31, 39, 31, 31, 16, 31, 31, 31,
31, 9, 31, 40, 31, 31, 31, 31,
16, 31, 16, 31, 38, 31, 31, 31,
31, 16, 31, 13, 31, 41, 33, 7,
16, 31, 31, 31, 31, 11, 34, 31,
13, 31, 33, 33, 7, 16, 31, 31,
31, 31, 31, 34, 31, 7, 42, 42,
42, 42, 42, 11, 42, 7, 42, 10,
10, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 10, 42,
0
};
static const char _khmer_syllable_machine_trans_targs[] = {
10, 14, 17, 20, 11, 21, 10, 24,
27, 30, 31, 32, 10, 22, 33, 34,
26, 35, 10, 12, 4, 0, 16, 3,
13, 15, 1, 10, 18, 2, 19, 10,
23, 5, 8, 25, 6, 10, 28, 7,
29, 9, 10
};
static const char _khmer_syllable_machine_trans_actions[] = {
1, 2, 2, 0, 2, 2, 3, 2,
2, 0, 2, 2, 6, 2, 0, 0,
0, 0, 7, 2, 0, 0, 0, 0,
2, 2, 0, 8, 0, 0, 0, 9,
2, 0, 0, 2, 0, 10, 0, 0,
0, 0, 11
};
static const char _khmer_syllable_machine_to_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 4, 0, 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_from_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 5, 0, 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 unsigned char _khmer_syllable_machine_eof_trans[] = {
1, 1, 1, 1, 1, 7, 7, 7,
7, 7, 0, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
32, 43, 43, 43
};
static const int khmer_syllable_machine_start = 10;
static const int khmer_syllable_machine_first_final = 10;
static const int khmer_syllable_machine_error = -1;
static const int khmer_syllable_machine_en_main = 10;
#line 36 "hb-ot-shape-complex-khmer-machine.rl"
#line 74 "hb-ot-shape-complex-khmer-machine.rl"
#define found_syllable(syllable_type) \
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
for (unsigned int i = last; i < p+1; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
last = p+1; \
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 HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
int cs;
hb_glyph_info_t *info = buffer->info;
#line 181 "hb-ot-shape-complex-khmer-machine.hh"
{
cs = khmer_syllable_machine_start;
ts = 0;
te = 0;
act = 0;
}
#line 95 "hb-ot-shape-complex-khmer-machine.rl"
p = 0;
pe = eof = buffer->len;
unsigned int last = 0;
unsigned int syllable_serial = 1;
#line 198 "hb-ot-shape-complex-khmer-machine.hh"
{
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 5:
#line 1 "NONE"
{ts = p;}
break;
#line 212 "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 68 "hb-ot-shape-complex-khmer-machine.rl"
{te = p+1;{ found_syllable (consonant_syllable); }}
break;
case 10:
#line 69 "hb-ot-shape-complex-khmer-machine.rl"
{te = p+1;{ found_syllable (broken_cluster); }}
break;
case 6:
#line 70 "hb-ot-shape-complex-khmer-machine.rl"
{te = p+1;{ found_syllable (non_khmer_cluster); }}
break;
case 7:
#line 68 "hb-ot-shape-complex-khmer-machine.rl"
{te = p;p--;{ found_syllable (consonant_syllable); }}
break;
case 9:
#line 69 "hb-ot-shape-complex-khmer-machine.rl"
{te = p;p--;{ found_syllable (broken_cluster); }}
break;
case 11:
#line 70 "hb-ot-shape-complex-khmer-machine.rl"
{te = p;p--;{ found_syllable (non_khmer_cluster); }}
break;
case 1:
#line 68 "hb-ot-shape-complex-khmer-machine.rl"
{{p = ((te))-1;}{ found_syllable (consonant_syllable); }}
break;
case 3:
#line 69 "hb-ot-shape-complex-khmer-machine.rl"
{{p = ((te))-1;}{ found_syllable (broken_cluster); }}
break;
#line 266 "hb-ot-shape-complex-khmer-machine.hh"
}
_again:
switch ( _khmer_syllable_machine_to_state_actions[cs] ) {
case 4:
#line 1 "NONE"
{ts = 0;}
break;
#line 275 "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 104 "hb-ot-shape-complex-khmer-machine.rl"
}
#endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */

Просмотреть файл

@ -0,0 +1,107 @@
/*
* 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
#include "hb-private.hh"
%%{
machine khmer_syllable_machine;
alphtype unsigned char;
write data;
}%%
%%{
# Same order as enum khmer_category_t. Not sure how to avoid duplication.
C = 1;
V = 2;
N = 3;
ZWNJ = 5;
ZWJ = 6;
M = 7;
SM = 8;
PLACEHOLDER = 11;
DOTTEDCIRCLE = 12;
RS = 13;
Coeng = 14;
Ra = 16;
c = (C | Ra | V); # is_consonant
n = ((ZWNJ?.RS)? (N.N?)?); # is_consonant_modifier
z = ZWJ|ZWNJ; # is_joiner
cn = c.n?;
matra_group = z?.M.N?;
syllable_tail = (SM.SM?)?;
broken_cluster = n? (Coeng.cn)* matra_group* (Coeng.cn)? syllable_tail;
consonant_syllable = (c|PLACEHOLDER|DOTTEDCIRCLE) broken_cluster;
other = any;
main := |*
consonant_syllable => { found_syllable (consonant_syllable); };
broken_cluster => { found_syllable (broken_cluster); };
other => { found_syllable (non_khmer_cluster); };
*|;
}%%
#define found_syllable(syllable_type) \
HB_STMT_START { \
if (0) fprintf (stderr, "syllable %d..%d %s\n", last, p+1, #syllable_type); \
for (unsigned int i = last; i < p+1; i++) \
info[i].syllable() = (syllable_serial << 4) | syllable_type; \
last = p+1; \
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 HB_UNUSED, te HB_UNUSED, act HB_UNUSED;
int cs;
hb_glyph_info_t *info = buffer->info;
%%{
write init;
getkey info[p].khmer_category();
}%%
p = 0;
pe = eof = buffer->len;
unsigned int last = 0;
unsigned int syllable_serial = 1;
%%{
write exec;
}%%
}
#endif /* HB_OT_SHAPE_COMPLEX_KHMER_MACHINE_HH */

Просмотреть файл

@ -0,0 +1,945 @@
/*
* 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
*/
#include "hb-ot-shape-complex-indic-private.hh"
#include "hb-ot-layout-private.hh"
/* buffer var allocations */
#define khmer_category() complex_var_u8_0() /* khmer_category_t */
#define khmer_position() complex_var_u8_1() /* khmer_position_t */
/*
* Khmer shaper.
*/
typedef indic_category_t khmer_category_t;
typedef indic_position_t khmer_position_t;
static inline khmer_position_t
matra_position (khmer_position_t side)
{
switch ((int) side)
{
case POS_PRE_C:
return POS_PRE_M;
case POS_POST_C:
case POS_ABOVE_C:
case POS_BELOW_C:
return POS_AFTER_POST;
default:
return side;
};
}
static inline bool
is_one_of (const hb_glyph_info_t &info, unsigned int flags)
{
/* If it ligated, all bets are off. */
if (_hb_glyph_info_ligated (&info)) return false;
return !!(FLAG_UNSAFE (info.khmer_category()) & flags);
}
static inline bool
is_joiner (const hb_glyph_info_t &info)
{
return is_one_of (info, JOINER_FLAGS);
}
static inline bool
is_consonant (const hb_glyph_info_t &info)
{
return is_one_of (info, CONSONANT_FLAGS | FLAG (OT_V));
}
static inline bool
is_coeng (const hb_glyph_info_t &info)
{
return is_one_of (info, FLAG (OT_Coeng));
}
static inline void
set_khmer_properties (hb_glyph_info_t &info)
{
hb_codepoint_t u = info.codepoint;
unsigned int type = hb_indic_get_categories (u);
khmer_category_t cat = (khmer_category_t) (type & 0x7Fu);
khmer_position_t pos = (khmer_position_t) (type >> 8);
/*
* Re-assign category
*/
if (unlikely (u == 0x17C6u)) cat = OT_N; /* Khmer Bindu doesn't like to be repositioned. */
else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x17CDu, 0x17D1u) ||
u == 0x17CBu || u == 0x17D3u || u == 0x17DDu)) /* Khmer Various signs */
{
/* These can occur mid-syllable (eg. before matras), even though Unicode marks them as Syllable_Modifier.
* https://github.com/roozbehp/unicode-data/issues/5 */
cat = OT_M;
pos = POS_ABOVE_C;
}
else if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x2010u, 0x2011u))) cat = OT_PLACEHOLDER;
else if (unlikely (u == 0x25CCu)) cat = OT_DOTTEDCIRCLE;
/*
* Re-assign position.
*/
if ((FLAG_UNSAFE (cat) & CONSONANT_FLAGS))
{
pos = POS_BASE_C;
if (u == 0x179Au)
cat = OT_Ra;
}
else if (cat == OT_M)
{
pos = matra_position (pos);
}
else if ((FLAG_UNSAFE (cat) & (FLAG (OT_SM) | FLAG (OT_A) | FLAG (OT_Symbol))))
{
pos = POS_SMVD;
}
info.khmer_category() = cat;
info.khmer_position() = pos;
}
/*
* Things above this line should ideally be moved to the Indic table itself.
*/
/*
* Khmer shaper.
*/
struct feature_list_t {
hb_tag_t tag;
hb_ot_map_feature_flags_t flags;
};
static const feature_list_t
khmer_features[] =
{
/*
* Basic features.
* These features are applied in order, one at a time, after initial_reordering.
*/
{HB_TAG('p','r','e','f'), F_NONE},
{HB_TAG('b','l','w','f'), F_NONE},
{HB_TAG('a','b','v','f'), F_NONE},
{HB_TAG('p','s','t','f'), F_NONE},
{HB_TAG('c','f','a','r'), F_NONE},
/*
* Other features.
* These features are applied all at once, after final_reordering.
* Default Bengali font in Windows for example has intermixed
* lookups for init,pres,abvs,blws features.
*/
{HB_TAG('p','r','e','s'), F_GLOBAL},
{HB_TAG('a','b','v','s'), F_GLOBAL},
{HB_TAG('b','l','w','s'), F_GLOBAL},
{HB_TAG('p','s','t','s'), F_GLOBAL},
/* Positioning features, though we don't care about the types. */
{HB_TAG('d','i','s','t'), F_GLOBAL},
{HB_TAG('a','b','v','m'), F_GLOBAL},
{HB_TAG('b','l','w','m'), F_GLOBAL},
};
/*
* Must be in the same order as the khmer_features array.
*/
enum {
PREF,
BLWF,
ABVF,
PSTF,
CFAR,
_PRES,
_ABVS,
_BLWS,
_PSTS,
_DIST,
_ABVM,
_BLWM,
KHMER_NUM_FEATURES,
KHMER_BASIC_FEATURES = _PRES /* Don't forget to update this! */
};
static void
setup_syllables (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
initial_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
final_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
clear_syllables (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
static void
collect_features_khmer (hb_ot_shape_planner_t *plan)
{
hb_ot_map_builder_t *map = &plan->map;
/* Do this before any lookups have been applied. */
map->add_gsub_pause (setup_syllables);
map->add_global_bool_feature (HB_TAG('l','o','c','l'));
/* The Indic specs do not require ccmp, but we apply it here since if
* there is a use of it, it's typically at the beginning. */
map->add_global_bool_feature (HB_TAG('c','c','m','p'));
unsigned int i = 0;
map->add_gsub_pause (initial_reordering);
for (; i < KHMER_BASIC_FEATURES; i++) {
map->add_feature (khmer_features[i].tag, 1, khmer_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ);
map->add_gsub_pause (nullptr);
}
map->add_gsub_pause (final_reordering);
for (; i < KHMER_NUM_FEATURES; i++) {
map->add_feature (khmer_features[i].tag, 1, khmer_features[i].flags | F_MANUAL_ZWJ | F_MANUAL_ZWNJ);
}
map->add_global_bool_feature (HB_TAG('c','a','l','t'));
map->add_global_bool_feature (HB_TAG('c','l','i','g'));
map->add_gsub_pause (clear_syllables);
}
static void
override_features_khmer (hb_ot_shape_planner_t *plan)
{
/* Uniscribe does not apply 'kern' in Khmer. */
if (hb_options ().uniscribe_bug_compatible)
{
plan->map.add_feature (HB_TAG('k','e','r','n'), 0, F_GLOBAL);
}
plan->map.add_feature (HB_TAG('l','i','g','a'), 0, F_GLOBAL);
}
struct would_substitute_feature_t
{
inline void init (const hb_ot_map_t *map, hb_tag_t feature_tag, bool zero_context_)
{
zero_context = zero_context_;
map->get_stage_lookups (0/*GSUB*/,
map->get_feature_stage (0/*GSUB*/, feature_tag),
&lookups, &count);
}
inline bool would_substitute (const hb_codepoint_t *glyphs,
unsigned int glyphs_count,
hb_face_t *face) const
{
for (unsigned int i = 0; i < count; i++)
if (hb_ot_layout_lookup_would_substitute_fast (face, lookups[i].index, glyphs, glyphs_count, zero_context))
return true;
return false;
}
private:
const hb_ot_map_t::lookup_map_t *lookups;
unsigned int count;
bool zero_context;
};
struct khmer_shape_plan_t
{
ASSERT_POD ();
inline bool get_virama_glyph (hb_font_t *font, hb_codepoint_t *pglyph) const
{
hb_codepoint_t glyph = virama_glyph;
if (unlikely (virama_glyph == (hb_codepoint_t) -1))
{
if (!font->get_nominal_glyph (0x17D2u, &glyph))
glyph = 0;
/* Technically speaking, the spec says we should apply 'locl' to virama too.
* Maybe one day... */
/* Our get_nominal_glyph() function needs a font, so we can't get the virama glyph
* during shape planning... Instead, overwrite it here. It's safe. Don't worry! */
virama_glyph = glyph;
}
*pglyph = glyph;
return glyph != 0;
}
mutable hb_codepoint_t virama_glyph;
would_substitute_feature_t pref;
hb_mask_t mask_array[KHMER_NUM_FEATURES];
};
static void *
data_create_khmer (const hb_ot_shape_plan_t *plan)
{
khmer_shape_plan_t *khmer_plan = (khmer_shape_plan_t *) calloc (1, sizeof (khmer_shape_plan_t));
if (unlikely (!khmer_plan))
return nullptr;
khmer_plan->virama_glyph = (hb_codepoint_t) -1;
khmer_plan->pref.init (&plan->map, HB_TAG('p','r','e','f'), true);
for (unsigned int i = 0; i < ARRAY_LENGTH (khmer_plan->mask_array); i++)
khmer_plan->mask_array[i] = (khmer_features[i].flags & F_GLOBAL) ?
0 : plan->map.get_1_mask (khmer_features[i].tag);
return khmer_plan;
}
static void
data_destroy_khmer (void *data)
{
free (data);
}
enum syllable_type_t {
consonant_syllable,
broken_cluster,
non_khmer_cluster,
};
#include "hb-ot-shape-complex-khmer-machine.hh"
static void
setup_masks_khmer (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_buffer_t *buffer,
hb_font_t *font HB_UNUSED)
{
HB_BUFFER_ALLOCATE_VAR (buffer, khmer_category);
HB_BUFFER_ALLOCATE_VAR (buffer, khmer_position);
/* We cannot setup masks here. We save information about characters
* and setup masks later on in a pause-callback. */
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
set_khmer_properties (info[i]);
}
static void
setup_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
find_syllables (buffer);
foreach_syllable (buffer, start, end)
buffer->unsafe_to_break (start, end);
}
static int
compare_khmer_order (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
{
int a = pa->khmer_position();
int b = pb->khmer_position();
return a < b ? -1 : a == b ? 0 : +1;
}
/* Rules from:
* https://www.microsoft.com/typography/otfntdev/devanot/shaping.aspx */
static void
initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
hb_face_t *face,
hb_buffer_t *buffer,
unsigned int start, unsigned int end)
{
const khmer_shape_plan_t *khmer_plan = (const khmer_shape_plan_t *) plan->data;
hb_glyph_info_t *info = buffer->info;
/* 1. Khmer shaping assumes that a syllable will begin with a Cons, IndV, or Number. */
/* The first consonant is always the base. */
unsigned int base = start;
info[base].khmer_position() = POS_BASE_C;
/* Mark all subsequent consonants as below. */
for (unsigned int i = base + 1; i < end; i++)
if (is_consonant (info[i]))
info[i].khmer_position() = POS_BELOW_C;
/* Mark final consonants. A final consonant is one appearing after a matra,
* like in Khmer. */
for (unsigned int i = base + 1; i < end; i++)
if (info[i].khmer_category() == OT_M) {
for (unsigned int j = i + 1; j < end; j++)
if (is_consonant (info[j])) {
info[j].khmer_position() = POS_FINAL_C;
break;
}
break;
}
/* Attach misc marks to previous char to move with them. */
{
khmer_position_t last_pos = POS_START;
for (unsigned int i = start; i < end; i++)
{
if ((FLAG_UNSAFE (info[i].khmer_category()) & (JOINER_FLAGS | FLAG (OT_N) | FLAG (OT_RS) | MEDIAL_FLAGS | FLAG (OT_Coeng))))
{
info[i].khmer_position() = last_pos;
if (unlikely (info[i].khmer_category() == OT_H &&
info[i].khmer_position() == POS_PRE_M))
{
/*
* Uniscribe doesn't move the Halant with Left Matra.
* TEST: U+092B,U+093F,U+094DE
* We follow. This is important for the Sinhala
* U+0DDA split matra since it decomposes to U+0DD9,U+0DCA
* where U+0DD9 is a left matra and U+0DCA is the virama.
* We don't want to move the virama with the left matra.
* TEST: U+0D9A,U+0DDA
*/
for (unsigned int j = i; j > start; j--)
if (info[j - 1].khmer_position() != POS_PRE_M) {
info[i].khmer_position() = info[j - 1].khmer_position();
break;
}
}
} else if (info[i].khmer_position() != POS_SMVD) {
last_pos = (khmer_position_t) info[i].khmer_position();
}
}
}
/* For post-base consonants let them own anything before them
* since the last consonant or matra. */
{
unsigned int last = base;
for (unsigned int i = base + 1; i < end; i++)
if (is_consonant (info[i]))
{
for (unsigned int j = last + 1; j < i; j++)
if (info[j].khmer_position() < POS_SMVD)
info[j].khmer_position() = info[i].khmer_position();
last = i;
} else if (info[i].khmer_category() == OT_M)
last = i;
}
{
/* Use syllable() for sort accounting temporarily. */
unsigned int syllable = info[start].syllable();
for (unsigned int i = start; i < end; i++)
info[i].syllable() = i - start;
/* Sit tight, rock 'n roll! */
hb_stable_sort (info + start, end - start, compare_khmer_order);
/* Find base again */
base = end;
for (unsigned int i = start; i < end; i++)
if (info[i].khmer_position() == POS_BASE_C)
{
base = i;
break;
}
/* Note! syllable() is a one-byte field. */
for (unsigned int i = base; i < end; i++)
if (info[i].syllable() != 255)
{
unsigned int max = i;
unsigned int j = start + info[i].syllable();
while (j != i)
{
max = MAX (max, j);
unsigned int next = start + info[j].syllable();
info[j].syllable() = 255; /* So we don't process j later again. */
j = next;
}
if (i != max)
buffer->merge_clusters (i, max + 1);
}
/* Put syllable back in. */
for (unsigned int i = start; i < end; i++)
info[i].syllable() = syllable;
}
/* Setup masks now */
{
hb_mask_t mask;
/* Post-base */
mask = khmer_plan->mask_array[BLWF] | khmer_plan->mask_array[ABVF] | khmer_plan->mask_array[PSTF];
for (unsigned int i = base + 1; i < end; i++)
info[i].mask |= mask;
}
unsigned int pref_len = 2;
if (khmer_plan->mask_array[PREF] && base + pref_len < end)
{
/* Find a Halant,Ra sequence and mark it for pre-base-reordering processing. */
for (unsigned int i = base + 1; i + pref_len - 1 < end; i++) {
hb_codepoint_t glyphs[2];
for (unsigned int j = 0; j < pref_len; j++)
glyphs[j] = info[i + j].codepoint;
if (khmer_plan->pref.would_substitute (glyphs, pref_len, face))
{
for (unsigned int j = 0; j < pref_len; j++)
info[i++].mask |= khmer_plan->mask_array[PREF];
/* Mark the subsequent stuff with 'cfar'. Used in Khmer.
* Read the feature spec.
* This allows distinguishing the following cases with MS Khmer fonts:
* U+1784,U+17D2,U+179A,U+17D2,U+1782
* U+1784,U+17D2,U+1782,U+17D2,U+179A
*/
if (khmer_plan->mask_array[CFAR])
for (; i < end; i++)
info[i].mask |= khmer_plan->mask_array[CFAR];
break;
}
}
}
}
static void
initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
hb_face_t *face,
hb_buffer_t *buffer,
unsigned int start, unsigned int end)
{
syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
switch (syllable_type)
{
case broken_cluster: /* We already inserted dotted-circles, so just call the consonant_syllable. */
case consonant_syllable:
initial_reordering_consonant_syllable (plan, face, buffer, start, end);
break;
case non_khmer_cluster:
break;
}
}
static inline void
insert_dotted_circles (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font,
hb_buffer_t *buffer)
{
/* Note: This loop is extra overhead, but should not be measurable. */
bool has_broken_syllables = false;
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
if ((info[i].syllable() & 0x0F) == broken_cluster)
{
has_broken_syllables = true;
break;
}
if (likely (!has_broken_syllables))
return;
hb_codepoint_t dottedcircle_glyph;
if (!font->get_nominal_glyph (0x25CCu, &dottedcircle_glyph))
return;
hb_glyph_info_t dottedcircle = {0};
dottedcircle.codepoint = 0x25CCu;
set_khmer_properties (dottedcircle);
dottedcircle.codepoint = dottedcircle_glyph;
buffer->clear_output ();
buffer->idx = 0;
unsigned int last_syllable = 0;
while (buffer->idx < buffer->len && !buffer->in_error)
{
unsigned int syllable = buffer->cur().syllable();
syllable_type_t syllable_type = (syllable_type_t) (syllable & 0x0F);
if (unlikely (last_syllable != syllable && syllable_type == broken_cluster))
{
last_syllable = syllable;
hb_glyph_info_t ginfo = dottedcircle;
ginfo.cluster = buffer->cur().cluster;
ginfo.mask = buffer->cur().mask;
ginfo.syllable() = buffer->cur().syllable();
/* TODO Set glyph_props? */
/* Insert dottedcircle after possible Repha. */
while (buffer->idx < buffer->len && !buffer->in_error &&
last_syllable == buffer->cur().syllable() &&
buffer->cur().khmer_category() == OT_Repha)
buffer->next_glyph ();
buffer->output_info (ginfo);
}
else
buffer->next_glyph ();
}
buffer->swap_buffers ();
}
static void
initial_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
insert_dotted_circles (plan, font, buffer);
foreach_syllable (buffer, start, end)
initial_reordering_syllable (plan, font->face, buffer, start, end);
}
static void
final_reordering_syllable (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer,
unsigned int start, unsigned int end)
{
const khmer_shape_plan_t *khmer_plan = (const khmer_shape_plan_t *) plan->data;
hb_glyph_info_t *info = buffer->info;
/* This function relies heavily on halant glyphs. Lots of ligation
* and possibly multiple substitutions happened prior to this
* phase, and that might have messed up our properties. Recover
* from a particular case of that where we're fairly sure that a
* class of OT_H is desired but has been lost. */
if (khmer_plan->virama_glyph)
{
unsigned int virama_glyph = khmer_plan->virama_glyph;
for (unsigned int i = start; i < end; i++)
if (info[i].codepoint == virama_glyph &&
_hb_glyph_info_ligated (&info[i]) &&
_hb_glyph_info_multiplied (&info[i]))
{
/* This will make sure that this glyph passes is_coeng() test. */
info[i].khmer_category() = OT_H;
_hb_glyph_info_clear_ligated_and_multiplied (&info[i]);
}
}
/* 4. Final reordering:
*
* After the localized forms and basic shaping forms GSUB features have been
* applied (see below), the shaping engine performs some final glyph
* reordering before applying all the remaining font features to the entire
* syllable.
*/
bool try_pref = !!khmer_plan->mask_array[PREF];
/* Find base again */
unsigned int base;
for (base = start; base < end; base++)
if (info[base].khmer_position() >= POS_BASE_C)
{
if (try_pref && base + 1 < end)
{
for (unsigned int i = base + 1; i < end; i++)
if ((info[i].mask & khmer_plan->mask_array[PREF]) != 0)
{
if (!(_hb_glyph_info_substituted (&info[i]) &&
_hb_glyph_info_ligated_and_didnt_multiply (&info[i])))
{
/* Ok, this was a 'pref' candidate but didn't form any.
* Base is around here... */
base = i;
while (base < end && is_coeng (info[base]))
base++;
info[base].khmer_position() = POS_BASE_C;
try_pref = false;
}
break;
}
}
if (start < base && info[base].khmer_position() > POS_BASE_C)
base--;
break;
}
if (base == end && start < base &&
is_one_of (info[base - 1], FLAG (OT_ZWJ)))
base--;
if (base < end)
while (start < base &&
is_one_of (info[base], (FLAG (OT_N) | FLAG (OT_Coeng))))
base--;
/* o Reorder matras:
*
* If a pre-base matra character had been reordered before applying basic
* features, the glyph can be moved closer to the main consonant based on
* whether half-forms had been formed. Actual position for the matra is
* defined as after last standalone halant glyph, after initial matra
* position and before the main consonant. If ZWJ or ZWNJ follow this
* halant, position is moved after it.
*/
if (start + 1 < end && start < base) /* Otherwise there can't be any pre-base matra characters. */
{
/* If we lost track of base, alas, position before last thingy. */
unsigned int new_pos = base == end ? base - 2 : base - 1;
while (new_pos > start &&
!(is_one_of (info[new_pos], (FLAG (OT_M) | FLAG (OT_Coeng)))))
new_pos--;
/* If we found no Halant we are done.
* Otherwise only proceed if the Halant does
* not belong to the Matra itself! */
if (is_coeng (info[new_pos]) &&
info[new_pos].khmer_position() != POS_PRE_M)
{
/* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */
if (new_pos + 1 < end && is_joiner (info[new_pos + 1]))
new_pos++;
}
else
new_pos = start; /* No move. */
if (start < new_pos && info[new_pos].khmer_position () != POS_PRE_M)
{
/* Now go see if there's actually any matras... */
for (unsigned int i = new_pos; i > start; i--)
if (info[i - 1].khmer_position () == POS_PRE_M)
{
unsigned int old_pos = i - 1;
if (old_pos < base && base <= new_pos) /* Shouldn't actually happen. */
base--;
hb_glyph_info_t tmp = info[old_pos];
memmove (&info[old_pos], &info[old_pos + 1], (new_pos - old_pos) * sizeof (info[0]));
info[new_pos] = tmp;
/* Note: this merge_clusters() is intentionally *after* the reordering.
* Indic matra reordering is special and tricky... */
buffer->merge_clusters (new_pos, MIN (end, base + 1));
new_pos--;
}
} else {
for (unsigned int i = start; i < base; i++)
if (info[i].khmer_position () == POS_PRE_M) {
buffer->merge_clusters (i, MIN (end, base + 1));
break;
}
}
}
/* o Reorder pre-base-reordering consonants:
*
* If a pre-base-reordering consonant is found, reorder it according to
* the following rules:
*/
if (try_pref && base + 1 < end) /* Otherwise there can't be any pre-base-reordering Ra. */
{
for (unsigned int i = base + 1; i < end; i++)
if ((info[i].mask & khmer_plan->mask_array[PREF]) != 0)
{
/* 1. Only reorder a glyph produced by substitution during application
* of the <pref> feature. (Note that a font may shape a Ra consonant with
* the feature generally but block it in certain contexts.)
*/
/* Note: We just check that something got substituted. We don't check that
* the <pref> feature actually did it...
*
* Reorder pref only if it ligated. */
if (_hb_glyph_info_ligated_and_didnt_multiply (&info[i]))
{
/*
* 2. Try to find a target position the same way as for pre-base matra.
* If it is found, reorder pre-base consonant glyph.
*
* 3. If position is not found, reorder immediately before main
* consonant.
*/
unsigned int new_pos = base;
while (new_pos > start &&
!(is_one_of (info[new_pos - 1], FLAG(OT_M) | FLAG (OT_Coeng))))
new_pos--;
/* In Khmer coeng model, a H,Ra can go *after* matras. If it goes after a
* split matra, it should be reordered to *before* the left part of such matra. */
if (new_pos > start && info[new_pos - 1].khmer_category() == OT_M)
{
unsigned int old_pos = i;
for (unsigned int j = base + 1; j < old_pos; j++)
if (info[j].khmer_category() == OT_M)
{
new_pos--;
break;
}
}
if (new_pos > start && is_coeng (info[new_pos - 1]))
{
/* -> If ZWJ or ZWNJ follow this halant, position is moved after it. */
if (new_pos < end && is_joiner (info[new_pos]))
new_pos++;
}
{
unsigned int old_pos = i;
buffer->merge_clusters (new_pos, old_pos + 1);
hb_glyph_info_t tmp = info[old_pos];
memmove (&info[new_pos + 1], &info[new_pos], (old_pos - new_pos) * sizeof (info[0]));
info[new_pos] = tmp;
if (new_pos <= base && base < old_pos)
base++;
}
}
break;
}
}
/*
* Finish off the clusters and go home!
*/
if (hb_options ().uniscribe_bug_compatible)
{
/* Uniscribe merges the entire syllable into a single cluster... Except for Tamil & Sinhala.
* This means, half forms are submerged into the main consonant's cluster.
* This is unnecessary, and makes cursor positioning harder, but that's what
* Uniscribe does. */
buffer->merge_clusters (start, end);
}
}
static void
final_reordering (const hb_ot_shape_plan_t *plan,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
unsigned int count = buffer->len;
if (unlikely (!count)) return;
foreach_syllable (buffer, start, end)
final_reordering_syllable (plan, buffer, start, end);
HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_category);
HB_BUFFER_DEALLOCATE_VAR (buffer, khmer_position);
}
static void
clear_syllables (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_font_t *font HB_UNUSED,
hb_buffer_t *buffer)
{
hb_glyph_info_t *info = buffer->info;
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++)
info[i].syllable() = 0;
}
static bool
decompose_khmer (const hb_ot_shape_normalize_context_t *c,
hb_codepoint_t ab,
hb_codepoint_t *a,
hb_codepoint_t *b)
{
switch (ab)
{
/*
* Decompose split matras that don't have Unicode decompositions.
*/
/* Khmer */
case 0x17BEu : *a = 0x17C1u; *b= 0x17BEu; return true;
case 0x17BFu : *a = 0x17C1u; *b= 0x17BFu; return true;
case 0x17C0u : *a = 0x17C1u; *b= 0x17C0u; return true;
case 0x17C4u : *a = 0x17C1u; *b= 0x17C4u; return true;
case 0x17C5u : *a = 0x17C1u; *b= 0x17C5u; return true;
}
return (bool) c->unicode->decompose (ab, a, b);
}
static bool
compose_khmer (const hb_ot_shape_normalize_context_t *c,
hb_codepoint_t a,
hb_codepoint_t b,
hb_codepoint_t *ab)
{
/* Avoid recomposing split matras. */
if (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (c->unicode->general_category (a)))
return false;
return (bool) c->unicode->compose (a, b, ab);
}
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_khmer =
{
collect_features_khmer,
override_features_khmer,
data_create_khmer,
data_destroy_khmer,
nullptr, /* preprocess_text */
nullptr, /* postprocess_glyphs */
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
decompose_khmer,
compose_khmer,
setup_masks_khmer,
nullptr, /* disable_otl */
nullptr, /* reorder_marks */
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
false, /* fallback_position */
};

Просмотреть файл

@ -54,9 +54,10 @@ enum hb_ot_shape_zero_width_marks_type_t {
HB_COMPLEX_SHAPER_IMPLEMENT (arabic) \
HB_COMPLEX_SHAPER_IMPLEMENT (hangul) \
HB_COMPLEX_SHAPER_IMPLEMENT (hebrew) \
HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_old) \
HB_COMPLEX_SHAPER_IMPLEMENT (indic) \
HB_COMPLEX_SHAPER_IMPLEMENT (khmer) \
HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \
HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_old) \
HB_COMPLEX_SHAPER_IMPLEMENT (thai) \
HB_COMPLEX_SHAPER_IMPLEMENT (tibetan) \
HB_COMPLEX_SHAPER_IMPLEMENT (use) \
@ -285,7 +286,7 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
planner->map.language_index[0],
HB_TAG ('p','r','e','f'),
nullptr))
return &_hb_ot_complex_shaper_indic;
return &_hb_ot_complex_shaper_khmer;
else
return &_hb_ot_complex_shaper_default;

Просмотреть файл

@ -36,271 +36,288 @@
#line 38 "hb-ot-shape-complex-use-machine.hh"
static const unsigned char _use_syllable_machine_trans_keys[] = {
1u, 1u, 0u, 43u, 21u, 21u, 8u, 39u, 8u, 39u, 1u, 1u, 8u, 39u, 8u, 39u,
8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u,
1u, 1u, 12u, 12u, 1u, 15u, 1u, 15u, 1u, 1u, 12u, 12u, 0u, 43u, 21u, 21u,
8u, 39u, 8u, 39u, 1u, 15u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 26u, 8u, 26u,
8u, 26u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u,
8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 13u, 21u, 4u, 4u, 13u, 13u,
8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 26u, 8u, 26u, 8u, 26u, 8u, 39u,
8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u,
13u, 21u, 4u, 4u, 13u, 13u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 26u,
8u, 26u, 8u, 26u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u,
8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 8u, 39u, 1u, 1u, 1u, 39u, 8u, 39u,
21u, 42u, 41u, 42u, 42u, 42u, 1u, 5u, 0
8u, 39u, 8u, 39u, 1u, 15u, 12u, 12u, 1u, 39u, 8u, 39u, 21u, 42u, 41u, 42u,
42u, 42u, 1u, 5u, 0
};
static const char _use_syllable_machine_key_spans[] = {
1, 44, 1, 32, 32, 1, 32, 32,
32, 19, 19, 19, 32, 32, 32, 32,
1, 1, 15, 15, 1, 1, 44, 1,
32, 32, 15, 32, 32, 32, 19, 19,
19, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 9, 1, 1,
32, 32, 32, 32, 19, 19, 19, 32,
32, 32, 32, 32, 32, 32, 32, 32,
9, 1, 1, 32, 32, 32, 32, 19,
19, 19, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 1, 39, 32,
22, 2, 1, 5
32, 32, 15, 1, 39, 32, 22, 2,
1, 5
};
static const short _use_syllable_machine_index_offsets[] = {
0, 2, 47, 49, 82, 115, 117, 150,
183, 216, 236, 256, 276, 309, 342, 375,
408, 441, 474, 507, 540, 573, 606, 639,
672, 682, 684, 686, 719, 752, 785, 818,
838, 858, 878, 911, 944, 977, 1010, 1043,
1076, 1109, 1142, 1175, 1208, 1241, 1243, 1283,
1316, 1339, 1342, 1344
0, 2, 4, 20, 36, 38, 40, 85,
87, 120, 153, 169, 202, 235, 268, 288,
308, 328, 361, 394, 427, 460, 493, 526,
559, 592, 625, 658, 691, 724, 734, 736,
738, 771, 804, 837, 870, 890, 910, 930,
963, 996, 1029, 1062, 1095, 1128, 1161, 1194,
1227, 1260, 1293, 1309, 1311, 1351, 1384, 1407,
1410, 1412
};
static const char _use_syllable_machine_indicies[] = {
1, 0, 2, 3, 4, 2, 5, 3,
4, 4, 6, 4, 4, 1, 7, 4,
4, 4, 2, 2, 8, 9, 4, 4,
10, 11, 12, 13, 14, 15, 16, 10,
17, 18, 19, 20, 21, 22, 4, 23,
24, 25, 4, 4, 4, 26, 4, 28,
27, 30, 29, 29, 31, 32, 29, 29,
29, 29, 29, 29, 29, 29, 33, 34,
35, 36, 37, 38, 39, 40, 34, 41,
33, 42, 43, 44, 45, 29, 46, 47,
48, 29, 30, 29, 29, 31, 32, 29,
29, 29, 29, 29, 29, 29, 29, 49,
34, 35, 36, 37, 38, 39, 40, 34,
41, 42, 42, 43, 44, 45, 29, 46,
47, 48, 29, 31, 50, 30, 29, 29,
31, 32, 29, 29, 29, 29, 29, 29,
29, 29, 29, 34, 35, 36, 37, 38,
39, 40, 34, 41, 42, 42, 43, 44,
45, 29, 46, 47, 48, 29, 30, 29,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 34, 35, 36, 37,
38, 29, 29, 29, 29, 29, 29, 43,
44, 45, 29, 46, 47, 48, 29, 30,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 35, 36,
37, 38, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 46, 47, 48, 29,
30, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
36, 37, 38, 29, 30, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 37, 38, 29,
30, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 38, 29, 30, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 36, 37, 38, 29,
29, 29, 29, 29, 29, 29, 29, 29,
29, 46, 47, 48, 29, 30, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 36, 37, 38,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 47, 48, 29, 30, 29,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 36, 37,
38, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 48, 29, 30,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 35, 36,
37, 38, 29, 29, 29, 29, 29, 29,
43, 44, 45, 29, 46, 47, 48, 29,
30, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 35,
36, 37, 38, 29, 29, 29, 29, 29,
29, 29, 44, 45, 29, 46, 47, 48,
29, 30, 29, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
35, 36, 37, 38, 29, 29, 29, 29,
29, 29, 29, 29, 45, 29, 46, 47,
48, 29, 30, 29, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
34, 35, 36, 37, 38, 29, 40, 34,
29, 29, 29, 43, 44, 45, 29, 46,
47, 48, 29, 30, 29, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
29, 34, 35, 36, 37, 38, 29, 51,
34, 29, 29, 29, 43, 44, 45, 29,
46, 47, 48, 29, 30, 29, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 34, 35, 36, 37, 38, 29,
29, 34, 29, 29, 29, 43, 44, 45,
29, 46, 47, 48, 29, 30, 29, 29,
29, 29, 29, 29, 29, 29, 29, 29,
29, 29, 29, 34, 35, 36, 37, 38,
39, 40, 34, 29, 29, 29, 43, 44,
45, 29, 46, 47, 48, 29, 30, 29,
29, 31, 32, 29, 29, 29, 29, 29,
29, 29, 29, 29, 34, 35, 36, 37,
38, 39, 40, 34, 41, 29, 42, 43,
44, 45, 29, 46, 47, 48, 29, 30,
29, 29, 31, 32, 29, 29, 29, 29,
29, 29, 29, 29, 29, 34, 35, 36,
37, 38, 39, 40, 34, 41, 33, 42,
43, 44, 45, 29, 46, 47, 48, 29,
53, 52, 52, 52, 52, 52, 52, 52,
54, 52, 5, 55, 53, 52, 6, 56,
56, 1, 57, 56, 56, 56, 56, 56,
56, 56, 56, 58, 10, 11, 12, 13,
14, 15, 16, 10, 17, 19, 19, 20,
21, 22, 56, 23, 24, 25, 56, 6,
56, 56, 1, 57, 56, 56, 56, 56,
56, 56, 56, 56, 56, 10, 11, 12,
13, 14, 15, 16, 10, 17, 19, 19,
20, 21, 22, 56, 23, 24, 25, 56,
6, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 10, 11,
12, 13, 14, 56, 56, 56, 56, 56,
56, 20, 21, 22, 56, 23, 24, 25,
56, 6, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56,
11, 12, 13, 14, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 23, 24,
25, 56, 6, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 12, 13, 14, 56, 6, 56,
56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 13,
14, 56, 6, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 14, 56, 6, 56,
56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 12, 13,
14, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 23, 24, 25, 56, 6,
56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 12,
13, 14, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 24, 25, 56,
6, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56,
12, 13, 14, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 25,
56, 6, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56,
11, 12, 13, 14, 56, 56, 56, 56,
56, 56, 20, 21, 22, 56, 23, 24,
25, 56, 6, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56,
56, 11, 12, 13, 14, 56, 56, 56,
56, 56, 56, 56, 21, 22, 56, 23,
24, 25, 56, 6, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 11, 12, 13, 14, 56, 56,
56, 56, 56, 56, 56, 56, 22, 56,
23, 24, 25, 56, 6, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 10, 11, 12, 13, 14, 56,
16, 10, 56, 56, 56, 20, 21, 22,
56, 23, 24, 25, 56, 6, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 10, 11, 12, 13, 14,
56, 59, 10, 56, 56, 56, 20, 21,
22, 56, 23, 24, 25, 56, 6, 56,
56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 10, 11, 12, 13,
14, 56, 56, 10, 56, 56, 56, 20,
21, 22, 56, 23, 24, 25, 56, 6,
56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 10, 11, 12,
13, 14, 15, 16, 10, 56, 56, 56,
20, 21, 22, 56, 23, 24, 25, 56,
6, 56, 56, 1, 57, 56, 56, 56,
56, 56, 56, 56, 56, 56, 10, 11,
12, 13, 14, 15, 16, 10, 17, 56,
19, 20, 21, 22, 56, 23, 24, 25,
56, 1, 60, 3, 56, 56, 56, 3,
56, 56, 6, 56, 56, 1, 57, 56,
56, 56, 56, 56, 56, 56, 56, 56,
10, 11, 12, 13, 14, 15, 16, 10,
17, 18, 19, 20, 21, 22, 56, 23,
24, 25, 56, 6, 56, 56, 1, 57,
56, 56, 56, 56, 56, 56, 56, 56,
56, 10, 11, 12, 13, 14, 15, 16,
10, 17, 18, 19, 20, 21, 22, 56,
23, 24, 25, 56, 62, 61, 61, 61,
61, 61, 61, 61, 61, 61, 61, 61,
61, 61, 61, 61, 61, 61, 61, 61,
62, 63, 61, 62, 63, 61, 63, 61,
3, 60, 60, 60, 3, 60, 0
1, 0, 3, 2, 1, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 4, 2, 5, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 6, 0, 5, 0, 8, 7,
9, 10, 11, 9, 12, 10, 11, 11,
13, 11, 11, 5, 14, 11, 11, 15,
9, 9, 16, 17, 11, 11, 18, 19,
20, 21, 22, 23, 24, 18, 25, 26,
27, 28, 29, 30, 11, 31, 32, 33,
11, 11, 11, 34, 11, 36, 35, 38,
37, 37, 1, 39, 37, 37, 40, 37,
37, 37, 37, 37, 41, 42, 43, 44,
45, 46, 47, 48, 42, 49, 41, 50,
51, 52, 53, 37, 54, 55, 56, 37,
38, 37, 37, 1, 39, 37, 37, 40,
37, 37, 37, 37, 37, 57, 42, 43,
44, 45, 46, 47, 48, 42, 49, 50,
50, 51, 52, 53, 37, 54, 55, 56,
37, 1, 58, 58, 58, 58, 58, 58,
58, 58, 58, 58, 58, 58, 58, 4,
58, 38, 37, 37, 1, 39, 37, 37,
40, 37, 37, 37, 37, 37, 37, 42,
43, 44, 45, 46, 47, 48, 42, 49,
50, 50, 51, 52, 53, 37, 54, 55,
56, 37, 38, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37,
42, 43, 44, 45, 46, 37, 37, 37,
37, 37, 37, 51, 52, 53, 37, 54,
55, 56, 37, 38, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 43, 44, 45, 46, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37,
54, 55, 56, 37, 38, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 44, 45, 46, 37,
38, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37,
37, 45, 46, 37, 38, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 46, 37,
38, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37,
44, 45, 46, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 54, 55, 56,
37, 38, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37,
37, 44, 45, 46, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 55,
56, 37, 38, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 44, 45, 46, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37,
37, 56, 37, 38, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 43, 44, 45, 46, 37, 37,
37, 37, 37, 37, 51, 52, 53, 37,
54, 55, 56, 37, 38, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 43, 44, 45, 46, 37,
37, 37, 37, 37, 37, 37, 52, 53,
37, 54, 55, 56, 37, 38, 37, 37,
37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 43, 44, 45, 46,
37, 37, 37, 37, 37, 37, 37, 37,
53, 37, 54, 55, 56, 37, 38, 37,
37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 42, 43, 44, 45,
46, 37, 48, 42, 37, 37, 37, 51,
52, 53, 37, 54, 55, 56, 37, 38,
37, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 42, 43, 44,
45, 46, 37, 59, 42, 37, 37, 37,
51, 52, 53, 37, 54, 55, 56, 37,
38, 37, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 42, 43,
44, 45, 46, 37, 37, 42, 37, 37,
37, 51, 52, 53, 37, 54, 55, 56,
37, 38, 37, 37, 37, 37, 37, 37,
37, 37, 37, 37, 37, 37, 37, 42,
43, 44, 45, 46, 47, 48, 42, 37,
37, 37, 51, 52, 53, 37, 54, 55,
56, 37, 38, 37, 37, 1, 39, 37,
37, 40, 37, 37, 37, 37, 37, 37,
42, 43, 44, 45, 46, 47, 48, 42,
49, 37, 50, 51, 52, 53, 37, 54,
55, 56, 37, 38, 37, 37, 1, 39,
37, 37, 40, 37, 37, 37, 37, 37,
37, 42, 43, 44, 45, 46, 47, 48,
42, 49, 41, 50, 51, 52, 53, 37,
54, 55, 56, 37, 61, 60, 60, 60,
60, 60, 60, 60, 62, 60, 12, 63,
61, 60, 13, 64, 64, 5, 8, 64,
64, 65, 64, 64, 64, 64, 64, 66,
18, 19, 20, 21, 22, 23, 24, 18,
25, 27, 27, 28, 29, 30, 64, 31,
32, 33, 64, 13, 64, 64, 5, 8,
64, 64, 65, 64, 64, 64, 64, 64,
64, 18, 19, 20, 21, 22, 23, 24,
18, 25, 27, 27, 28, 29, 30, 64,
31, 32, 33, 64, 13, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 18, 19, 20, 21, 22, 64,
64, 64, 64, 64, 64, 28, 29, 30,
64, 31, 32, 33, 64, 13, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 19, 20, 21, 22,
64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 31, 32, 33, 64, 13, 64,
64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 20, 21,
22, 64, 13, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 21, 22, 64, 13, 64,
64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64,
22, 64, 13, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 20, 21, 22, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 31,
32, 33, 64, 13, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 20, 21, 22, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64,
64, 32, 33, 64, 13, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 20, 21, 22, 64,
64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 33, 64, 13, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 19, 20, 21, 22,
64, 64, 64, 64, 64, 64, 28, 29,
30, 64, 31, 32, 33, 64, 13, 64,
64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 19, 20, 21,
22, 64, 64, 64, 64, 64, 64, 64,
29, 30, 64, 31, 32, 33, 64, 13,
64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 19, 20,
21, 22, 64, 64, 64, 64, 64, 64,
64, 64, 30, 64, 31, 32, 33, 64,
13, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 18, 19,
20, 21, 22, 64, 24, 18, 64, 64,
64, 28, 29, 30, 64, 31, 32, 33,
64, 13, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 18,
19, 20, 21, 22, 64, 67, 18, 64,
64, 64, 28, 29, 30, 64, 31, 32,
33, 64, 13, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64,
18, 19, 20, 21, 22, 64, 64, 18,
64, 64, 64, 28, 29, 30, 64, 31,
32, 33, 64, 13, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64,
64, 18, 19, 20, 21, 22, 23, 24,
18, 64, 64, 64, 28, 29, 30, 64,
31, 32, 33, 64, 13, 64, 64, 5,
8, 64, 64, 65, 64, 64, 64, 64,
64, 64, 18, 19, 20, 21, 22, 23,
24, 18, 25, 64, 27, 28, 29, 30,
64, 31, 32, 33, 64, 5, 68, 68,
68, 68, 68, 68, 68, 68, 68, 68,
68, 68, 68, 6, 68, 8, 68, 10,
64, 64, 64, 10, 64, 64, 13, 64,
64, 5, 8, 64, 64, 65, 64, 64,
64, 64, 64, 64, 18, 19, 20, 21,
22, 23, 24, 18, 25, 26, 27, 28,
29, 30, 64, 31, 32, 33, 64, 13,
64, 64, 5, 8, 64, 64, 65, 64,
64, 64, 64, 64, 64, 18, 19, 20,
21, 22, 23, 24, 18, 25, 26, 27,
28, 29, 30, 64, 31, 32, 33, 64,
70, 69, 69, 69, 69, 69, 69, 69,
69, 69, 69, 69, 69, 69, 69, 69,
69, 69, 69, 69, 70, 71, 69, 70,
71, 69, 71, 69, 10, 68, 68, 68,
10, 68, 0
};
static const char _use_syllable_machine_trans_targs[] = {
1, 27, 2, 3, 1, 24, 1, 45,
46, 48, 29, 30, 31, 32, 33, 40,
41, 43, 47, 44, 37, 38, 39, 34,
35, 36, 51, 1, 1, 1, 1, 4,
5, 23, 7, 8, 9, 10, 11, 18,
19, 21, 22, 15, 16, 17, 12, 13,
14, 6, 1, 20, 1, 25, 26, 1,
1, 0, 28, 42, 1, 1, 49, 50
6, 9, 6, 2, 0, 32, 4, 6,
3, 7, 8, 6, 29, 6, 50, 51,
52, 54, 34, 35, 36, 37, 38, 45,
46, 48, 53, 49, 42, 43, 44, 39,
40, 41, 57, 6, 6, 6, 6, 10,
1, 28, 12, 13, 14, 15, 16, 23,
24, 26, 27, 20, 21, 22, 17, 18,
19, 11, 6, 25, 6, 30, 31, 6,
6, 5, 33, 47, 6, 6, 55, 56
};
static const char _use_syllable_machine_trans_actions[] = {
1, 2, 0, 0, 5, 0, 6, 0,
2, 0, 0, 0, 0, 0, 0, 0,
0, 0, 2, 2, 0, 0, 0, 0,
0, 0, 0, 7, 8, 9, 10, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 11, 0, 12, 0, 0, 13,
14, 0, 2, 0, 15, 16, 0, 0
1, 2, 3, 0, 0, 4, 0, 5,
0, 0, 2, 8, 0, 9, 10, 10,
4, 0, 0, 0, 0, 0, 0, 0,
0, 0, 4, 4, 0, 0, 0, 0,
0, 0, 0, 11, 12, 13, 14, 15,
0, 2, 0, 0, 0, 0, 0, 0,
0, 0, 2, 0, 0, 0, 0, 0,
0, 2, 16, 0, 17, 0, 0, 18,
19, 0, 4, 0, 20, 21, 0, 0
};
static const char _use_syllable_machine_to_state_actions[] = {
0, 3, 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, 0,
0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0,
0, 0
};
static const char _use_syllable_machine_from_state_actions[] = {
0, 4, 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, 0,
0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0,
0, 0
};
static const short _use_syllable_machine_eof_trans[] = {
1, 0, 28, 30, 30, 51, 30, 30,
30, 30, 30, 30, 30, 30, 30, 30,
30, 30, 30, 30, 30, 30, 30, 30,
53, 56, 53, 57, 57, 57, 57, 57,
57, 57, 57, 57, 57, 57, 57, 57,
57, 57, 57, 57, 57, 61, 57, 57,
62, 62, 62, 61
1, 3, 3, 1, 1, 8, 0, 36,
38, 38, 59, 38, 38, 38, 38, 38,
38, 38, 38, 38, 38, 38, 38, 38,
38, 38, 38, 38, 38, 61, 64, 61,
65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 65, 65, 65, 65, 65, 65,
65, 65, 69, 69, 65, 65, 70, 70,
70, 69
};
static const int use_syllable_machine_start = 1;
static const int use_syllable_machine_first_final = 1;
static const int use_syllable_machine_start = 6;
static const int use_syllable_machine_first_final = 6;
static const int use_syllable_machine_error = -1;
static const int use_syllable_machine_en_main = 1;
static const int use_syllable_machine_en_main = 6;
#line 38 "hb-ot-shape-complex-use-machine.rl"
#line 140 "hb-ot-shape-complex-use-machine.rl"
#line 141 "hb-ot-shape-complex-use-machine.rl"
#define found_syllable(syllable_type) \
@ -320,7 +337,7 @@ find_syllables (hb_buffer_t *buffer)
int cs;
hb_glyph_info_t *info = buffer->info;
#line 324 "hb-ot-shape-complex-use-machine.hh"
#line 341 "hb-ot-shape-complex-use-machine.hh"
{
cs = use_syllable_machine_start;
ts = 0;
@ -328,7 +345,7 @@ find_syllables (hb_buffer_t *buffer)
act = 0;
}
#line 161 "hb-ot-shape-complex-use-machine.rl"
#line 162 "hb-ot-shape-complex-use-machine.rl"
p = 0;
@ -337,7 +354,7 @@ find_syllables (hb_buffer_t *buffer)
unsigned int last = 0;
unsigned int syllable_serial = 1;
#line 341 "hb-ot-shape-complex-use-machine.hh"
#line 358 "hb-ot-shape-complex-use-machine.hh"
{
int _slen;
int _trans;
@ -347,11 +364,11 @@ find_syllables (hb_buffer_t *buffer)
goto _test_eof;
_resume:
switch ( _use_syllable_machine_from_state_actions[cs] ) {
case 4:
case 7:
#line 1 "NONE"
{ts = p;}
break;
#line 355 "hb-ot-shape-complex-use-machine.hh"
#line 372 "hb-ot-shape-complex-use-machine.hh"
}
_keys = _use_syllable_machine_trans_keys + (cs<<1);
@ -369,72 +386,114 @@ _eof_trans:
goto _again;
switch ( _use_syllable_machine_trans_actions[_trans] ) {
case 2:
#line 1 "NONE"
{te = p+1;}
break;
case 8:
#line 129 "hb-ot-shape-complex-use-machine.rl"
case 12:
#line 130 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (independent_cluster); }}
break;
case 10:
#line 131 "hb-ot-shape-complex-use-machine.rl"
case 14:
#line 132 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (standard_cluster); }}
break;
case 6:
#line 135 "hb-ot-shape-complex-use-machine.rl"
case 9:
#line 136 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (broken_cluster); }}
break;
case 5:
#line 136 "hb-ot-shape-complex-use-machine.rl"
case 8:
#line 137 "hb-ot-shape-complex-use-machine.rl"
{te = p+1;{ found_syllable (non_cluster); }}
break;
case 7:
#line 129 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (independent_cluster); }}
break;
case 11:
#line 130 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (virama_terminated_cluster); }}
{te = p;p--;{ found_syllable (independent_cluster); }}
break;
case 9:
case 16:
#line 131 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (standard_cluster); }}
{te = p;p--;{ found_syllable (virama_terminated_cluster); }}
break;
case 13:
#line 132 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (standard_cluster); }}
break;
case 18:
#line 133 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (number_joiner_terminated_cluster); }}
break;
case 12:
#line 133 "hb-ot-shape-complex-use-machine.rl"
case 17:
#line 134 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (numeral_cluster); }}
break;
case 16:
#line 134 "hb-ot-shape-complex-use-machine.rl"
case 21:
#line 135 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (symbol_cluster); }}
break;
case 14:
#line 135 "hb-ot-shape-complex-use-machine.rl"
case 19:
#line 136 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (broken_cluster); }}
break;
case 15:
#line 136 "hb-ot-shape-complex-use-machine.rl"
case 20:
#line 137 "hb-ot-shape-complex-use-machine.rl"
{te = p;p--;{ found_syllable (non_cluster); }}
break;
case 1:
#line 135 "hb-ot-shape-complex-use-machine.rl"
case 3:
#line 132 "hb-ot-shape-complex-use-machine.rl"
{{p = ((te))-1;}{ found_syllable (standard_cluster); }}
break;
case 5:
#line 136 "hb-ot-shape-complex-use-machine.rl"
{{p = ((te))-1;}{ found_syllable (broken_cluster); }}
break;
#line 429 "hb-ot-shape-complex-use-machine.hh"
case 1:
#line 1 "NONE"
{ switch( act ) {
case 2:
{{p = ((te))-1;} found_syllable (virama_terminated_cluster); }
break;
case 3:
{{p = ((te))-1;} found_syllable (standard_cluster); }
break;
case 7:
{{p = ((te))-1;} found_syllable (broken_cluster); }
break;
case 8:
{{p = ((te))-1;} found_syllable (non_cluster); }
break;
}
}
break;
case 15:
#line 1 "NONE"
{te = p+1;}
#line 131 "hb-ot-shape-complex-use-machine.rl"
{act = 2;}
break;
case 2:
#line 1 "NONE"
{te = p+1;}
#line 132 "hb-ot-shape-complex-use-machine.rl"
{act = 3;}
break;
case 4:
#line 1 "NONE"
{te = p+1;}
#line 136 "hb-ot-shape-complex-use-machine.rl"
{act = 7;}
break;
case 10:
#line 1 "NONE"
{te = p+1;}
#line 137 "hb-ot-shape-complex-use-machine.rl"
{act = 8;}
break;
#line 488 "hb-ot-shape-complex-use-machine.hh"
}
_again:
switch ( _use_syllable_machine_to_state_actions[cs] ) {
case 3:
case 6:
#line 1 "NONE"
{ts = 0;}
break;
#line 438 "hb-ot-shape-complex-use-machine.hh"
#line 497 "hb-ot-shape-complex-use-machine.hh"
}
if ( ++p != pe )
@ -450,7 +509,7 @@ _again:
}
#line 170 "hb-ot-shape-complex-use-machine.rl"
#line 171 "hb-ot-shape-complex-use-machine.rl"
}

Просмотреть файл

@ -89,7 +89,8 @@ SMBlw = 42; # SYM_MOD_BELOW
CS = 43; # CONS_WITH_STACKER
consonant_modifiers = CMAbv* CMBlw* ((H B | SUB) VS? CMAbv? CMBlw*)*;
# Override: Adjoc ZWJ placement. https://github.com/harfbuzz/harfbuzz/issues/542#issuecomment-353169729
consonant_modifiers = CMAbv* CMBlw* ((ZWJ?.H.ZWJ? B | SUB) VS? CMAbv? CMBlw*)*;
# Override: Allow two MBlw. https://github.com/harfbuzz/harfbuzz/issues/376
medial_consonants = MPre? MAbv? MBlw?.MBlw? MPst?;
dependent_vowels = VPre* VAbv* VBlw* VPst*;

Просмотреть файл

@ -75,7 +75,13 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 00C0 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* 00D0 */ O, O, O, O, O, O, O, GB,
#define use_offset_0x0900u 80
#define use_offset_0x0348u 80
/* Combining Diacritical Marks */
O, O, O, O, O, O, O, CGJ,
#define use_offset_0x0900u 88
/* Devanagari */
@ -188,7 +194,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 0DE0 */ O, O, O, O, O, O, B, B, B, B, B, B, B, B, B, B,
/* 0DF0 */ O, O, VPst, VPst, O, O, O, O,
#define use_offset_0x1000u 1352
#define use_offset_0x1000u 1360
/* Myanmar */
@ -204,7 +210,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1080 */ B, B, MBlw, VPst, VPre, VAbv, VAbv, VMPst, VMPst, VMPst, VMPst, VMPst, VMPst, VMBlw, B, VMPst,
/* 1090 */ B, B, B, B, B, B, B, B, B, B, VMPst, VMPst, VPst, VAbv, O, O,
#define use_offset_0x1700u 1512
#define use_offset_0x1700u 1520
/* Tagalog */
@ -237,7 +243,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 17D0 */ FM, VAbv, H, FM, O, O, O, O, O, O, O, O, B, VAbv, O, O,
/* 17E0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x1900u 1752
#define use_offset_0x1900u 1760
/* Limbu */
@ -281,7 +287,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1A80 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
/* 1A90 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x1b00u 2168
#define use_offset_0x1b00u 2176
/* Balinese */
@ -307,7 +313,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1BC0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1BD0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 1BE0 */ B, B, B, B, B, B, CMAbv, VPst, VAbv, VAbv, VPst, VPst, VPst, VAbv, VPst, VAbv,
/* 1BF0 */ FAbv, FAbv, VPst, VPst, O, O, O, O, O, O, O, O, O, O, O, O,
/* 1BF0 */ FAbv, FAbv, CMBlw, CMBlw, O, O, O, O, O, O, O, O, O, O, O, O,
/* Lepcha */
@ -317,7 +323,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1C30 */ FAbv, FAbv, FAbv, FAbv, VMPre, VMPre, FM, CMBlw, O, O, O, O, O, O, O, O,
/* 1C40 */ B, B, B, B, B, B, B, B, B, B, O, O, O, B, B, B,
#define use_offset_0x1cd0u 2504
#define use_offset_0x1cd0u 2512
/* Vedic Extensions */
@ -326,20 +332,20 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 1CE0 */ VMAbv, VMPst, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, VMBlw, O, O, O, O, VMBlw, O, O,
/* 1CF0 */ O, O, VMPst, VMPst, VMAbv, O, O, VMPst, VMAbv, VMAbv, O, O, O, O, O, O,
#define use_offset_0x1df8u 2552
#define use_offset_0x1df8u 2560
/* Combining Diacritical Marks Supplement */
O, O, O, FM, O, O, O, O,
#define use_offset_0x2008u 2560
#define use_offset_0x2008u 2568
/* General Punctuation */
O, O, O, O, ZWNJ, ZWJ, O, O,
/* 2010 */ GB, GB, GB, GB, GB, O, O, O,
#define use_offset_0x2060u 2576
#define use_offset_0x2060u 2584
/* 2060 */ WJ, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
@ -348,14 +354,20 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 2070 */ O, O, O, O, FM, O, O, O, O, O, O, O, O, O, O, O,
/* 2080 */ O, O, FM, FM, FM, O, O, O,
#define use_offset_0x20f0u 2616
#define use_offset_0x20f0u 2624
/* Combining Diacritical Marks for Symbols */
/* 20F0 */ VMAbv, O, O, O, O, O, O, O,
#define use_offset_0xa800u 2624
#define use_offset_0x25c8u 2632
/* Geometric Shapes */
O, O, O, O, GB, O, O, O,
#define use_offset_0xa800u 2640
/* Syloti Nagri */
@ -442,7 +454,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* AAE0 */ B, B, B, B, B, B, B, B, B, B, B, VPre, VBlw, VAbv, VPre, VPst,
/* AAF0 */ O, O, O, O, O, VMPst, H, O,
#define use_offset_0xabc0u 3384
#define use_offset_0xabc0u 3400
/* Meetei Mayek */
@ -452,14 +464,14 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* ABE0 */ B, B, B, VPst, VPst, VAbv, VPst, VPst, VBlw, VPst, VPst, O, VMPst, VBlw, O, O,
/* ABF0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0xfe00u 3448
#define use_offset_0xfe00u 3464
/* Variation Selectors */
/* FE00 */ VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS, VS,
#define use_offset_0x10a00u 3464
#define use_offset_0x10a00u 3480
/* Kharoshthi */
@ -470,7 +482,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 10A30 */ B, B, B, B, O, O, O, O, CMAbv, CMBlw, CMBlw, O, O, O, O, H,
/* 10A40 */ B, B, B, B, B, B, B, B,
#define use_offset_0x11000u 3536
#define use_offset_0x11000u 3552
/* Brahmi */
@ -482,7 +494,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11040 */ VBlw, VBlw, VAbv, VAbv, VAbv, VAbv, H, O, O, O, O, O, O, O, O, O,
/* 11050 */ O, O, N, N, N, N, N, N, N, N, N, N, N, N, N, N,
/* 11060 */ N, N, N, N, N, N, B, B, B, B, B, B, B, B, B, B,
/* 11070 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, O,
/* 11070 */ O, O, O, O, O, O, O, O, O, O, O, O, O, O, O, HN,
/* Kaithi */
@ -491,7 +503,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 110A0 */ B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B,
/* 110B0 */ VPst, VPre, VPst, VBlw, VBlw, VAbv, VAbv, VPst, VPst, H, CMBlw, O, O, O, O, O,
#define use_offset_0x11100u 3728
#define use_offset_0x11100u 3744
/* Chakma */
@ -529,7 +541,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11220 */ B, B, B, B, B, B, B, B, B, B, B, B, VPst, VPst, VPst, VBlw,
/* 11230 */ VAbv, VAbv, VAbv, VAbv, VMAbv, H, CMAbv, CMAbv, O, O, O, O, O, O, VMAbv, O,
#define use_offset_0x11280u 4048
#define use_offset_0x11280u 4064
/* Multani */
@ -557,7 +569,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11360 */ B, B, VPst, VPst, O, O, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O,
/* 11370 */ VMAbv, VMAbv, VMAbv, VMAbv, VMAbv, O, O, O,
#define use_offset_0x11400u 4296
#define use_offset_0x11400u 4312
/* Newa */
@ -580,7 +592,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 114C0 */ VMAbv, VMPst, H, CMBlw, B, O, O, O, O, O, O, O, O, O, O, O,
/* 114D0 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
#define use_offset_0x11580u 4520
#define use_offset_0x11580u 4536
/* Siddham */
@ -623,7 +635,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11720 */ VPst, VPst, VAbv, VAbv, VBlw, VBlw, VPre, VAbv, VBlw, VAbv, VAbv, VAbv, O, O, O, O,
/* 11730 */ B, B, B, B, B, B, B, B, B, B, B, B, O, O, O, O,
#define use_offset_0x11a00u 4968
#define use_offset_0x11a00u 4984
/* Zanabazar Square */
@ -642,7 +654,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11A80 */ B, B, B, B, O, O, R, R, R, R, FBlw, FBlw, FBlw, FBlw, FBlw, FBlw,
/* 11A90 */ FBlw, FBlw, FBlw, FBlw, FBlw, FBlw, VMAbv, VMPst, CMAbv, H, O, O, O, O, O, O,
#define use_offset_0x11c00u 5128
#define use_offset_0x11c00u 5144
/* Bhaiksuki */
@ -663,7 +675,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11CA0 */ SUB, SUB, SUB, SUB, SUB, SUB, SUB, SUB, O, SUB, SUB, SUB, SUB, SUB, SUB, SUB,
/* 11CB0 */ VBlw, VPre, VBlw, VAbv, VPst, VMAbv, VMAbv, O,
#define use_offset_0x11d00u 5312
#define use_offset_0x11d00u 5328
/* Masaram Gondi */
@ -675,7 +687,7 @@ static const USE_TABLE_ELEMENT_TYPE use_table[] = {
/* 11D40 */ VMAbv, VMAbv, CMBlw, VAbv, VBlw, H, R, MBlw, O, O, O, O, O, O, O, O,
/* 11D50 */ B, B, B, B, B, B, B, B, B, B, O, O, O, O, O, O,
}; /* Table items: 5408; occupancy: 73% */
}; /* Table items: 5424; occupancy: 73% */
USE_TABLE_ELEMENT_TYPE
hb_use_get_categories (hb_codepoint_t u)
@ -685,8 +697,8 @@ hb_use_get_categories (hb_codepoint_t u)
case 0x0u:
if (hb_in_range<hb_codepoint_t> (u, 0x0028u, 0x003Fu)) return use_table[u - 0x0028u + use_offset_0x0028u];
if (hb_in_range<hb_codepoint_t> (u, 0x00A0u, 0x00D7u)) return use_table[u - 0x00A0u + use_offset_0x00a0u];
if (hb_in_range<hb_codepoint_t> (u, 0x0348u, 0x034Fu)) return use_table[u - 0x0348u + use_offset_0x0348u];
if (hb_in_range<hb_codepoint_t> (u, 0x0900u, 0x0DF7u)) return use_table[u - 0x0900u + use_offset_0x0900u];
if (unlikely (u == 0x034Fu)) return CGJ;
break;
case 0x1u:
@ -702,7 +714,7 @@ hb_use_get_categories (hb_codepoint_t u)
if (hb_in_range<hb_codepoint_t> (u, 0x2008u, 0x2017u)) return use_table[u - 0x2008u + use_offset_0x2008u];
if (hb_in_range<hb_codepoint_t> (u, 0x2060u, 0x2087u)) return use_table[u - 0x2060u + use_offset_0x2060u];
if (hb_in_range<hb_codepoint_t> (u, 0x20F0u, 0x20F7u)) return use_table[u - 0x20F0u + use_offset_0x20f0u];
if (unlikely (u == 0x25CCu)) return GB;
if (hb_in_range<hb_codepoint_t> (u, 0x25C8u, 0x25CFu)) return use_table[u - 0x25C8u + use_offset_0x25c8u];
break;
case 0xAu:
@ -727,7 +739,6 @@ hb_use_get_categories (hb_codepoint_t u)
if (hb_in_range<hb_codepoint_t> (u, 0x11A00u, 0x11A9Fu)) return use_table[u - 0x11A00u + use_offset_0x11a00u];
if (hb_in_range<hb_codepoint_t> (u, 0x11C00u, 0x11CB7u)) return use_table[u - 0x11C00u + use_offset_0x11c00u];
if (hb_in_range<hb_codepoint_t> (u, 0x11D00u, 0x11D5Fu)) return use_table[u - 0x11D00u + use_offset_0x11d00u];
if (unlikely (u == 0x1107Fu)) return HN;
break;
default:

Просмотреть файл

@ -442,10 +442,10 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
{
if (!plan->has_kern) return;
OT::hb_apply_context_t c (1, font, buffer);
OT::hb_ot_apply_context_t c (1, font, buffer);
c.set_lookup_mask (plan->kern_mask);
c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
OT::hb_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input;
OT::hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input;
skippy_iter.init (&c);
unsigned int count = buffer->len;
@ -473,6 +473,7 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
pos[idx].x_advance += kern1;
pos[skippy_iter.idx].x_advance += kern2;
pos[skippy_iter.idx].x_offset += kern2;
buffer->unsafe_to_break (idx, skippy_iter.idx + 1);
}
if (y_kern)
@ -482,6 +483,7 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
pos[idx].y_advance += kern1;
pos[skippy_iter.idx].y_advance += kern2;
pos[skippy_iter.idx].y_offset += kern2;
buffer->unsafe_to_break (idx, skippy_iter.idx + 1);
}
idx = skippy_iter.idx;

Просмотреть файл

@ -345,9 +345,8 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0)
break;
/* We are going to do a O(n^2). Only do this if the sequence is short,
* but not too short ;). */
if (end - i < 2 || end - i > HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS) {
/* We are going to do a O(n^2). Only do this if the sequence is short. */
if (end - i > HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS) {
i = end;
continue;
}
@ -373,13 +372,11 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
buffer->clear_output ();
count = buffer->len;
unsigned int starter = 0;
bool combine = true;
buffer->next_glyph ();
while (buffer->idx < count && !buffer->in_error)
{
hb_codepoint_t composed, glyph;
if (combine &&
/* We don't try to compose a non-mark character with it's preceding starter.
if (/* We don't try to compose a non-mark character with it's preceding starter.
* This is both an optimization to avoid trying to compose every two neighboring
* glyphs in most scripts AND a desired feature for Hangul. Apparently Hangul
* fonts are not designed to mix-and-match pre-composed syllables and Jamo. */
@ -410,22 +407,27 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
continue;
}
else if (/* We sometimes custom-tailor the sorted order of marks. In that case, stop
* trying to combine as soon as combining-class drops. */
starter < buffer->out_len - 1 &&
info_cc (buffer->prev()) > info_cc (buffer->cur()))
combine = false;
}
/* Blocked, or doesn't compose. */
buffer->next_glyph ();
if (info_cc (buffer->prev()) == 0)
{
starter = buffer->out_len - 1;
combine = true;
}
}
buffer->swap_buffers ();
if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_CGJ)
{
/* For all CGJ, check if it prevented any reordering at all.
* If it did NOT, then make it skippable.
* https://github.com/harfbuzz/harfbuzz/issues/554
*/
for (unsigned int i = 1; i + 1 < buffer->len; i++)
if (buffer->info[i].codepoint == 0x034Fu/*CGJ*/ &&
info_cc(buffer->info[i-1]) <= info_cc(buffer->info[i+1]))
{
_hb_glyph_info_unhide (&buffer->info[i]);
}
}
}

Просмотреть файл

@ -40,6 +40,8 @@
#include "hb-unicode-private.hh"
#include "hb-set-private.hh"
#include "hb-ot-layout-gsubgpos-private.hh"
#include "hb-aat-layout-private.hh"
static hb_tag_t common_features[] = {
HB_TAG('c','c','m','p'),
@ -450,7 +452,8 @@ hb_ot_zero_width_default_ignorables (hb_ot_shape_context_t *c)
hb_buffer_t *buffer = c->buffer;
if (!(buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_DEFAULT_IGNORABLES) ||
(buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES))
(buffer->flags & HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES) ||
(buffer->flags & HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES))
return;
unsigned int count = buffer->len;
@ -486,7 +489,8 @@ hb_ot_hide_default_ignorables (hb_ot_shape_context_t *c)
return;
hb_codepoint_t space;
if (c->font->get_nominal_glyph (' ', &space))
if (!(buffer->flags & HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES) &&
c->font->get_nominal_glyph (' ', &space))
{
/* Replace default-ignorables with a zero-advance space glyph. */
for (/*continue*/; i < count; i++)
@ -614,7 +618,8 @@ hb_ot_substitute_complex (hb_ot_shape_context_t *c)
c->plan->substitute (c->font, buffer);
return;
/* XXX Call morx instead. */
//hb_aat_layout_substitute (c->font, c->buffer);
}
static inline void

Просмотреть файл

@ -133,8 +133,8 @@ struct avar
protected:
FixedVersion<>version; /* Version of the avar table
* initially set to 0x00010000u */
UINT16 reserved; /* This field is permanently reserved. Set to 0. */
UINT16 axisCount; /* The number of variation axes in the font. This
HBUINT16 reserved; /* This field is permanently reserved. Set to 0. */
HBUINT16 axisCount; /* The number of variation axes in the font. This
* must be the same number as axisCount in the
* 'fvar' table. */
SegmentMaps axisSegmentMapsZ;

Просмотреть файл

@ -42,11 +42,11 @@ struct InstanceRecord
}
protected:
UINT16 subfamilyNameID;/* The name ID for entries in the 'name' table
HBUINT16 subfamilyNameID;/* The name ID for entries in the 'name' table
* that provide subfamily names for this instance. */
UINT16 reserved; /* Reserved for future use — set to 0. */
HBUINT16 reserved; /* Reserved for future use — set to 0. */
Fixed coordinates[VAR];/* The coordinates array for this instance. */
//UINT16 postScriptNameIDX;/*Optional. The name ID for entries in the 'name'
//HBUINT16 postScriptNameIDX;/*Optional. The name ID for entries in the 'name'
// * table that provide PostScript names for this
// * instance. */
@ -67,8 +67,8 @@ struct AxisRecord
Fixed minValue; /* The minimum coordinate value for the axis. */
Fixed defaultValue; /* The default coordinate value for the axis. */
Fixed maxValue; /* The maximum coordinate value for the axis. */
UINT16 reserved; /* Reserved for future use — set to 0. */
UINT16 axisNameID; /* The name ID for entries in the 'name' table that
HBUINT16 reserved; /* Reserved for future use — set to 0. */
HBUINT16 axisNameID; /* The name ID for entries in the 'name' table that
* provide a display name for this axis. */
public:
@ -188,14 +188,14 @@ struct fvar
* initially set to 0x00010000u */
Offset16 things; /* Offset in bytes from the beginning of the table
* to the start of the AxisRecord array. */
UINT16 reserved; /* This field is permanently reserved. Set to 2. */
UINT16 axisCount; /* The number of variation axes in the font (the
HBUINT16 reserved; /* This field is permanently reserved. Set to 2. */
HBUINT16 axisCount; /* The number of variation axes in the font (the
* number of records in the axes array). */
UINT16 axisSize; /* The size in bytes of each VariationAxisRecord —
HBUINT16 axisSize; /* The size in bytes of each VariationAxisRecord —
* set to 20 (0x0014) for this version. */
UINT16 instanceCount; /* The number of named instances defined in the font
HBUINT16 instanceCount; /* The number of named instances defined in the font
* (the number of records in the instances array). */
UINT16 instanceSize; /* The size in bytes of each InstanceRecord — set
HBUINT16 instanceSize; /* The size in bytes of each InstanceRecord — set
* to either axisCount * sizeof(Fixed) + 4, or to
* axisCount * sizeof(Fixed) + 6. */

Просмотреть файл

@ -55,7 +55,7 @@ struct DeltaSetIndexMap
unsigned int u = 0;
{ /* Fetch it. */
unsigned int w = get_width ();
const UINT8 *p = mapData + w * v;
const HBUINT8 *p = mapData + w * v;
for (; w; w--)
u = (u << 8) + *p++;
}
@ -78,10 +78,10 @@ struct DeltaSetIndexMap
{ return (format & 0xF) + 1; }
protected:
UINT16 format; /* A packed field that describes the compressed
HBUINT16 format; /* A packed field that describes the compressed
* representation of delta-set indices. */
UINT16 mapCount; /* The number of mapping entries. */
UINT8 mapData[VAR]; /* The delta-set index mapping data. */
HBUINT16 mapCount; /* The number of mapping entries. */
HBUINT8 mapData[VAR]; /* The delta-set index mapping data. */
public:
DEFINE_SIZE_ARRAY (4, mapData);

Просмотреть файл

@ -43,7 +43,7 @@ struct VariationValueRecord
public:
Tag valueTag; /* Four-byte tag identifying a font-wide measure. */
UINT32 varIdx; /* Outer/inner index into VariationStore item. */
HBUINT32 varIdx; /* Outer/inner index into VariationStore item. */
public:
DEFINE_SIZE_STATIC (8);
@ -95,13 +95,13 @@ protected:
protected:
FixedVersion<>version; /* Version of the metrics variation table
* initially set to 0x00010000u */
UINT16 reserved; /* Not used; set to 0. */
UINT16 valueRecordSize;/* The size in bytes of each value record —
HBUINT16 reserved; /* Not used; set to 0. */
HBUINT16 valueRecordSize;/* The size in bytes of each value record —
* must be greater than zero. */
UINT16 valueRecordCount;/* The number of value records — may be zero. */
HBUINT16 valueRecordCount;/* The number of value records — may be zero. */
OffsetTo<VariationStore>
varStore; /* Offset to item variation store table. */
UINT8 values[VAR]; /* Array of value records. The records must be
HBUINT8 values[VAR]; /* Array of value records. The records must be
* in binary order of their valueTag field. */
public:

Просмотреть файл

@ -29,6 +29,8 @@
#ifndef HB_PRIVATE_HH
#define HB_PRIVATE_HH
#define _GNU_SOURCE 1
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@ -40,6 +42,7 @@
#define HB_OT_H_IN
#endif
#include <math.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
@ -86,8 +89,6 @@ extern "C" void hb_free_impl(void *ptr);
#endif // __cplusplus < 201103L
#define _GNU_SOURCE 1
#if (defined(__GNUC__) || defined(__clang__)) && defined(__OPTIMIZE__)
#define likely(expr) (__builtin_expect (!!(expr), 1))
#define unlikely(expr) (__builtin_expect (!!(expr), 0))
@ -297,9 +298,10 @@ static_assert ((sizeof (hb_var_int_t) == 4), "");
/* Misc */
/* Void! */
struct _hb_void_t {};
typedef const _hb_void_t *hb_void_t;
/*
* Void!
*/
typedef const struct _hb_void_t *hb_void_t;
#define HB_VOID ((const _hb_void_t *) nullptr)
/* Return the number of 1 bits in mask. */

Просмотреть файл

@ -185,6 +185,7 @@ struct hb_set_t
inline void init (void)
{
in_error = false;
page_map.init ();
pages.init ();
}

Просмотреть файл

@ -351,7 +351,7 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name)
* full, PS. All of them point to the same name data with our unique name.
*/
blob = OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (blob);
blob = OT::Sanitizer<OT::OpenTypeFontFile>().sanitize (blob);
unsigned int length, new_length, name_str_len;
const char *orig_sfnt_data = hb_blob_get_data (blob, &length);

Просмотреть файл

@ -38,9 +38,9 @@ HB_BEGIN_DECLS
#define HB_VERSION_MAJOR 1
#define HB_VERSION_MINOR 7
#define HB_VERSION_MICRO 4
#define HB_VERSION_MICRO 5
#define HB_VERSION_STRING "1.7.4"
#define HB_VERSION_STRING "1.7.5"
#define HB_VERSION_ATLEAST(major,minor,micro) \
((major)*10000+(minor)*100+(micro) <= \

Просмотреть файл

@ -24,7 +24,6 @@
* Red Hat Author(s): Behdad Esfahbod
*/
#include "hb-mutex-private.hh"
#include "hb-open-file-private.hh"
#include "hb-ot-layout-gdef-table.hh"
#include "hb-ot-layout-gsubgpos-private.hh"

Просмотреть файл

@ -32,12 +32,14 @@ SOURCES += [
'hb-ot-math.cc', # conflict with hb-ot-layout.cc
'hb-ot-shape-complex-hangul.cc', # error: redefinition of enumerator 'NONE'
'hb-ot-shape-complex-indic.cc', # error: redefinition of enumerator 'INIT'
'hb-ot-shape-complex-khmer.cc', # error: redefinition of enumerator 'syllable_type_t'
'hb-ot-shape-complex-use.cc', # error: redefinition of 'basic_features'
'hb-ot-shape.cc', # error: functions that differ only in their return type cannot be overloaded
'hb-shape-plan.cc', # error: redefinition of 'hb_ot_shaper_face_data_ensure'
]
UNIFIED_SOURCES += [
'hb-aat-layout.cc',
'hb-buffer.cc',
'hb-face.cc',
'hb-font.cc',