зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1417131 - Update HarfBuzz to 1.7.1. r=jfkthame
This commit is contained in:
Родитель
ded0cee6bf
Коммит
aac3a947d7
|
@ -1,3 +1,23 @@
|
|||
Overview of changes leading to 1.7.1
|
||||
Tuesday, November 14, 2017
|
||||
====================================
|
||||
|
||||
- Fix atexit object destruction regression.
|
||||
- Fix minor integer-overflow.
|
||||
|
||||
|
||||
Overview of changes leading to 1.7.0
|
||||
Monday, November 13, 2017
|
||||
====================================
|
||||
|
||||
- Minor Indic fixes.
|
||||
- Implement kerning and glyph names in hb-ot-font.
|
||||
- Various DSO optimization re .data and .bss sizes.
|
||||
- Make C++11 optional; build fixes.
|
||||
- Mark all other backends "unsafe-to-break".
|
||||
- Graphite fix.
|
||||
|
||||
|
||||
Overview of changes leading to 1.6.3
|
||||
Thursday, October 26th, 2017
|
||||
====================================
|
||||
|
@ -809,7 +829,7 @@ Wednesday, July 16, 2014
|
|||
U+FFFD REPLACEMENT CHARACTER now.
|
||||
- With all changes in this release, the buffer will contain fully
|
||||
valid Unicode after hb_buffer_add_utf8/16/32 no matter how
|
||||
broken the input is. This can be overriden though. See below.
|
||||
broken the input is. This can be overridden though. See below.
|
||||
- Fix Mongolian Variation Selectors for fonts without GDEF.
|
||||
- Fix minor invalid buffer access.
|
||||
- Accept zh-Hant and zh-Hans language tags. hb_ot_tag_to_language()
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
[![Build Status](https://travis-ci.org/behdad/harfbuzz.svg)](https://travis-ci.org/behdad/harfbuzz)
|
||||
[![Build Status](https://ci.appveyor.com/api/projects/status/4oaq58ns2h0m2soa?svg=true)](https://ci.appveyor.com/project/behdad/harfbuzz)
|
||||
[![CircleCI](https://circleci.com/gh/behdad/harfbuzz.svg?style=svg)](https://circleci.com/gh/behdad/harfbuzz)
|
||||
[![Coverage Status](https://img.shields.io/coveralls/behdad/harfbuzz.svg)](https://coveralls.io/r/behdad/harfbuzz)
|
||||
[ABI Tracker](http://abi-laboratory.pro/tracker/timeline/harfbuzz/)
|
||||
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
gfx/harfbuzz status as of 2017-10-26:
|
||||
gfx/harfbuzz status as of 2017-11-14:
|
||||
|
||||
This directory contains the harfbuzz source from the 'master' branch of
|
||||
This directory contains the HarfBuzz source from the 'master' branch of
|
||||
https://github.com/behdad/harfbuzz.
|
||||
|
||||
Current version: 1.6.3
|
||||
Current version: 1.7.1
|
||||
|
||||
UPDATING:
|
||||
|
||||
Note that gfx/harfbuzz/src/hb-version.h is not present in the upstream Git
|
||||
repository. It is created at build time by the harfbuzz build system;
|
||||
repository. It is created at build time by the HarfBuzz build system;
|
||||
but as we don't use that build system in mozilla, it is necessary to refresh
|
||||
this file when updating harfbuzz, and check it into the mozilla tree.
|
||||
this file when updating HarfBuzz, and check it into the mozilla tree.
|
||||
|
||||
The normal approach to updating harfbuzz, therefore, is to pull the latest HB
|
||||
The normal approach to updating HarfBuzz, therefore, is to pull the latest HB
|
||||
source into a scratch directory and do a local build; then copy the original
|
||||
sources AND the generated header mentioned above from the build directory into
|
||||
the mozilla tree.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
AC_PREREQ([2.64])
|
||||
AC_INIT([HarfBuzz],
|
||||
[1.6.3],
|
||||
[1.7.1],
|
||||
[https://github.com/behdad/harfbuzz/issues/new],
|
||||
[harfbuzz],
|
||||
[http://harfbuzz.org/])
|
||||
|
@ -23,6 +23,7 @@ AC_USE_SYSTEM_EXTENSIONS
|
|||
AC_PROG_CC
|
||||
AM_PROG_CC_C_O
|
||||
AC_PROG_CXX
|
||||
AX_CXX_COMPILE_STDCXX(11, noext, optional)
|
||||
AC_SYS_LARGEFILE
|
||||
PKG_PROG_PKG_CONFIG([0.20])
|
||||
AM_MISSING_PROG([RAGEL], [ragel])
|
||||
|
@ -80,9 +81,6 @@ if test "x$GCC" = "xyes"; then
|
|||
# Make symbols link locally
|
||||
LDFLAGS="$LDFLAGS -Bsymbolic-functions"
|
||||
|
||||
# Choose C++ version
|
||||
CXXFLAGS="$CXXFLAGS -std=c++11"
|
||||
|
||||
# Make sure we don't link to libstdc++
|
||||
CXXFLAGS="$CXXFLAGS -fno-rtti -fno-exceptions"
|
||||
|
||||
|
@ -167,7 +165,7 @@ dnl ===========================================================================
|
|||
|
||||
AC_ARG_WITH(gobject,
|
||||
[AS_HELP_STRING([--with-gobject=@<:@yes/no/auto@:>@],
|
||||
[Use gobject @<:@default=auto@:>@])],,
|
||||
[Use gobject @<:@default=no@:>@])],,
|
||||
[with_gobject=no])
|
||||
have_gobject=false
|
||||
if test "x$with_gobject" = "xyes" -o "x$with_gobject" = "xauto"; then
|
||||
|
|
|
@ -48,7 +48,7 @@ GIT_MK_URL = https://raw.githubusercontent.com/behdad/git.mk/master/git.mk
|
|||
#
|
||||
# This file knows how to handle autoconf, automake, libtool, gtk-doc,
|
||||
# gnome-doc-utils, yelp.m4, mallard, intltool, gsettings, dejagnu, appdata,
|
||||
# appstream.
|
||||
# appstream, hotdoc.
|
||||
#
|
||||
# This makefile provides the following targets:
|
||||
#
|
||||
|
@ -86,6 +86,7 @@ GITIGNORE_MAINTAINERCLEANFILES_TOPLEVEL = \
|
|||
ar-lib \
|
||||
compile \
|
||||
config.guess \
|
||||
config.rpath \
|
||||
config.sub \
|
||||
depcomp \
|
||||
install-sh \
|
||||
|
@ -120,6 +121,47 @@ GITIGNORE_MAINTAINERCLEANFILES_M4_LIBTOOL = \
|
|||
lt~obsolete.m4 \
|
||||
; do echo "$$MACRO_DIR/$$x"; done; \
|
||||
fi`
|
||||
#
|
||||
# Modules that use gettext and use AC_CONFIG_MACRO_DIR() may also include this,
|
||||
# though it's harmless to include regardless.
|
||||
GITIGNORE_MAINTAINERCLEANFILES_M4_GETTEXT = \
|
||||
`MACRO_DIR=$(srcdir)/$$(cd $(top_srcdir); $(AUTOCONF) --trace 'AC_CONFIG_MACRO_DIR:$$1' ./configure.ac); \
|
||||
if test "x$$MACRO_DIR" != "x$(srcdir)/"; then \
|
||||
for x in \
|
||||
codeset.m4 \
|
||||
extern-inline.m4 \
|
||||
fcntl-o.m4 \
|
||||
gettext.m4 \
|
||||
glibc2.m4 \
|
||||
glibc21.m4 \
|
||||
iconv.m4 \
|
||||
intdiv0.m4 \
|
||||
intl.m4 \
|
||||
intldir.m4 \
|
||||
intlmacosx.m4 \
|
||||
intmax.m4 \
|
||||
inttypes-pri.m4 \
|
||||
inttypes_h.m4 \
|
||||
lcmessage.m4 \
|
||||
lib-ld.m4 \
|
||||
lib-link.m4 \
|
||||
lib-prefix.m4 \
|
||||
lock.m4 \
|
||||
longlong.m4 \
|
||||
nls.m4 \
|
||||
po.m4 \
|
||||
printf-posix.m4 \
|
||||
progtest.m4 \
|
||||
size_max.m4 \
|
||||
stdint_h.m4 \
|
||||
threadlib.m4 \
|
||||
uintmax_t.m4 \
|
||||
visibility.m4 \
|
||||
wchar_t.m4 \
|
||||
wint_t.m4 \
|
||||
xsize.m4 \
|
||||
; do echo "$$MACRO_DIR/$$x"; done; \
|
||||
fi`
|
||||
|
||||
|
||||
|
||||
|
@ -208,6 +250,15 @@ $(srcdir)/.gitignore: Makefile.am $(top_srcdir)/git.mk
|
|||
"*/*.omf.out" \
|
||||
; do echo /$$x; done; \
|
||||
fi; \
|
||||
if test "x$(HOTDOC)" = x; then :; else \
|
||||
$(foreach project, $(HOTDOC_PROJECTS),echo "/$(call HOTDOC_TARGET,$(project))"; \
|
||||
echo "/$(shell $(call HOTDOC_PROJECT_COMMAND,$(project)) --get-conf-path output)" ; \
|
||||
echo "/$(shell $(call HOTDOC_PROJECT_COMMAND,$(project)) --get-private-folder)" ; \
|
||||
) \
|
||||
for x in \
|
||||
.hotdoc.d \
|
||||
; do echo "/$$x"; done; \
|
||||
fi; \
|
||||
if test "x$(HELP_ID)" = x -o "x$(HELP_LINGUAS)" = x; then :; else \
|
||||
for lc in $(HELP_LINGUAS); do \
|
||||
for x in \
|
||||
|
@ -235,6 +286,7 @@ $(srcdir)/.gitignore: Makefile.am $(top_srcdir)/git.mk
|
|||
fi; \
|
||||
if test -f $(srcdir)/po/Makefile.in.in; then \
|
||||
for x in \
|
||||
ABOUT-NLS \
|
||||
po/Makefile.in.in \
|
||||
po/Makefile.in.in~ \
|
||||
po/Makefile.in \
|
||||
|
@ -243,6 +295,7 @@ $(srcdir)/.gitignore: Makefile.am $(top_srcdir)/git.mk
|
|||
po/POTFILES \
|
||||
po/Rules-quot \
|
||||
po/stamp-it \
|
||||
po/stamp-po \
|
||||
po/.intltool-merge-cache \
|
||||
"po/*.gmo" \
|
||||
"po/*.header" \
|
||||
|
@ -274,7 +327,7 @@ $(srcdir)/.gitignore: Makefile.am $(top_srcdir)/git.mk
|
|||
if test "x$(am__dirstamp)" = x; then :; else \
|
||||
echo "$(am__dirstamp)"; \
|
||||
fi; \
|
||||
if test "x$(LTCOMPILE)" = x -a "x$(LTCXXCOMPILE)" = x -a "x$(GTKDOC_RUN)" = x; then :; else \
|
||||
if test "x$(findstring libtool,$(LTCOMPILE))" = x -a "x$(findstring libtool,$(LTCXXCOMPILE))" = x -a "x$(GTKDOC_RUN)" = x; then :; else \
|
||||
for x in \
|
||||
"*.lo" \
|
||||
".libs" "_libs" \
|
||||
|
|
|
@ -34,7 +34,7 @@ grep -v 'hb-private[.]hh:' |
|
|||
grep . >&2 && stat=1
|
||||
|
||||
|
||||
echo 'Checking that there is no #include <hb.*.h>'
|
||||
echo 'Checking that there is no #include <hb-*.h>'
|
||||
for x in $HBHEADERS $HBSOURCES; do
|
||||
test -f "$srcdir/$x" && x="$srcdir/$x"
|
||||
grep '#.*\<include\>.*<.*hb' "$x" /dev/null >&2 && stat=1
|
||||
|
|
|
@ -5,7 +5,7 @@ includedir=/usr/local/include
|
|||
|
||||
Name: harfbuzz
|
||||
Description: HarfBuzz text shaping library ICU integration
|
||||
Version: 1.6.3
|
||||
Version: 1.7.1
|
||||
|
||||
Requires: harfbuzz
|
||||
Requires.private: icu-uc
|
||||
|
|
|
@ -5,7 +5,7 @@ includedir=/usr/local/include
|
|||
|
||||
Name: harfbuzz
|
||||
Description: HarfBuzz text shaping library
|
||||
Version: 1.6.3
|
||||
Version: 1.7.1
|
||||
|
||||
Libs: -L${libdir} -lharfbuzz
|
||||
Libs.private: -lm
|
||||
|
|
|
@ -89,9 +89,9 @@ typedef int32_t hb_atomic_int_impl_t;
|
|||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P))
|
||||
#else
|
||||
#if __ppc64__ || __x86_64__ || __aarch64__
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (void *) (O), (int64_t) (void *) (N), (int64_t*) (P))
|
||||
#else
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P))
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (void *) (O), (int32_t) (void *) (N), (int32_t*) (P))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#endif
|
||||
|
||||
#include "hb-private.hh"
|
||||
#include "hb-debug.hh"
|
||||
|
||||
#include "hb-object-private.hh"
|
||||
|
||||
|
@ -44,12 +45,6 @@
|
|||
#include <errno.h>
|
||||
|
||||
|
||||
|
||||
#ifndef HB_DEBUG_BLOB
|
||||
#define HB_DEBUG_BLOB (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
|
||||
struct hb_blob_t {
|
||||
hb_object_header_t header;
|
||||
ASSERT_POD ();
|
||||
|
|
|
@ -305,16 +305,16 @@ struct hb_buffer_t {
|
|||
info.cluster = cluster;
|
||||
}
|
||||
|
||||
int
|
||||
inline int
|
||||
_unsafe_to_break_find_min_cluster (const hb_glyph_info_t *info,
|
||||
unsigned int start, unsigned int end,
|
||||
unsigned int cluster) const
|
||||
{
|
||||
for (unsigned int i = start; i < end; i++)
|
||||
cluster = MIN (cluster, info[i].cluster);
|
||||
cluster = MIN<unsigned int> (cluster, info[i].cluster);
|
||||
return cluster;
|
||||
}
|
||||
void
|
||||
inline void
|
||||
_unsafe_to_break_set_mask (hb_glyph_info_t *info,
|
||||
unsigned int start, unsigned int end,
|
||||
unsigned int cluster)
|
||||
|
@ -326,6 +326,19 @@ struct hb_buffer_t {
|
|||
info[i].mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
unsafe_to_break_all (void)
|
||||
{
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
info[i].mask |= HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
|
||||
}
|
||||
inline void
|
||||
safe_to_break_all (void)
|
||||
{
|
||||
for (unsigned int i = 0; i < len; i++)
|
||||
info[i].mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_BREAK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -554,7 +554,7 @@ hb_buffer_t::merge_clusters_impl (unsigned int start,
|
|||
unsigned int cluster = info[start].cluster;
|
||||
|
||||
for (unsigned int i = start + 1; i < end; i++)
|
||||
cluster = MIN (cluster, info[i].cluster);
|
||||
cluster = MIN<unsigned int> (cluster, info[i].cluster);
|
||||
|
||||
/* Extend end */
|
||||
while (end < len && info[end - 1].cluster == info[end].cluster)
|
||||
|
@ -585,7 +585,7 @@ hb_buffer_t::merge_out_clusters (unsigned int start,
|
|||
unsigned int cluster = out_info[start].cluster;
|
||||
|
||||
for (unsigned int i = start + 1; i < end; i++)
|
||||
cluster = MIN (cluster, out_info[i].cluster);
|
||||
cluster = MIN<unsigned int> (cluster, out_info[i].cluster);
|
||||
|
||||
/* Extend start */
|
||||
while (start && out_info[start - 1].cluster == out_info[start].cluster)
|
||||
|
|
|
@ -85,7 +85,7 @@ hb_tag_from_string (const char *str, int len)
|
|||
for (; i < 4; i++)
|
||||
tag[i] = ' ';
|
||||
|
||||
return HB_TAG_CHAR4 (tag);
|
||||
return HB_TAG (tag[0], tag[1], tag[2], tag[3]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -699,34 +699,43 @@ parse_uint32 (const char **pp, const char *end, uint32_t *pv)
|
|||
|
||||
#if defined (HAVE_NEWLOCALE) && defined (HAVE_STRTOD_L)
|
||||
#define USE_XLOCALE 1
|
||||
#define HB_LOCALE_T locale_t
|
||||
#define HB_CREATE_LOCALE(locName) newlocale (LC_ALL_MASK, locName, nullptr)
|
||||
#define HB_FREE_LOCALE(loc) freelocale (loc)
|
||||
#elif defined(_MSC_VER)
|
||||
#define USE_XLOCALE 1
|
||||
#define HB_LOCALE_T _locale_t
|
||||
#define HB_CREATE_LOCALE(locName) _create_locale (LC_ALL, locName)
|
||||
#define HB_FREE_LOCALE(loc) _free_locale (loc)
|
||||
#define strtod_l(a, b, c) _strtod_l ((a), (b), (c))
|
||||
#endif
|
||||
|
||||
#ifdef USE_XLOCALE
|
||||
|
||||
static locale_t C_locale;
|
||||
static HB_LOCALE_T C_locale;
|
||||
|
||||
#ifdef HB_USE_ATEXIT
|
||||
static void
|
||||
free_C_locale (void)
|
||||
{
|
||||
if (C_locale)
|
||||
freelocale (C_locale);
|
||||
HB_FREE_LOCALE (C_locale);
|
||||
}
|
||||
#endif
|
||||
|
||||
static locale_t
|
||||
static HB_LOCALE_T
|
||||
get_C_locale (void)
|
||||
{
|
||||
retry:
|
||||
locale_t C = (locale_t) hb_atomic_ptr_get (&C_locale);
|
||||
HB_LOCALE_T C = (HB_LOCALE_T) hb_atomic_ptr_get (&C_locale);
|
||||
|
||||
if (unlikely (!C))
|
||||
{
|
||||
C = newlocale (LC_ALL_MASK, "C", nullptr);
|
||||
C = HB_CREATE_LOCALE ("C");
|
||||
|
||||
if (!hb_atomic_ptr_cmpexch (&C_locale, nullptr, C))
|
||||
{
|
||||
freelocale (C_locale);
|
||||
HB_FREE_LOCALE (C_locale);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,16 +27,14 @@
|
|||
*/
|
||||
|
||||
#define HB_SHAPER coretext
|
||||
|
||||
#include "hb-private.hh"
|
||||
#include "hb-debug.hh"
|
||||
#include "hb-shaper-impl-private.hh"
|
||||
|
||||
#include "hb-coretext.h"
|
||||
#include <math.h>
|
||||
|
||||
|
||||
#ifndef HB_DEBUG_CORETEXT
|
||||
#define HB_DEBUG_CORETEXT (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
/* https://developer.apple.com/documentation/coretext/1508745-ctfontcreatewithgraphicsfont */
|
||||
#define HB_CORETEXT_DEFAULT_FONT_SIZE 12.f
|
||||
|
||||
|
@ -351,7 +349,9 @@ struct active_feature_t {
|
|||
feature_record_t rec;
|
||||
unsigned int order;
|
||||
|
||||
static int cmp (const active_feature_t *a, const active_feature_t *b) {
|
||||
static int cmp (const void *pa, const void *pb) {
|
||||
const active_feature_t *a = (const active_feature_t *) pa;
|
||||
const active_feature_t *b = (const active_feature_t *) pb;
|
||||
return a->rec.feature < b->rec.feature ? -1 : a->rec.feature > b->rec.feature ? 1 :
|
||||
a->order < b->order ? -1 : a->order > b->order ? 1 :
|
||||
a->rec.setting < b->rec.setting ? -1 : a->rec.setting > b->rec.setting ? 1 :
|
||||
|
@ -367,7 +367,9 @@ struct feature_event_t {
|
|||
bool start;
|
||||
active_feature_t feature;
|
||||
|
||||
static int cmp (const feature_event_t *a, const feature_event_t *b) {
|
||||
static int cmp (const void *pa, const void *pb) {
|
||||
const feature_event_t *a = (const feature_event_t *) pa;
|
||||
const feature_event_t *b = (const feature_event_t *) pb;
|
||||
return a->index < b->index ? -1 : a->index > b->index ? 1 :
|
||||
a->start < b->start ? -1 : a->start > b->start ? 1 :
|
||||
active_feature_t::cmp (&a->feature, &b->feature);
|
||||
|
@ -1260,6 +1262,8 @@ resize_and_retry:
|
|||
}
|
||||
}
|
||||
|
||||
buffer->unsafe_to_break_all ();
|
||||
|
||||
#undef FAIL
|
||||
|
||||
fail:
|
||||
|
|
|
@ -0,0 +1,419 @@
|
|||
/*
|
||||
* 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_DEBUG_HH
|
||||
#define HB_DEBUG_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
|
||||
#ifndef HB_DEBUG
|
||||
#define HB_DEBUG 0
|
||||
#endif
|
||||
|
||||
static inline bool
|
||||
_hb_debug (unsigned int level,
|
||||
unsigned int max_level)
|
||||
{
|
||||
return level < max_level;
|
||||
}
|
||||
|
||||
#define DEBUG_LEVEL_ENABLED(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT))
|
||||
#define DEBUG_ENABLED(WHAT) (DEBUG_LEVEL_ENABLED (WHAT, 0))
|
||||
|
||||
static inline void
|
||||
_hb_print_func (const char *func)
|
||||
{
|
||||
if (func)
|
||||
{
|
||||
unsigned int func_len = strlen (func);
|
||||
/* Skip "static" */
|
||||
if (0 == strncmp (func, "static ", 7))
|
||||
func += 7;
|
||||
/* Skip "typename" */
|
||||
if (0 == strncmp (func, "typename ", 9))
|
||||
func += 9;
|
||||
/* Skip return type */
|
||||
const char *space = strchr (func, ' ');
|
||||
if (space)
|
||||
func = space + 1;
|
||||
/* Skip parameter list */
|
||||
const char *paren = strchr (func, '(');
|
||||
if (paren)
|
||||
func_len = paren - func;
|
||||
fprintf (stderr, "%.*s", func_len, func);
|
||||
}
|
||||
}
|
||||
|
||||
template <int max_level> static inline void
|
||||
_hb_debug_msg_va (const char *what,
|
||||
const void *obj,
|
||||
const char *func,
|
||||
bool indented,
|
||||
unsigned int level,
|
||||
int level_dir,
|
||||
const char *message,
|
||||
va_list ap) HB_PRINTF_FUNC(7, 0);
|
||||
template <int max_level> static inline void
|
||||
_hb_debug_msg_va (const char *what,
|
||||
const void *obj,
|
||||
const char *func,
|
||||
bool indented,
|
||||
unsigned int level,
|
||||
int level_dir,
|
||||
const char *message,
|
||||
va_list ap)
|
||||
{
|
||||
if (!_hb_debug (level, max_level))
|
||||
return;
|
||||
|
||||
fprintf (stderr, "%-10s", what ? what : "");
|
||||
|
||||
if (obj)
|
||||
fprintf (stderr, "(%0*lx) ", (unsigned int) (2 * sizeof (void *)), (unsigned long) obj);
|
||||
else
|
||||
fprintf (stderr, " %*s ", (unsigned int) (2 * sizeof (void *)), "");
|
||||
|
||||
if (indented) {
|
||||
#define VBAR "\342\224\202" /* U+2502 BOX DRAWINGS LIGHT VERTICAL */
|
||||
#define VRBAR "\342\224\234" /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
|
||||
#define DLBAR "\342\225\256" /* U+256E BOX DRAWINGS LIGHT ARC DOWN AND LEFT */
|
||||
#define ULBAR "\342\225\257" /* U+256F BOX DRAWINGS LIGHT ARC UP AND LEFT */
|
||||
#define LBAR "\342\225\264" /* U+2574 BOX DRAWINGS LIGHT LEFT */
|
||||
static const char bars[] =
|
||||
VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR
|
||||
VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR
|
||||
VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR
|
||||
VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR
|
||||
VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR;
|
||||
fprintf (stderr, "%2u %s" VRBAR "%s",
|
||||
level,
|
||||
bars + sizeof (bars) - 1 - MIN ((unsigned int) sizeof (bars) - 1, (unsigned int) (sizeof (VBAR) - 1) * level),
|
||||
level_dir ? (level_dir > 0 ? DLBAR : ULBAR) : LBAR);
|
||||
} else
|
||||
fprintf (stderr, " " VRBAR LBAR);
|
||||
|
||||
_hb_print_func (func);
|
||||
|
||||
if (message)
|
||||
{
|
||||
fprintf (stderr, ": ");
|
||||
vfprintf (stderr, message, ap);
|
||||
}
|
||||
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
template <> inline void
|
||||
_hb_debug_msg_va<0> (const char *what HB_UNUSED,
|
||||
const void *obj HB_UNUSED,
|
||||
const char *func HB_UNUSED,
|
||||
bool indented HB_UNUSED,
|
||||
unsigned int level HB_UNUSED,
|
||||
int level_dir HB_UNUSED,
|
||||
const char *message HB_UNUSED,
|
||||
va_list ap HB_UNUSED) {}
|
||||
|
||||
template <int max_level> static inline void
|
||||
_hb_debug_msg (const char *what,
|
||||
const void *obj,
|
||||
const char *func,
|
||||
bool indented,
|
||||
unsigned int level,
|
||||
int level_dir,
|
||||
const char *message,
|
||||
...) HB_PRINTF_FUNC(7, 8);
|
||||
template <int max_level> static inline void
|
||||
_hb_debug_msg (const char *what,
|
||||
const void *obj,
|
||||
const char *func,
|
||||
bool indented,
|
||||
unsigned int level,
|
||||
int level_dir,
|
||||
const char *message,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, message);
|
||||
_hb_debug_msg_va<max_level> (what, obj, func, indented, level, level_dir, message, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
template <> inline void
|
||||
_hb_debug_msg<0> (const char *what HB_UNUSED,
|
||||
const void *obj HB_UNUSED,
|
||||
const char *func HB_UNUSED,
|
||||
bool indented HB_UNUSED,
|
||||
unsigned int level HB_UNUSED,
|
||||
int level_dir HB_UNUSED,
|
||||
const char *message HB_UNUSED,
|
||||
...) HB_PRINTF_FUNC(7, 8);
|
||||
template <> inline void
|
||||
_hb_debug_msg<0> (const char *what HB_UNUSED,
|
||||
const void *obj HB_UNUSED,
|
||||
const char *func HB_UNUSED,
|
||||
bool indented HB_UNUSED,
|
||||
unsigned int level HB_UNUSED,
|
||||
int level_dir HB_UNUSED,
|
||||
const char *message HB_UNUSED,
|
||||
...) {}
|
||||
|
||||
#define DEBUG_MSG_LEVEL(WHAT, OBJ, LEVEL, LEVEL_DIR, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), nullptr, true, (LEVEL), (LEVEL_DIR), __VA_ARGS__)
|
||||
#define DEBUG_MSG(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), nullptr, false, 0, 0, __VA_ARGS__)
|
||||
#define DEBUG_MSG_FUNC(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), HB_FUNC, false, 0, 0, __VA_ARGS__)
|
||||
|
||||
|
||||
/*
|
||||
* Printer
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
struct hb_printer_t {
|
||||
const char *print (const T&) { return "something"; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hb_printer_t<bool> {
|
||||
const char *print (bool v) { return v ? "true" : "false"; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hb_printer_t<hb_void_t> {
|
||||
const char *print (hb_void_t) { return ""; }
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Trace
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
static inline void _hb_warn_no_return (bool returned)
|
||||
{
|
||||
if (unlikely (!returned)) {
|
||||
fprintf (stderr, "OUCH, returned with no call to return_trace(). This is a bug, please report.\n");
|
||||
}
|
||||
}
|
||||
template <>
|
||||
/*static*/ inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED)
|
||||
{}
|
||||
|
||||
template <int max_level, typename ret_t>
|
||||
struct hb_auto_trace_t {
|
||||
explicit inline hb_auto_trace_t (unsigned int *plevel_,
|
||||
const char *what_,
|
||||
const void *obj_,
|
||||
const char *func,
|
||||
const char *message,
|
||||
...) : plevel (plevel_), what (what_), obj (obj_), returned (false)
|
||||
{
|
||||
if (plevel) ++*plevel;
|
||||
|
||||
va_list ap;
|
||||
va_start (ap, message);
|
||||
_hb_debug_msg_va<max_level> (what, obj, func, true, plevel ? *plevel : 0, +1, message, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
inline ~hb_auto_trace_t (void)
|
||||
{
|
||||
_hb_warn_no_return<ret_t> (returned);
|
||||
if (!returned) {
|
||||
_hb_debug_msg<max_level> (what, obj, nullptr, true, plevel ? *plevel : 1, -1, " ");
|
||||
}
|
||||
if (plevel) --*plevel;
|
||||
}
|
||||
|
||||
inline ret_t ret (ret_t v, unsigned int line = 0)
|
||||
{
|
||||
if (unlikely (returned)) {
|
||||
fprintf (stderr, "OUCH, double calls to return_trace(). This is a bug, please report.\n");
|
||||
return v;
|
||||
}
|
||||
|
||||
_hb_debug_msg<max_level> (what, obj, nullptr, true, plevel ? *plevel : 1, -1,
|
||||
"return %s (line %d)",
|
||||
hb_printer_t<ret_t>().print (v), line);
|
||||
if (plevel) --*plevel;
|
||||
plevel = nullptr;
|
||||
returned = true;
|
||||
return v;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int *plevel;
|
||||
const char *what;
|
||||
const void *obj;
|
||||
bool returned;
|
||||
};
|
||||
template <typename ret_t> /* Make sure we don't use hb_auto_trace_t when not tracing. */
|
||||
struct hb_auto_trace_t<0, ret_t>;
|
||||
|
||||
/* For disabled tracing; optimize out everything.
|
||||
* https://github.com/behdad/harfbuzz/pull/605 */
|
||||
template <typename ret_t>
|
||||
struct hb_no_trace_t {
|
||||
inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; }
|
||||
};
|
||||
|
||||
#define return_trace(RET) return trace.ret (RET, __LINE__)
|
||||
|
||||
|
||||
/*
|
||||
* Instances.
|
||||
*/
|
||||
|
||||
#ifndef HB_DEBUG_ARABIC
|
||||
#define HB_DEBUG_ARABIC (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
#ifndef HB_DEBUG_BLOB
|
||||
#define HB_DEBUG_BLOB (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
#ifndef HB_DEBUG_CORETEXT
|
||||
#define HB_DEBUG_CORETEXT (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
#ifndef HB_DEBUG_DIRECTWRITE
|
||||
#define HB_DEBUG_DIRECTWRITE (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
#ifndef HB_DEBUG_FT
|
||||
#define HB_DEBUG_FT (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
#ifndef HB_DEBUG_GET_COVERAGE
|
||||
#define HB_DEBUG_GET_COVERAGE (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
#ifndef HB_DEBUG_OBJECT
|
||||
#define HB_DEBUG_OBJECT (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
#ifndef HB_DEBUG_SHAPE_PLAN
|
||||
#define HB_DEBUG_SHAPE_PLAN (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
#ifndef HB_DEBUG_UNISCRIBE
|
||||
#define HB_DEBUG_UNISCRIBE (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* With tracing.
|
||||
*/
|
||||
|
||||
#ifndef HB_DEBUG_APPLY
|
||||
#define HB_DEBUG_APPLY (HB_DEBUG+0)
|
||||
#endif
|
||||
#if HB_DEBUG_APPLY
|
||||
#define TRACE_APPLY(this) \
|
||||
hb_auto_trace_t<HB_DEBUG_APPLY, bool> trace \
|
||||
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
|
||||
"idx %d gid %u lookup %d", \
|
||||
c->buffer->idx, c->buffer->cur().codepoint, (int) c->lookup_index)
|
||||
#else
|
||||
#define TRACE_APPLY(this) hb_no_trace_t<bool> trace
|
||||
#endif
|
||||
|
||||
#ifndef HB_DEBUG_CLOSURE
|
||||
#define HB_DEBUG_CLOSURE (HB_DEBUG+0)
|
||||
#endif
|
||||
#if HB_DEBUG_CLOSURE
|
||||
#define TRACE_CLOSURE(this) \
|
||||
hb_auto_trace_t<HB_DEBUG_CLOSURE, hb_void_t> trace \
|
||||
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
|
||||
"")
|
||||
#else
|
||||
#define TRACE_CLOSURE(this) hb_no_trace_t<hb_void_t> trace HB_UNUSED
|
||||
#endif
|
||||
|
||||
#ifndef HB_DEBUG_COLLECT_GLYPHS
|
||||
#define HB_DEBUG_COLLECT_GLYPHS (HB_DEBUG+0)
|
||||
#endif
|
||||
#if HB_DEBUG_COLLECT_GLYPHS
|
||||
#define TRACE_COLLECT_GLYPHS(this) \
|
||||
hb_auto_trace_t<HB_DEBUG_COLLECT_GLYPHS, hb_void_t> trace \
|
||||
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
|
||||
"")
|
||||
#else
|
||||
#define TRACE_COLLECT_GLYPHS(this) hb_no_trace_t<hb_void_t> trace HB_UNUSED
|
||||
#endif
|
||||
|
||||
#ifndef HB_DEBUG_SANITIZE
|
||||
#define HB_DEBUG_SANITIZE (HB_DEBUG+0)
|
||||
#endif
|
||||
#if HB_DEBUG_SANITIZE
|
||||
#define TRACE_SANITIZE(this) \
|
||||
hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace \
|
||||
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
|
||||
"");
|
||||
#else
|
||||
#define TRACE_SANITIZE(this) hb_no_trace_t<bool> trace
|
||||
#endif
|
||||
|
||||
#ifndef HB_DEBUG_SERIALIZE
|
||||
#define HB_DEBUG_SERIALIZE (HB_DEBUG+0)
|
||||
#endif
|
||||
#if HB_DEBUG_SERIALIZE
|
||||
#define TRACE_SERIALIZE(this) \
|
||||
hb_auto_trace_t<HB_DEBUG_SERIALIZE, bool> trace \
|
||||
(&c->debug_depth, "SERIALIZE", c, HB_FUNC, \
|
||||
"");
|
||||
#else
|
||||
#define TRACE_SERIALIZE(this) hb_no_trace_t<bool> trace
|
||||
#endif
|
||||
|
||||
#ifndef HB_DEBUG_WOULD_APPLY
|
||||
#define HB_DEBUG_WOULD_APPLY (HB_DEBUG+0)
|
||||
#endif
|
||||
#if HB_DEBUG_WOULD_APPLY
|
||||
#define TRACE_WOULD_APPLY(this) \
|
||||
hb_auto_trace_t<HB_DEBUG_WOULD_APPLY, bool> trace \
|
||||
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
|
||||
"%d glyphs", c->len);
|
||||
#else
|
||||
#define TRACE_WOULD_APPLY(this) hb_no_trace_t<bool> trace
|
||||
#endif
|
||||
|
||||
#ifndef HB_DEBUG_DISPATCH
|
||||
#define HB_DEBUG_DISPATCH ( \
|
||||
HB_DEBUG_APPLY + \
|
||||
HB_DEBUG_CLOSURE + \
|
||||
HB_DEBUG_COLLECT_GLYPHS + \
|
||||
HB_DEBUG_SANITIZE + \
|
||||
HB_DEBUG_SERIALIZE + \
|
||||
HB_DEBUG_WOULD_APPLY + \
|
||||
0)
|
||||
#endif
|
||||
#if HB_DEBUG_DISPATCH
|
||||
#define TRACE_DISPATCH(this, format) \
|
||||
hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \
|
||||
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
|
||||
"format %d", (int) format);
|
||||
#else
|
||||
#define TRACE_DISPATCH(this, format) hb_no_trace_t<typename context_t::return_t> trace
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* HB_DEBUG_HH */
|
|
@ -22,6 +22,8 @@
|
|||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*/
|
||||
|
||||
#include "hb-private.hh"
|
||||
#include "hb-debug.hh"
|
||||
#define HB_SHAPER directwrite
|
||||
#include "hb-shaper-impl-private.hh"
|
||||
|
||||
|
@ -30,10 +32,6 @@
|
|||
#include "hb-directwrite.h"
|
||||
|
||||
|
||||
#ifndef HB_DEBUG_DIRECTWRITE
|
||||
#define HB_DEBUG_DIRECTWRITE (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
HB_SHAPER_DATA_ENSURE_DEFINE(directwrite, face)
|
||||
HB_SHAPER_DATA_ENSURE_DEFINE(directwrite, font)
|
||||
|
||||
|
@ -929,8 +927,7 @@ hb_directwrite_shape_experimental_width(hb_font_t *font,
|
|||
hb_bool_t res = _hb_directwrite_shape_full (shape_plan, font, buffer,
|
||||
features, num_features, width);
|
||||
|
||||
if (res)
|
||||
buffer->content_type = HB_BUFFER_CONTENT_TYPE_GLYPHS;
|
||||
buffer->unsafe_to_break_all ();
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,161 @@
|
|||
/*
|
||||
* 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_DSALGS_HH
|
||||
#define HB_DSALGS_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
|
||||
static inline void *
|
||||
hb_bsearch_r (const void *key, const void *base,
|
||||
size_t nmemb, size_t size,
|
||||
int (*compar)(const void *_key, const void *_item, void *_arg),
|
||||
void *arg)
|
||||
{
|
||||
int min = 0, max = (int) nmemb - 1;
|
||||
while (min <= max)
|
||||
{
|
||||
int mid = (min + max) / 2;
|
||||
const void *p = (const void *) (((const char *) base) + (mid * size));
|
||||
int c = compar (key, p, arg);
|
||||
if (c < 0)
|
||||
max = mid - 1;
|
||||
else if (c > 0)
|
||||
min = mid + 1;
|
||||
else
|
||||
return (void *) p;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* From https://github.com/noporpoise/sort_r */
|
||||
|
||||
/* Isaac Turner 29 April 2014 Public Domain */
|
||||
|
||||
/*
|
||||
|
||||
hb_sort_r function to be exported.
|
||||
|
||||
Parameters:
|
||||
base is the array to be sorted
|
||||
nel is the number of elements in the array
|
||||
width is the size in bytes of each element of the array
|
||||
compar is the comparison function
|
||||
arg is a pointer to be passed to the comparison function
|
||||
|
||||
void hb_sort_r(void *base, size_t nel, size_t width,
|
||||
int (*compar)(const void *_a, const void *_b, void *_arg),
|
||||
void *arg);
|
||||
*/
|
||||
|
||||
|
||||
/* swap a, b iff a>b */
|
||||
/* __restrict is same as restrict but better support on old machines */
|
||||
static int sort_r_cmpswap(char *__restrict a, char *__restrict b, size_t w,
|
||||
int (*compar)(const void *_a, const void *_b,
|
||||
void *_arg),
|
||||
void *arg)
|
||||
{
|
||||
char tmp, *end = a+w;
|
||||
if(compar(a, b, arg) > 0) {
|
||||
for(; a < end; a++, b++) { tmp = *a; *a = *b; *b = tmp; }
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Note: quicksort is not stable, equivalent values may be swapped */
|
||||
static inline void sort_r_simple(void *base, size_t nel, size_t w,
|
||||
int (*compar)(const void *_a, const void *_b,
|
||||
void *_arg),
|
||||
void *arg)
|
||||
{
|
||||
char *b = (char *)base, *end = b + nel*w;
|
||||
if(nel < 7) {
|
||||
/* Insertion sort for arbitrarily small inputs */
|
||||
char *pi, *pj;
|
||||
for(pi = b+w; pi < end; pi += w) {
|
||||
for(pj = pi; pj > b && sort_r_cmpswap(pj-w,pj,w,compar,arg); pj -= w) {}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* nel > 6; Quicksort */
|
||||
|
||||
/* Use median of first, middle and last items as pivot */
|
||||
char *x, *y, *xend, ch;
|
||||
char *pl, *pr;
|
||||
char *last = b+w*(nel-1), *tmp;
|
||||
char *l[3];
|
||||
l[0] = b;
|
||||
l[1] = b+w*(nel/2);
|
||||
l[2] = last;
|
||||
|
||||
if(compar(l[0],l[1],arg) > 0) { tmp=l[0]; l[0]=l[1]; l[1]=tmp; }
|
||||
if(compar(l[1],l[2],arg) > 0) {
|
||||
tmp=l[1]; l[1]=l[2]; l[2]=tmp; /* swap(l[1],l[2]) */
|
||||
if(compar(l[0],l[1],arg) > 0) { tmp=l[0]; l[0]=l[1]; l[1]=tmp; }
|
||||
}
|
||||
|
||||
/* swap l[id], l[2] to put pivot as last element */
|
||||
for(x = l[1], y = last, xend = x+w; x<xend; x++, y++) {
|
||||
ch = *x; *x = *y; *y = ch;
|
||||
}
|
||||
|
||||
pl = b;
|
||||
pr = last;
|
||||
|
||||
while(pl < pr) {
|
||||
for(; pl < pr; pl += w) {
|
||||
if(sort_r_cmpswap(pl, pr, w, compar, arg)) {
|
||||
pr -= w; /* pivot now at pl */
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(; pl < pr; pr -= w) {
|
||||
if(sort_r_cmpswap(pl, pr, w, compar, arg)) {
|
||||
pl += w; /* pivot now at pr */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sort_r_simple(b, (pl-b)/w, w, compar, arg);
|
||||
sort_r_simple(pl+w, (end-(pl+w))/w, w, compar, arg);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void hb_sort_r(void *base, size_t nel, size_t width,
|
||||
int (*compar)(const void *_a, const void *_b, void *_arg),
|
||||
void *arg)
|
||||
{
|
||||
sort_r_simple(base, nel, width, compar, arg);
|
||||
}
|
||||
|
||||
#endif /* HB_DSALGS_HH */
|
|
@ -143,5 +143,7 @@ _hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
|
|||
if (HB_DIRECTION_IS_BACKWARD (direction))
|
||||
hb_buffer_reverse (buffer);
|
||||
|
||||
buffer->safe_to_break_all ();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
*/
|
||||
|
||||
#include "hb-private.hh"
|
||||
#include "hb-debug.hh"
|
||||
|
||||
#include "hb-ft.h"
|
||||
|
||||
|
@ -38,12 +39,6 @@
|
|||
#include FT_TRUETYPE_TABLES_H
|
||||
|
||||
|
||||
|
||||
#ifndef HB_DEBUG_FT
|
||||
#define HB_DEBUG_FT (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
|
||||
/* TODO:
|
||||
*
|
||||
* In general, this file does a fine job of what it's supposed to do.
|
||||
|
|
|
@ -364,22 +364,44 @@ hb_glib_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
|||
return utf8_decomposed_len;
|
||||
}
|
||||
|
||||
static hb_unicode_funcs_t *static_glib_funcs = nullptr;
|
||||
|
||||
#ifdef HB_USE_ATEXIT
|
||||
static
|
||||
void free_static_glib_funcs (void)
|
||||
{
|
||||
hb_unicode_funcs_destroy (static_glib_funcs);
|
||||
}
|
||||
#endif
|
||||
|
||||
hb_unicode_funcs_t *
|
||||
hb_glib_get_unicode_funcs (void)
|
||||
{
|
||||
static const hb_unicode_funcs_t _hb_glib_unicode_funcs = {
|
||||
HB_OBJECT_HEADER_STATIC,
|
||||
retry:
|
||||
hb_unicode_funcs_t *funcs = (hb_unicode_funcs_t *) hb_atomic_ptr_get (&static_glib_funcs);
|
||||
|
||||
nullptr, /* parent */
|
||||
true, /* immutable */
|
||||
{
|
||||
#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_glib_unicode_##name,
|
||||
if (unlikely (!funcs))
|
||||
{
|
||||
funcs = hb_unicode_funcs_create (nullptr);
|
||||
|
||||
#define HB_UNICODE_FUNC_IMPLEMENT(name) \
|
||||
hb_unicode_funcs_set_##name##_func (funcs, hb_glib_unicode_##name, nullptr, nullptr);
|
||||
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_UNICODE_FUNC_IMPLEMENT
|
||||
|
||||
hb_unicode_funcs_make_immutable (funcs);
|
||||
|
||||
if (!hb_atomic_ptr_cmpexch (&static_glib_funcs, nullptr, funcs)) {
|
||||
hb_unicode_funcs_destroy (funcs);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
#ifdef HB_USE_ATEXIT
|
||||
atexit (free_static_glib_funcs); /* First person registers atexit() callback. */
|
||||
#endif
|
||||
};
|
||||
|
||||
return const_cast<hb_unicode_funcs_t *> (&_hb_glib_unicode_funcs);
|
||||
return hb_unicode_funcs_reference (funcs);
|
||||
}
|
||||
|
||||
#if GLIB_CHECK_VERSION(2,31,10)
|
||||
|
|
|
@ -307,6 +307,8 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan,
|
|||
curradv = gr_slot_origin_X(gr_seg_first_slot(seg));
|
||||
clusters[0].advance = gr_seg_advance_X(seg) - curradv;
|
||||
}
|
||||
else
|
||||
clusters[0].advance = 0;
|
||||
for (is = gr_seg_first_slot (seg), ic = 0; is; is = gr_slot_next_in_segment (is), ic++)
|
||||
{
|
||||
unsigned int before = gr_slot_before (is);
|
||||
|
@ -332,7 +334,10 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan,
|
|||
if (HB_DIRECTION_IS_BACKWARD(buffer->props.direction))
|
||||
c->advance = curradv - gr_slot_origin_X(is);
|
||||
else
|
||||
clusters[ci].advance = gr_slot_origin_X(is) - curradv;
|
||||
{
|
||||
c->advance = 0;
|
||||
clusters[ci].advance += gr_slot_origin_X(is) - curradv;
|
||||
}
|
||||
ci++;
|
||||
curradv = gr_slot_origin_X(is);
|
||||
}
|
||||
|
@ -345,7 +350,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan,
|
|||
if (HB_DIRECTION_IS_BACKWARD(buffer->props.direction))
|
||||
clusters[ci].advance += curradv;
|
||||
else
|
||||
clusters[ci].advance = gr_seg_advance_X(seg) - curradv;
|
||||
clusters[ci].advance += gr_seg_advance_X(seg) - curradv;
|
||||
ci++;
|
||||
|
||||
for (unsigned int i = 0; i < ci; ++i)
|
||||
|
@ -411,5 +416,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan,
|
|||
if (feats) gr_featureval_destroy (feats);
|
||||
gr_seg_destroy (seg);
|
||||
|
||||
buffer->unsafe_to_break_all ();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -345,27 +345,50 @@ hb_icu_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
|||
}
|
||||
|
||||
|
||||
static hb_unicode_funcs_t *static_icu_funcs = nullptr;
|
||||
|
||||
#ifdef HB_USE_ATEXIT
|
||||
static
|
||||
void free_static_icu_funcs (void)
|
||||
{
|
||||
hb_unicode_funcs_destroy (static_icu_funcs);
|
||||
}
|
||||
#endif
|
||||
|
||||
hb_unicode_funcs_t *
|
||||
hb_icu_get_unicode_funcs (void)
|
||||
{
|
||||
static const hb_unicode_funcs_t _hb_icu_unicode_funcs = {
|
||||
HB_OBJECT_HEADER_STATIC,
|
||||
retry:
|
||||
hb_unicode_funcs_t *funcs = (hb_unicode_funcs_t *) hb_atomic_ptr_get (&static_icu_funcs);
|
||||
|
||||
nullptr, /* parent */
|
||||
true, /* immutable */
|
||||
{
|
||||
#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_icu_unicode_##name,
|
||||
if (unlikely (!funcs))
|
||||
{
|
||||
#if U_ICU_VERSION_MAJOR_NUM >= 49
|
||||
if (!hb_atomic_ptr_get (&normalizer)) {
|
||||
UErrorCode icu_err = U_ZERO_ERROR;
|
||||
/* We ignore failure in getNFCInstace(). */
|
||||
(void) hb_atomic_ptr_cmpexch (&normalizer, nullptr, unorm2_getNFCInstance (&icu_err));
|
||||
}
|
||||
#endif
|
||||
|
||||
funcs = hb_unicode_funcs_create (nullptr);
|
||||
|
||||
#define HB_UNICODE_FUNC_IMPLEMENT(name) \
|
||||
hb_unicode_funcs_set_##name##_func (funcs, hb_icu_unicode_##name, nullptr, nullptr);
|
||||
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_UNICODE_FUNC_IMPLEMENT
|
||||
|
||||
hb_unicode_funcs_make_immutable (funcs);
|
||||
|
||||
if (!hb_atomic_ptr_cmpexch (&static_icu_funcs, nullptr, funcs)) {
|
||||
hb_unicode_funcs_destroy (funcs);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
#ifdef HB_USE_ATEXIT
|
||||
atexit (free_static_icu_funcs); /* First person registers atexit() callback. */
|
||||
#endif
|
||||
};
|
||||
|
||||
#if U_ICU_VERSION_MAJOR_NUM >= 49
|
||||
if (!hb_atomic_ptr_get (&normalizer)) {
|
||||
UErrorCode icu_err = U_ZERO_ERROR;
|
||||
/* We ignore failure in getNFCInstace(). */
|
||||
(void) hb_atomic_ptr_cmpexch (&normalizer, nullptr, unorm2_getNFCInstance (&icu_err));
|
||||
}
|
||||
#endif
|
||||
return const_cast<hb_unicode_funcs_t *> (&_hb_icu_unicode_funcs);
|
||||
return hb_unicode_funcs_reference (funcs);
|
||||
}
|
||||
|
|
|
@ -33,18 +33,12 @@
|
|||
#define HB_OBJECT_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
#include "hb-debug.hh"
|
||||
|
||||
#include "hb-atomic-private.hh"
|
||||
#include "hb-mutex-private.hh"
|
||||
|
||||
|
||||
/* Debug */
|
||||
|
||||
#ifndef HB_DEBUG_OBJECT
|
||||
#define HB_DEBUG_OBJECT (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
|
||||
/* reference_count */
|
||||
|
||||
#define HB_REFERENCE_COUNT_INERT_VALUE -1
|
||||
|
|
|
@ -53,6 +53,9 @@ struct TTCHeader;
|
|||
|
||||
typedef struct TableRecord
|
||||
{
|
||||
int cmp (Tag t) const
|
||||
{ return t.cmp (tag); }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
@ -73,10 +76,9 @@ typedef struct OffsetTable
|
|||
friend struct OpenTypeFontFile;
|
||||
|
||||
inline unsigned int get_table_count (void) const
|
||||
{ return numTables; }
|
||||
{ return tables.len; }
|
||||
inline const TableRecord& get_table (unsigned int i) const
|
||||
{
|
||||
if (unlikely (i >= numTables)) return Null(TableRecord);
|
||||
return tables[i];
|
||||
}
|
||||
inline unsigned int get_table_tags (unsigned int start_offset,
|
||||
|
@ -85,33 +87,28 @@ typedef struct OffsetTable
|
|||
{
|
||||
if (table_count)
|
||||
{
|
||||
if (start_offset >= numTables)
|
||||
if (start_offset >= tables.len)
|
||||
*table_count = 0;
|
||||
else
|
||||
*table_count = MIN (*table_count, numTables - start_offset);
|
||||
*table_count = MIN<unsigned int> (*table_count, tables.len - start_offset);
|
||||
|
||||
const TableRecord *sub_tables = tables + start_offset;
|
||||
const TableRecord *sub_tables = tables.array + start_offset;
|
||||
unsigned int count = *table_count;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
table_tags[i] = sub_tables[i].tag;
|
||||
}
|
||||
return numTables;
|
||||
return tables.len;
|
||||
}
|
||||
inline bool find_table_index (hb_tag_t tag, unsigned int *table_index) const
|
||||
{
|
||||
Tag t;
|
||||
t.set (tag);
|
||||
unsigned int count = numTables;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
if (t == tables[i].tag)
|
||||
{
|
||||
if (table_index) *table_index = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (table_index) *table_index = Index::NOT_FOUND_INDEX;
|
||||
return false;
|
||||
/* Linear-search for small tables to work around fonts with unsorted
|
||||
* table list. */
|
||||
int i = tables.len < 64 ? tables.lsearch (t) : tables.bsearch (t);
|
||||
if (table_index)
|
||||
*table_index = i == -1 ? Index::NOT_FOUND_INDEX : (unsigned int) i;
|
||||
return i != -1;
|
||||
}
|
||||
inline const TableRecord& get_table_by_tag (hb_tag_t tag) const
|
||||
{
|
||||
|
@ -124,16 +121,13 @@ typedef struct OffsetTable
|
|||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) && c->check_array (tables, TableRecord::static_size, numTables));
|
||||
return_trace (c->check_struct (this) && tables.sanitize (c));
|
||||
}
|
||||
|
||||
protected:
|
||||
Tag sfnt_version; /* '\0\001\0\00' if TrueType / 'OTTO' if CFF */
|
||||
USHORT numTables; /* Number of tables. */
|
||||
USHORT searchRangeZ; /* (Maximum power of 2 <= numTables) x 16 */
|
||||
USHORT entrySelectorZ; /* Log2(maximum power of 2 <= numTables). */
|
||||
USHORT rangeShiftZ; /* NumTables x 16-searchRange. */
|
||||
TableRecord tables[VAR]; /* TableRecord entries. numTables items */
|
||||
BinSearchArrayOf<TableRecord>
|
||||
tables;
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (12, tables);
|
||||
} OpenTypeFontFace;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#define HB_OPEN_TYPE_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
#include "hb-debug.hh"
|
||||
#include "hb-face-private.hh"
|
||||
|
||||
|
||||
|
@ -130,14 +131,16 @@ static inline Type& StructAfter(TObject &X)
|
|||
*/
|
||||
|
||||
/* Global nul-content Null pool. Enlarge as necessary. */
|
||||
/* TODO This really should be a extern HB_INTERNAL and defined somewhere... */
|
||||
static const void *_NullPool[(256+8) / sizeof (void *)];
|
||||
|
||||
#define HB_NULL_POOL_SIZE 264
|
||||
static_assert (HB_NULL_POOL_SIZE % sizeof (void *) == 0, "Align HB_NULL_POOL_SIZE.");
|
||||
extern HB_INTERNAL const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)];
|
||||
|
||||
/* Generic nul-content Null objects. */
|
||||
template <typename Type>
|
||||
static inline const Type& Null (void) {
|
||||
static_assert ((sizeof (Type) <= sizeof (_NullPool)), "");
|
||||
return *CastP<Type> (_NullPool);
|
||||
static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE.");
|
||||
return *CastP<Type> (_hb_NullPool);
|
||||
}
|
||||
|
||||
/* Specializaiton for arbitrary-content arbitrary-sized Null objects. */
|
||||
|
@ -172,16 +175,6 @@ struct hb_dispatch_context_t
|
|||
* Sanitize
|
||||
*/
|
||||
|
||||
#ifndef HB_DEBUG_SANITIZE
|
||||
#define HB_DEBUG_SANITIZE (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
|
||||
#define TRACE_SANITIZE(this) \
|
||||
hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace \
|
||||
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
|
||||
"");
|
||||
|
||||
/* This limits sanitizing time on really broken fonts. */
|
||||
#ifndef HB_SANITIZE_MAX_EDITS
|
||||
#define HB_SANITIZE_MAX_EDITS 32
|
||||
|
@ -385,16 +378,6 @@ struct Sanitizer
|
|||
* Serialize
|
||||
*/
|
||||
|
||||
#ifndef HB_DEBUG_SERIALIZE
|
||||
#define HB_DEBUG_SERIALIZE (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
|
||||
#define TRACE_SERIALIZE(this) \
|
||||
hb_auto_trace_t<HB_DEBUG_SERIALIZE, bool> trace \
|
||||
(&c->debug_depth, "SERIALIZE", c, HB_FUNC, \
|
||||
"");
|
||||
|
||||
|
||||
struct hb_serialize_context_t
|
||||
{
|
||||
|
@ -632,10 +615,11 @@ struct IntType
|
|||
inline bool operator == (const IntType<Type,Size> &o) const { return (Type) v == (Type) o.v; }
|
||||
inline bool operator != (const IntType<Type,Size> &o) const { return !(*this == o); }
|
||||
static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); }
|
||||
inline int cmp (Type a) const
|
||||
template <typename Type2>
|
||||
inline int cmp (Type2 a) const
|
||||
{
|
||||
Type b = v;
|
||||
if (sizeof (Type) < sizeof (int))
|
||||
if (sizeof (Type) < sizeof (int) && sizeof (Type2) < sizeof (int))
|
||||
return (int) a - (int) b;
|
||||
else
|
||||
return a < b ? -1 : a == b ? 0 : +1;
|
||||
|
@ -651,9 +635,9 @@ struct IntType
|
|||
DEFINE_SIZE_STATIC (Size);
|
||||
};
|
||||
|
||||
typedef IntType<int8_t , 1> CHAR; /* 8-bit signed integer. */
|
||||
typedef IntType<uint8_t , 1> BYTE; /* 8-bit unsigned integer. */
|
||||
typedef IntType<int8_t , 1> INT8; /* 8-bit signed integer. */
|
||||
typedef IntType<int8_t, 1> CHAR; /* 8-bit signed integer. */
|
||||
typedef IntType<uint8_t, 1> BYTE; /* 8-bit unsigned integer. */
|
||||
typedef IntType<int8_t, 1> INT8; /* 8-bit signed integer. */
|
||||
typedef IntType<uint16_t, 2> USHORT; /* 16-bit unsigned integer. */
|
||||
typedef IntType<int16_t, 2> SHORT; /* 16-bit signed integer. */
|
||||
typedef IntType<uint32_t, 4> ULONG; /* 32-bit unsigned integer. */
|
||||
|
@ -713,10 +697,7 @@ struct Tag : ULONG
|
|||
DEFINE_NULL_DATA (Tag, " ");
|
||||
|
||||
/* Glyph index number, same as uint16 (length = 16 bits) */
|
||||
struct GlyphID : USHORT {
|
||||
static inline int cmp (const GlyphID *a, const GlyphID *b) { return b->USHORT::cmp (*a); }
|
||||
inline int cmp (hb_codepoint_t a) const { return (int) a - (int) *this; }
|
||||
};
|
||||
typedef USHORT GlyphID;
|
||||
|
||||
/* Script/language-system/feature index */
|
||||
struct Index : USHORT {
|
||||
|
@ -943,7 +924,7 @@ struct ArrayOf
|
|||
inline bool sanitize_shallow (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) && c->check_array (array, Type::static_size, len));
|
||||
return_trace (len.sanitize (c) && c->check_array (array, Type::static_size, len));
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -1009,12 +990,6 @@ struct HeadlessArrayOf
|
|||
return_trace (true);
|
||||
}
|
||||
|
||||
inline bool sanitize_shallow (hb_sanitize_context_t *c) const
|
||||
{
|
||||
return c->check_struct (this)
|
||||
&& c->check_array (this, Type::static_size, len);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
@ -1032,6 +1007,15 @@ struct HeadlessArrayOf
|
|||
return_trace (true);
|
||||
}
|
||||
|
||||
private:
|
||||
inline bool sanitize_shallow (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (len.sanitize (c) &&
|
||||
(!len || c->check_array (array, Type::static_size, len - 1)));
|
||||
}
|
||||
|
||||
public:
|
||||
LenType len;
|
||||
Type array[VAR];
|
||||
public:
|
||||
|
@ -1039,7 +1023,9 @@ struct HeadlessArrayOf
|
|||
};
|
||||
|
||||
|
||||
/* An array with sorted elements. Supports binary searching. */
|
||||
/*
|
||||
* An array with sorted elements. Supports binary searching.
|
||||
*/
|
||||
template <typename Type, typename LenType=USHORT>
|
||||
struct SortedArrayOf : ArrayOf<Type, LenType>
|
||||
{
|
||||
|
@ -1064,6 +1050,33 @@ struct SortedArrayOf : ArrayOf<Type, LenType>
|
|||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Binary-search arrays
|
||||
*/
|
||||
|
||||
struct BinSearchHeader
|
||||
{
|
||||
inline operator uint32_t (void) const { return len; }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
protected:
|
||||
USHORT len;
|
||||
USHORT searchRangeZ;
|
||||
USHORT entrySelectorZ;
|
||||
USHORT rangeShiftZ;
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (8);
|
||||
};
|
||||
|
||||
template <typename Type>
|
||||
struct BinSearchArrayOf : SortedArrayOf<Type, BinSearchHeader> {};
|
||||
|
||||
|
||||
/* Lazy struct and blob loaders. */
|
||||
|
||||
|
|
|
@ -36,9 +36,10 @@
|
|||
#include "hb-ot-head-table.hh"
|
||||
#include "hb-ot-hhea-table.hh"
|
||||
#include "hb-ot-hmtx-table.hh"
|
||||
#include "hb-ot-kern-table.hh"
|
||||
#include "hb-ot-os2-table.hh"
|
||||
#include "hb-ot-var-hvar-table.hh"
|
||||
#include "hb-ot-post-table.hh"
|
||||
#include "hb-ot-var-hvar-table.hh"
|
||||
|
||||
|
||||
struct hb_ot_face_metrics_accelerator_t
|
||||
|
@ -304,25 +305,24 @@ struct hb_ot_face_cbdt_accelerator_t
|
|||
struct hb_ot_face_post_accelerator_t
|
||||
{
|
||||
hb_blob_t *post_blob;
|
||||
unsigned int post_len;
|
||||
const OT::post *post;
|
||||
OT::post::accelerator_t accel;
|
||||
|
||||
inline void init (hb_face_t *face)
|
||||
{
|
||||
this->post_blob = OT::Sanitizer<OT::post>::sanitize (face->reference_table (HB_OT_TAG_post));
|
||||
this->post = OT::Sanitizer<OT::post>::lock_instance (this->post_blob);
|
||||
this->post_len = hb_blob_get_length (this->post_blob);
|
||||
hb_blob_t *blob = this->post_blob = OT::Sanitizer<OT::post>::sanitize (face->reference_table (HB_OT_TAG_post));
|
||||
accel.init (OT::Sanitizer<OT::post>::lock_instance (blob), hb_blob_get_length (blob));
|
||||
}
|
||||
|
||||
inline void fini (void)
|
||||
{
|
||||
accel.fini ();
|
||||
hb_blob_destroy (this->post_blob);
|
||||
}
|
||||
|
||||
inline bool get_glyph_name (hb_codepoint_t glyph,
|
||||
char *name, unsigned int size) const
|
||||
{
|
||||
return this->post->get_glyph_name (glyph, name, size, this->post_len);
|
||||
return this->accel.get_glyph_name (glyph, name, size);
|
||||
}
|
||||
|
||||
inline bool get_glyph_from_name (const char *name, int len,
|
||||
|
@ -331,10 +331,31 @@ struct hb_ot_face_post_accelerator_t
|
|||
if (unlikely (!len))
|
||||
return false;
|
||||
|
||||
return this->post->get_glyph_from_name (name, len, glyph, this->post_len);
|
||||
return this->accel.get_glyph_from_name (name, len, glyph);
|
||||
}
|
||||
};
|
||||
|
||||
struct hb_ot_face_kern_accelerator_t
|
||||
{
|
||||
hb_blob_t *kern_blob;
|
||||
OT::kern::accelerator_t accel;
|
||||
|
||||
inline void init (hb_face_t *face)
|
||||
{
|
||||
hb_blob_t *blob = this->kern_blob = OT::Sanitizer<OT::kern>::sanitize (face->reference_table (HB_OT_TAG_kern));
|
||||
accel.init (OT::Sanitizer<OT::kern>::lock_instance (blob), hb_blob_get_length (blob));
|
||||
}
|
||||
|
||||
inline void fini (void)
|
||||
{
|
||||
accel.fini ();
|
||||
hb_blob_destroy (this->kern_blob);
|
||||
}
|
||||
|
||||
inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
|
||||
{ return accel.get_h_kerning (left, right); }
|
||||
};
|
||||
|
||||
typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj,
|
||||
hb_codepoint_t codepoint,
|
||||
hb_codepoint_t *glyph);
|
||||
|
@ -471,6 +492,7 @@ struct hb_ot_font_t
|
|||
OT::hb_lazy_loader_t<hb_ot_face_glyf_accelerator_t> glyf;
|
||||
OT::hb_lazy_loader_t<hb_ot_face_cbdt_accelerator_t> cbdt;
|
||||
OT::hb_lazy_loader_t<hb_ot_face_post_accelerator_t> post;
|
||||
OT::hb_lazy_loader_t<hb_ot_face_kern_accelerator_t> kern;
|
||||
};
|
||||
|
||||
|
||||
|
@ -489,6 +511,7 @@ _hb_ot_font_create (hb_face_t *face)
|
|||
ot_font->glyf.init (face);
|
||||
ot_font->cbdt.init (face);
|
||||
ot_font->post.init (face);
|
||||
ot_font->kern.init (face);
|
||||
|
||||
return ot_font;
|
||||
}
|
||||
|
@ -504,6 +527,7 @@ _hb_ot_font_destroy (void *data)
|
|||
ot_font->glyf.fini ();
|
||||
ot_font->cbdt.fini ();
|
||||
ot_font->post.fini ();
|
||||
ot_font->kern.fini ();
|
||||
|
||||
free (ot_font);
|
||||
}
|
||||
|
@ -553,6 +577,17 @@ hb_ot_get_glyph_v_advance (hb_font_t *font,
|
|||
return font->em_scale_y (-(int) ot_font->v_metrics.get_advance (glyph, font));
|
||||
}
|
||||
|
||||
static hb_position_t
|
||||
hb_ot_get_glyph_h_kerning (hb_font_t *font,
|
||||
void *font_data,
|
||||
hb_codepoint_t left_glyph,
|
||||
hb_codepoint_t right_glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
||||
return font->em_scale_x (ot_font->kern->get_h_kerning (left_glyph, right_glyph));
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
hb_ot_get_glyph_extents (hb_font_t *font HB_UNUSED,
|
||||
void *font_data,
|
||||
|
@ -650,7 +685,7 @@ retry:
|
|||
hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ot_get_glyph_v_advance, nullptr, nullptr);
|
||||
//hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, nullptr, nullptr);
|
||||
//hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr);
|
||||
//hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ot_get_glyph_h_kerning, nullptr, nullptr); TODO
|
||||
hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ot_get_glyph_h_kerning, nullptr, nullptr);
|
||||
//hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ot_get_glyph_v_kerning, nullptr, nullptr);
|
||||
hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr);
|
||||
//hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr); TODO
|
||||
|
|
|
@ -0,0 +1,389 @@
|
|||
/*
|
||||
* 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_OT_KERN_TABLE_HH
|
||||
#define HB_OT_KERN_TABLE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
/*
|
||||
* kern -- Kerning
|
||||
*/
|
||||
|
||||
#define HB_OT_TAG_kern HB_TAG('k','e','r','n')
|
||||
|
||||
struct hb_glyph_pair_t
|
||||
{
|
||||
hb_codepoint_t left;
|
||||
hb_codepoint_t right;
|
||||
};
|
||||
|
||||
struct KernPair
|
||||
{
|
||||
inline int get_kerning (void) const
|
||||
{ return value; }
|
||||
|
||||
inline int cmp (const hb_glyph_pair_t &o) const
|
||||
{
|
||||
int ret = left.cmp (o.left);
|
||||
if (ret) return ret;
|
||||
return right.cmp (o.right);
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this));
|
||||
}
|
||||
|
||||
protected:
|
||||
GlyphID left;
|
||||
GlyphID right;
|
||||
FWORD value;
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (6);
|
||||
};
|
||||
|
||||
struct KernSubTableFormat0
|
||||
{
|
||||
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
|
||||
{
|
||||
hb_glyph_pair_t pair = {left, right};
|
||||
int i = pairs.bsearch (pair);
|
||||
if (i == -1)
|
||||
return 0;
|
||||
return pairs[i].get_kerning ();
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (pairs.sanitize (c));
|
||||
}
|
||||
|
||||
protected:
|
||||
BinSearchArrayOf<KernPair> pairs; /* Array of kerning pairs. */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (8, pairs);
|
||||
};
|
||||
|
||||
struct KernClassTable
|
||||
{
|
||||
inline unsigned int get_class (hb_codepoint_t g) const { return classes[g - firstGlyph]; }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (firstGlyph.sanitize (c) && classes.sanitize (c));
|
||||
}
|
||||
|
||||
protected:
|
||||
USHORT firstGlyph; /* First glyph in class range. */
|
||||
ArrayOf<USHORT> classes; /* Glyph classes. */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, classes);
|
||||
};
|
||||
|
||||
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 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))
|
||||
return 0;
|
||||
const FWORD *v = &StructAtOffset<FWORD> (arr, offset);
|
||||
if (unlikely ((const void *) v < (const void *) arr || (const void *) (v + 1) > (const void *) end))
|
||||
return 0;
|
||||
return *v;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (rowWidth.sanitize (c) &&
|
||||
leftClassTable.sanitize (c, this) &&
|
||||
rightClassTable.sanitize (c, this) &&
|
||||
array.sanitize (c, this));
|
||||
}
|
||||
|
||||
protected:
|
||||
USHORT 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. */
|
||||
OffsetTo<KernClassTable>
|
||||
rightClassTable;/* Offset from beginning of this subtable to
|
||||
* right-hand class table. */
|
||||
OffsetTo<FWORD>
|
||||
array; /* Offset from beginning of this subtable to
|
||||
* the start of the kerning array. */
|
||||
public:
|
||||
DEFINE_SIZE_MIN (8);
|
||||
};
|
||||
|
||||
struct KernSubTable
|
||||
{
|
||||
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end, unsigned int format) const
|
||||
{
|
||||
switch (format) {
|
||||
case 0: return u.format0.get_kerning (left, right);
|
||||
case 2: return u.format2.get_kerning (left, right, end);
|
||||
default:return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c, unsigned int format) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
switch (format) {
|
||||
case 0: return_trace (u.format0.sanitize (c));
|
||||
case 2: return_trace (u.format2.sanitize (c));
|
||||
default:return_trace (true);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
union {
|
||||
KernSubTableFormat0 format0;
|
||||
KernSubTableFormat2 format2;
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_MIN (0);
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
struct KernSubTableWrapper
|
||||
{
|
||||
/* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
|
||||
inline const T* thiz (void) const { return static_cast<const T *> (this); }
|
||||
|
||||
inline bool is_horizontal (void) const
|
||||
{ return (thiz()->coverage & T::COVERAGE_CHECK_FLAGS) == T::COVERAGE_CHECK_HORIZONTAL; }
|
||||
|
||||
inline bool is_override (void) const
|
||||
{ return bool (thiz()->coverage & T::COVERAGE_OVERRIDE_FLAG); }
|
||||
|
||||
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
|
||||
{ return thiz()->subtable.get_kerning (left, right, end, thiz()->format); }
|
||||
|
||||
inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, const char *end) const
|
||||
{ return is_horizontal () ? get_kerning (left, right, end) : 0; }
|
||||
|
||||
inline unsigned int get_size (void) const { return thiz()->length; }
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (thiz()) &&
|
||||
thiz()->length >= thiz()->min_size &&
|
||||
c->check_array (thiz(), 1, thiz()->length) &&
|
||||
thiz()->subtable.sanitize (c, thiz()->format));
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct KernTable
|
||||
{
|
||||
/* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
|
||||
inline const T* thiz (void) const { return static_cast<const T *> (this); }
|
||||
|
||||
inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const
|
||||
{
|
||||
int v = 0;
|
||||
const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (thiz()->data);
|
||||
unsigned int count = thiz()->nTables;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
if (st->is_override ())
|
||||
v = 0;
|
||||
v += st->get_h_kerning (left, right, table_length + (const char *) this);
|
||||
st = &StructAfter<typename T::SubTableWrapper> (*st);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!c->check_struct (thiz()) ||
|
||||
thiz()->version != T::VERSION))
|
||||
return_trace (false);
|
||||
|
||||
const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (thiz()->data);
|
||||
unsigned int count = thiz()->nTables;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
if (unlikely (!st->sanitize (c)))
|
||||
return_trace (false);
|
||||
st = &StructAfter<typename T::SubTableWrapper> (*st);
|
||||
}
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
};
|
||||
|
||||
struct KernOT : KernTable<KernOT>
|
||||
{
|
||||
friend struct KernTable<KernOT>;
|
||||
|
||||
static const uint16_t VERSION = 0x0000u;
|
||||
|
||||
struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper>
|
||||
{
|
||||
friend struct KernSubTableWrapper<SubTableWrapper>;
|
||||
|
||||
enum coverage_flags_t {
|
||||
COVERAGE_DIRECTION_FLAG = 0x01u,
|
||||
COVERAGE_MINIMUM_FLAG = 0x02u,
|
||||
COVERAGE_CROSSSTREAM_FLAG = 0x04u,
|
||||
COVERAGE_OVERRIDE_FLAG = 0x08u,
|
||||
|
||||
COVERAGE_VARIATION_FLAG = 0x00u, /* Not supported. */
|
||||
|
||||
COVERAGE_CHECK_FLAGS = 0x07u,
|
||||
COVERAGE_CHECK_HORIZONTAL = 0x01u
|
||||
};
|
||||
|
||||
protected:
|
||||
USHORT versionZ; /* Unused. */
|
||||
USHORT length; /* Length of the subtable (including this header). */
|
||||
BYTE format; /* Subtable format. */
|
||||
BYTE coverage; /* Coverage bits. */
|
||||
KernSubTable subtable; /* Subtable data. */
|
||||
public:
|
||||
DEFINE_SIZE_MIN (6);
|
||||
};
|
||||
|
||||
protected:
|
||||
USHORT version; /* Version--0x0000u */
|
||||
USHORT nTables; /* Number of subtables in the kerning table. */
|
||||
BYTE data[VAR];
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, data);
|
||||
};
|
||||
|
||||
struct KernAAT : KernTable<KernAAT>
|
||||
{
|
||||
friend struct KernTable<KernAAT>;
|
||||
|
||||
static const uint32_t VERSION = 0x00010000u;
|
||||
|
||||
struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper>
|
||||
{
|
||||
friend struct KernSubTableWrapper<SubTableWrapper>;
|
||||
|
||||
enum coverage_flags_t {
|
||||
COVERAGE_DIRECTION_FLAG = 0x80u,
|
||||
COVERAGE_CROSSSTREAM_FLAG = 0x40u,
|
||||
COVERAGE_VARIATION_FLAG = 0x20u,
|
||||
|
||||
COVERAGE_OVERRIDE_FLAG = 0x00u, /* Not supported. */
|
||||
|
||||
COVERAGE_CHECK_FLAGS = 0xE0u,
|
||||
COVERAGE_CHECK_HORIZONTAL = 0x00u
|
||||
};
|
||||
|
||||
protected:
|
||||
ULONG length; /* Length of the subtable (including this header). */
|
||||
BYTE coverage; /* Coverage bits. */
|
||||
BYTE format; /* Subtable format. */
|
||||
USHORT tupleIndex; /* The tuple index (used for variations fonts).
|
||||
* This value specifies which tuple this subtable covers. */
|
||||
KernSubTable subtable; /* Subtable data. */
|
||||
public:
|
||||
DEFINE_SIZE_MIN (8);
|
||||
};
|
||||
|
||||
protected:
|
||||
ULONG version; /* Version--0x00010000u */
|
||||
ULONG nTables; /* Number of subtables in the kerning table. */
|
||||
BYTE data[VAR];
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (8, data);
|
||||
};
|
||||
|
||||
struct kern
|
||||
{
|
||||
static const hb_tag_t tableTag = HB_OT_TAG_kern;
|
||||
|
||||
inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const
|
||||
{
|
||||
switch (u.major) {
|
||||
case 0: return u.ot.get_h_kerning (left, right, table_length);
|
||||
case 1: return u.aat.get_h_kerning (left, right, table_length);
|
||||
default:return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (!u.major.sanitize (c)) return_trace (false);
|
||||
switch (u.major) {
|
||||
case 0: return_trace (u.ot.sanitize (c));
|
||||
case 1: return_trace (u.aat.sanitize (c));
|
||||
default:return_trace (true);
|
||||
}
|
||||
}
|
||||
|
||||
struct accelerator_t
|
||||
{
|
||||
inline void init (const kern *table_, unsigned int table_length_)
|
||||
{
|
||||
table = table_;
|
||||
table_length = table_length_;
|
||||
}
|
||||
inline void fini (void) {}
|
||||
|
||||
inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
|
||||
{ return table->get_h_kerning (left, right, table_length); }
|
||||
|
||||
private:
|
||||
const kern *table;
|
||||
unsigned int table_length;
|
||||
};
|
||||
|
||||
protected:
|
||||
union {
|
||||
USHORT major;
|
||||
KernOT ot;
|
||||
KernAAT aat;
|
||||
} u;
|
||||
public:
|
||||
DEFINE_SIZE_UNION (2, major);
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
||||
|
||||
#endif /* HB_OT_KERN_TABLE_HH */
|
|
@ -29,6 +29,8 @@
|
|||
#ifndef HB_OT_LAYOUT_COMMON_PRIVATE_HH
|
||||
#define HB_OT_LAYOUT_COMMON_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
#include "hb-debug.hh"
|
||||
#include "hb-ot-layout-private.hh"
|
||||
#include "hb-open-type-private.hh"
|
||||
#include "hb-set-private.hh"
|
||||
|
@ -45,12 +47,6 @@
|
|||
namespace OT {
|
||||
|
||||
|
||||
#define TRACE_DISPATCH(this, format) \
|
||||
hb_auto_trace_t<context_t::max_debug_depth, typename context_t::return_t> trace \
|
||||
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
|
||||
"format %d", (int) format);
|
||||
|
||||
|
||||
#define NOT_COVERED ((unsigned int) -1)
|
||||
|
||||
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
#ifndef HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH
|
||||
#define HB_OT_LAYOUT_GSUBGPOS_PRIVATE_HH
|
||||
|
||||
#include "hb-private.hh"
|
||||
#include "hb-debug.hh"
|
||||
#include "hb-buffer-private.hh"
|
||||
#include "hb-ot-layout-gdef-table.hh"
|
||||
#include "hb-set-private.hh"
|
||||
|
@ -37,15 +39,6 @@
|
|||
namespace OT {
|
||||
|
||||
|
||||
#ifndef HB_DEBUG_CLOSURE
|
||||
#define HB_DEBUG_CLOSURE (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
#define TRACE_CLOSURE(this) \
|
||||
hb_auto_trace_t<HB_DEBUG_CLOSURE, hb_void_t> trace \
|
||||
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
|
||||
"");
|
||||
|
||||
struct hb_closure_context_t :
|
||||
hb_dispatch_context_t<hb_closure_context_t, hb_void_t, HB_DEBUG_CLOSURE>
|
||||
{
|
||||
|
@ -85,16 +78,6 @@ struct hb_closure_context_t :
|
|||
};
|
||||
|
||||
|
||||
|
||||
#ifndef HB_DEBUG_WOULD_APPLY
|
||||
#define HB_DEBUG_WOULD_APPLY (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
#define TRACE_WOULD_APPLY(this) \
|
||||
hb_auto_trace_t<HB_DEBUG_WOULD_APPLY, bool> trace \
|
||||
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
|
||||
"%d glyphs", c->len);
|
||||
|
||||
struct hb_would_apply_context_t :
|
||||
hb_dispatch_context_t<hb_would_apply_context_t, bool, HB_DEBUG_WOULD_APPLY>
|
||||
{
|
||||
|
@ -122,16 +105,6 @@ struct hb_would_apply_context_t :
|
|||
};
|
||||
|
||||
|
||||
|
||||
#ifndef HB_DEBUG_COLLECT_GLYPHS
|
||||
#define HB_DEBUG_COLLECT_GLYPHS (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
#define TRACE_COLLECT_GLYPHS(this) \
|
||||
hb_auto_trace_t<HB_DEBUG_COLLECT_GLYPHS, hb_void_t> trace \
|
||||
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
|
||||
"");
|
||||
|
||||
struct hb_collect_glyphs_context_t :
|
||||
hb_dispatch_context_t<hb_collect_glyphs_context_t, hb_void_t, HB_DEBUG_COLLECT_GLYPHS>
|
||||
{
|
||||
|
@ -219,10 +192,6 @@ struct hb_collect_glyphs_context_t :
|
|||
|
||||
|
||||
|
||||
#ifndef HB_DEBUG_GET_COVERAGE
|
||||
#define HB_DEBUG_GET_COVERAGE (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
/* XXX Can we remove this? */
|
||||
|
||||
template <typename set_t>
|
||||
|
@ -249,17 +218,6 @@ struct hb_add_coverage_context_t :
|
|||
};
|
||||
|
||||
|
||||
|
||||
#ifndef HB_DEBUG_APPLY
|
||||
#define HB_DEBUG_APPLY (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
#define TRACE_APPLY(this) \
|
||||
hb_auto_trace_t<HB_DEBUG_APPLY, bool> trace \
|
||||
(&c->debug_depth, c->get_name (), this, HB_FUNC, \
|
||||
"idx %d gid %u lookup %d", \
|
||||
c->buffer->idx, c->buffer->cur().codepoint, (int) c->lookup_index);
|
||||
|
||||
struct hb_apply_context_t :
|
||||
hb_dispatch_context_t<hb_apply_context_t, bool, HB_DEBUG_APPLY>
|
||||
{
|
||||
|
@ -1247,11 +1205,11 @@ struct Rule
|
|||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return inputCount.sanitize (c)
|
||||
&& lookupCount.sanitize (c)
|
||||
&& c->check_range (inputZ,
|
||||
inputZ[0].static_size * inputCount
|
||||
+ lookupRecordX[0].static_size * lookupCount);
|
||||
return_trace (inputCount.sanitize (c) &&
|
||||
lookupCount.sanitize (c) &&
|
||||
c->check_range (inputZ,
|
||||
inputZ[0].static_size * inputCount +
|
||||
lookupRecordX[0].static_size * lookupCount));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -35,10 +35,14 @@
|
|||
#include "hb-ot-layout-gsub-table.hh"
|
||||
#include "hb-ot-layout-gpos-table.hh"
|
||||
#include "hb-ot-layout-jstf-table.hh" // Just so we compile it; unused otherwise.
|
||||
#include "hb-ot-name-table.hh" // Just so we compile it; unused otherwise.
|
||||
|
||||
#include "hb-ot-map-private.hh"
|
||||
|
||||
|
||||
const void * const OT::_hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
|
||||
|
||||
|
||||
hb_ot_layout_t *
|
||||
_hb_ot_layout_create (hb_face_t *face)
|
||||
{
|
||||
|
|
|
@ -63,8 +63,12 @@ struct hb_ot_map_t
|
|||
unsigned short auto_zwj : 1;
|
||||
hb_mask_t mask;
|
||||
|
||||
static int cmp (const lookup_map_t *a, const lookup_map_t *b)
|
||||
{ return a->index < b->index ? -1 : a->index > b->index ? 1 : 0; }
|
||||
static int cmp (const void *pa, const void *pb)
|
||||
{
|
||||
const lookup_map_t *a = (const lookup_map_t *) pa;
|
||||
const lookup_map_t *b = (const lookup_map_t *) pb;
|
||||
return a->index < b->index ? -1 : a->index > b->index ? 1 : 0;
|
||||
}
|
||||
};
|
||||
|
||||
typedef void (*pause_func_t) (const struct hb_ot_shape_plan_t *plan, hb_font_t *font, hb_buffer_t *buffer);
|
||||
|
@ -210,9 +214,13 @@ struct hb_ot_map_builder_t
|
|||
unsigned int default_value; /* for non-global features, what should the unset glyphs take */
|
||||
unsigned int stage[2]; /* GSUB/GPOS */
|
||||
|
||||
static int cmp (const feature_info_t *a, const feature_info_t *b)
|
||||
{ return (a->tag != b->tag) ? (a->tag < b->tag ? -1 : 1) :
|
||||
(a->seq < b->seq ? -1 : a->seq > b->seq ? 1 : 0); }
|
||||
static int cmp (const void *pa, const void *pb)
|
||||
{
|
||||
const feature_info_t *a = (const feature_info_t *) pa;
|
||||
const feature_info_t *b = (const feature_info_t *) pb;
|
||||
return (a->tag != b->tag) ? (a->tag < b->tag ? -1 : 1) :
|
||||
(a->seq < b->seq ? -1 : a->seq > b->seq ? 1 : 0);
|
||||
}
|
||||
};
|
||||
|
||||
struct stage_info_t {
|
||||
|
|
|
@ -42,8 +42,10 @@ namespace OT {
|
|||
|
||||
struct NameRecord
|
||||
{
|
||||
static int cmp (const NameRecord *a, const NameRecord *b)
|
||||
static int cmp (const void *pa, const void *pb)
|
||||
{
|
||||
const NameRecord *a = (const NameRecord *) pa;
|
||||
const NameRecord *b = (const NameRecord *) pb;
|
||||
int ret;
|
||||
ret = b->platformID.cmp (a->platformID);
|
||||
if (ret) return ret;
|
||||
|
@ -89,7 +91,7 @@ struct name
|
|||
key.encodingID.set (encoding_id);
|
||||
key.languageID.set (language_id);
|
||||
key.nameID.set (name_id);
|
||||
NameRecord *match = (NameRecord *) bsearch (&key, nameRecord, count, sizeof (nameRecord[0]), (hb_compare_func_t) NameRecord::cmp);
|
||||
NameRecord *match = (NameRecord *) bsearch (&key, nameRecord, count, sizeof (nameRecord[0]), NameRecord::cmp);
|
||||
|
||||
if (!match)
|
||||
return 0;
|
||||
|
|
|
@ -0,0 +1,294 @@
|
|||
/*
|
||||
* 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_OT_POST_MACROMAN_HH
|
||||
#if 0 /* Make checks happy. */
|
||||
#define HB_OT_POST_MACROMAN_HH
|
||||
#include "hb-private.hh"
|
||||
#endif
|
||||
|
||||
|
||||
_S(".notdef")
|
||||
_S(".null")
|
||||
_S("nonmarkingreturn")
|
||||
_S("space")
|
||||
_S("exclam")
|
||||
_S("quotedbl")
|
||||
_S("numbersign")
|
||||
_S("dollar")
|
||||
_S("percent")
|
||||
_S("ampersand")
|
||||
_S("quotesingle")
|
||||
_S("parenleft")
|
||||
_S("parenright")
|
||||
_S("asterisk")
|
||||
_S("plus")
|
||||
_S("comma")
|
||||
_S("hyphen")
|
||||
_S("period")
|
||||
_S("slash")
|
||||
_S("zero")
|
||||
_S("one")
|
||||
_S("two")
|
||||
_S("three")
|
||||
_S("four")
|
||||
_S("five")
|
||||
_S("six")
|
||||
_S("seven")
|
||||
_S("eight")
|
||||
_S("nine")
|
||||
_S("colon")
|
||||
_S("semicolon")
|
||||
_S("less")
|
||||
_S("equal")
|
||||
_S("greater")
|
||||
_S("question")
|
||||
_S("at")
|
||||
_S("A")
|
||||
_S("B")
|
||||
_S("C")
|
||||
_S("D")
|
||||
_S("E")
|
||||
_S("F")
|
||||
_S("G")
|
||||
_S("H")
|
||||
_S("I")
|
||||
_S("J")
|
||||
_S("K")
|
||||
_S("L")
|
||||
_S("M")
|
||||
_S("N")
|
||||
_S("O")
|
||||
_S("P")
|
||||
_S("Q")
|
||||
_S("R")
|
||||
_S("S")
|
||||
_S("T")
|
||||
_S("U")
|
||||
_S("V")
|
||||
_S("W")
|
||||
_S("X")
|
||||
_S("Y")
|
||||
_S("Z")
|
||||
_S("bracketleft")
|
||||
_S("backslash")
|
||||
_S("bracketright")
|
||||
_S("asciicircum")
|
||||
_S("underscore")
|
||||
_S("grave")
|
||||
_S("a")
|
||||
_S("b")
|
||||
_S("c")
|
||||
_S("d")
|
||||
_S("e")
|
||||
_S("f")
|
||||
_S("g")
|
||||
_S("h")
|
||||
_S("i")
|
||||
_S("j")
|
||||
_S("k")
|
||||
_S("l")
|
||||
_S("m")
|
||||
_S("n")
|
||||
_S("o")
|
||||
_S("p")
|
||||
_S("q")
|
||||
_S("r")
|
||||
_S("s")
|
||||
_S("t")
|
||||
_S("u")
|
||||
_S("v")
|
||||
_S("w")
|
||||
_S("x")
|
||||
_S("y")
|
||||
_S("z")
|
||||
_S("braceleft")
|
||||
_S("bar")
|
||||
_S("braceright")
|
||||
_S("asciitilde")
|
||||
_S("Adieresis")
|
||||
_S("Aring")
|
||||
_S("Ccedilla")
|
||||
_S("Eacute")
|
||||
_S("Ntilde")
|
||||
_S("Odieresis")
|
||||
_S("Udieresis")
|
||||
_S("aacute")
|
||||
_S("agrave")
|
||||
_S("acircumflex")
|
||||
_S("adieresis")
|
||||
_S("atilde")
|
||||
_S("aring")
|
||||
_S("ccedilla")
|
||||
_S("eacute")
|
||||
_S("egrave")
|
||||
_S("ecircumflex")
|
||||
_S("edieresis")
|
||||
_S("iacute")
|
||||
_S("igrave")
|
||||
_S("icircumflex")
|
||||
_S("idieresis")
|
||||
_S("ntilde")
|
||||
_S("oacute")
|
||||
_S("ograve")
|
||||
_S("ocircumflex")
|
||||
_S("odieresis")
|
||||
_S("otilde")
|
||||
_S("uacute")
|
||||
_S("ugrave")
|
||||
_S("ucircumflex")
|
||||
_S("udieresis")
|
||||
_S("dagger")
|
||||
_S("degree")
|
||||
_S("cent")
|
||||
_S("sterling")
|
||||
_S("section")
|
||||
_S("bullet")
|
||||
_S("paragraph")
|
||||
_S("germandbls")
|
||||
_S("registered")
|
||||
_S("copyright")
|
||||
_S("trademark")
|
||||
_S("acute")
|
||||
_S("dieresis")
|
||||
_S("notequal")
|
||||
_S("AE")
|
||||
_S("Oslash")
|
||||
_S("infinity")
|
||||
_S("plusminus")
|
||||
_S("lessequal")
|
||||
_S("greaterequal")
|
||||
_S("yen")
|
||||
_S("mu")
|
||||
_S("partialdiff")
|
||||
_S("summation")
|
||||
_S("product")
|
||||
_S("pi")
|
||||
_S("integral")
|
||||
_S("ordfeminine")
|
||||
_S("ordmasculine")
|
||||
_S("Omega")
|
||||
_S("ae")
|
||||
_S("oslash")
|
||||
_S("questiondown")
|
||||
_S("exclamdown")
|
||||
_S("logicalnot")
|
||||
_S("radical")
|
||||
_S("florin")
|
||||
_S("approxequal")
|
||||
_S("Delta")
|
||||
_S("guillemotleft")
|
||||
_S("guillemotright")
|
||||
_S("ellipsis")
|
||||
_S("nonbreakingspace")
|
||||
_S("Agrave")
|
||||
_S("Atilde")
|
||||
_S("Otilde")
|
||||
_S("OE")
|
||||
_S("oe")
|
||||
_S("endash")
|
||||
_S("emdash")
|
||||
_S("quotedblleft")
|
||||
_S("quotedblright")
|
||||
_S("quoteleft")
|
||||
_S("quoteright")
|
||||
_S("divide")
|
||||
_S("lozenge")
|
||||
_S("ydieresis")
|
||||
_S("Ydieresis")
|
||||
_S("fraction")
|
||||
_S("currency")
|
||||
_S("guilsinglleft")
|
||||
_S("guilsinglright")
|
||||
_S("fi")
|
||||
_S("fl")
|
||||
_S("daggerdbl")
|
||||
_S("periodcentered")
|
||||
_S("quotesinglbase")
|
||||
_S("quotedblbase")
|
||||
_S("perthousand")
|
||||
_S("Acircumflex")
|
||||
_S("Ecircumflex")
|
||||
_S("Aacute")
|
||||
_S("Edieresis")
|
||||
_S("Egrave")
|
||||
_S("Iacute")
|
||||
_S("Icircumflex")
|
||||
_S("Idieresis")
|
||||
_S("Igrave")
|
||||
_S("Oacute")
|
||||
_S("Ocircumflex")
|
||||
_S("apple")
|
||||
_S("Ograve")
|
||||
_S("Uacute")
|
||||
_S("Ucircumflex")
|
||||
_S("Ugrave")
|
||||
_S("dotlessi")
|
||||
_S("circumflex")
|
||||
_S("tilde")
|
||||
_S("macron")
|
||||
_S("breve")
|
||||
_S("dotaccent")
|
||||
_S("ring")
|
||||
_S("cedilla")
|
||||
_S("hungarumlaut")
|
||||
_S("ogonek")
|
||||
_S("caron")
|
||||
_S("Lslash")
|
||||
_S("lslash")
|
||||
_S("Scaron")
|
||||
_S("scaron")
|
||||
_S("Zcaron")
|
||||
_S("zcaron")
|
||||
_S("brokenbar")
|
||||
_S("Eth")
|
||||
_S("eth")
|
||||
_S("Yacute")
|
||||
_S("yacute")
|
||||
_S("Thorn")
|
||||
_S("thorn")
|
||||
_S("minus")
|
||||
_S("multiply")
|
||||
_S("onesuperior")
|
||||
_S("twosuperior")
|
||||
_S("threesuperior")
|
||||
_S("onehalf")
|
||||
_S("onequarter")
|
||||
_S("threequarters")
|
||||
_S("franc")
|
||||
_S("Gbreve")
|
||||
_S("gbreve")
|
||||
_S("Idotaccent")
|
||||
_S("Scedilla")
|
||||
_S("scedilla")
|
||||
_S("Cacute")
|
||||
_S("cacute")
|
||||
_S("Ccaron")
|
||||
_S("ccaron")
|
||||
_S("dcroat")
|
||||
|
||||
|
||||
#endif /* HB_OT_POST_MACROMAN_HH */
|
|
@ -28,50 +28,16 @@
|
|||
#define HB_OT_POST_TABLE_HH
|
||||
|
||||
#include "hb-open-type-private.hh"
|
||||
#include "hb-dsalgs.hh"
|
||||
|
||||
#define HB_STRING_ARRAY_NAME format1_names
|
||||
#define HB_STRING_ARRAY_LIST "hb-ot-post-macroman.hh"
|
||||
#include "hb-string-array.hh"
|
||||
#undef HB_STRING_ARRAY_LIST
|
||||
#undef HB_STRING_ARRAY_NAME
|
||||
|
||||
#define NUM_FORMAT1_NAMES 258
|
||||
|
||||
static const char* const format1_names[NUM_FORMAT1_NAMES] =
|
||||
{
|
||||
".notdef", ".null", "nonmarkingreturn", "space", "exclam", "quotedbl",
|
||||
"numbersign", "dollar", "percent", "ampersand", "quotesingle", "parenleft",
|
||||
"parenright", "asterisk", "plus", "comma", "hyphen", "period", "slash",
|
||||
"zero", "one", "two", "three", "four", "five", "six", "seven", "eight",
|
||||
"nine", "colon", "semicolon", "less", "equal", "greater", "question", "at",
|
||||
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O",
|
||||
"P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bracketleft",
|
||||
"backslash", "bracketright", "asciicircum", "underscore", "grave", "a", "b",
|
||||
"c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q",
|
||||
"r", "s", "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar",
|
||||
"braceright", "asciitilde", "Adieresis", "Aring", "Ccedilla", "Eacute",
|
||||
"Ntilde", "Odieresis", "Udieresis", "aacute", "agrave", "acircumflex",
|
||||
"adieresis", "atilde", "aring", "ccedilla", "eacute", "egrave",
|
||||
"ecircumflex", "edieresis", "iacute", "igrave", "icircumflex", "idieresis",
|
||||
"ntilde", "oacute", "ograve", "ocircumflex", "odieresis", "otilde", "uacute",
|
||||
"ugrave", "ucircumflex", "udieresis", "dagger", "degree", "cent", "sterling",
|
||||
"section", "bullet", "paragraph", "germandbls", "registered", "copyright",
|
||||
"trademark", "acute", "dieresis", "notequal", "AE", "Oslash", "infinity",
|
||||
"plusminus", "lessequal", "greaterequal", "yen", "mu", "partialdiff",
|
||||
"summation", "product", "pi", "integral", "ordfeminine", "ordmasculine",
|
||||
"Omega", "ae", "oslash", "questiondown", "exclamdown", "logicalnot",
|
||||
"radical", "florin", "approxequal", "Delta", "guillemotleft",
|
||||
"guillemotright", "ellipsis", "nonbreakingspace", "Agrave", "Atilde",
|
||||
"Otilde", "OE", "oe", "endash", "emdash", "quotedblleft", "quotedblright",
|
||||
"quoteleft", "quoteright", "divide", "lozenge", "ydieresis", "Ydieresis",
|
||||
"fraction", "currency", "guilsinglleft", "guilsinglright", "fi", "fl",
|
||||
"daggerdbl", "periodcentered", "quotesinglbase", "quotedblbase",
|
||||
"perthousand", "Acircumflex", "Ecircumflex", "Aacute", "Edieresis", "Egrave",
|
||||
"Iacute", "Icircumflex", "Idieresis", "Igrave", "Oacute", "Ocircumflex",
|
||||
"apple", "Ograve", "Uacute", "Ucircumflex", "Ugrave", "dotlessi",
|
||||
"circumflex", "tilde", "macron", "breve", "dotaccent", "ring", "cedilla",
|
||||
"hungarumlaut", "ogonek", "caron", "Lslash", "lslash", "Scaron", "scaron",
|
||||
"Zcaron", "zcaron", "brokenbar", "Eth", "eth", "Yacute", "yacute", "Thorn",
|
||||
"thorn", "minus", "multiply", "onesuperior", "twosuperior", "threesuperior",
|
||||
"onehalf", "onequarter", "threequarters", "franc", "Gbreve", "gbreve",
|
||||
"Idotaccent", "Scedilla", "scedilla", "Cacute", "cacute", "Ccaron", "ccaron",
|
||||
"dcroat",
|
||||
};
|
||||
|
||||
namespace OT {
|
||||
|
||||
|
||||
|
@ -87,13 +53,10 @@ struct postV2Tail
|
|||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (numberOfGlyphs.sanitize (c) &&
|
||||
c->check_array (glyphNameIndex, sizeof (USHORT), numberOfGlyphs));
|
||||
return_trace (glyphNameIndex.sanitize (c));
|
||||
}
|
||||
|
||||
USHORT numberOfGlyphs; /* Number of glyphs (this should be the
|
||||
* same as numGlyphs in 'maxp' table). */
|
||||
USHORT glyphNameIndex[VAR]; /* This is not an offset, but is the
|
||||
ArrayOf<USHORT>glyphNameIndex; /* This is not an offset, but is the
|
||||
* ordinal number of the glyph in 'post'
|
||||
* string tables. */
|
||||
BYTE namesX[VAR]; /* Glyph names with length bytes [variable]
|
||||
|
@ -119,134 +82,157 @@ struct post
|
|||
return_trace (true);
|
||||
}
|
||||
|
||||
inline bool get_glyph_name (hb_codepoint_t glyph,
|
||||
char *buffer, unsigned int buffer_length,
|
||||
unsigned int blob_len) const
|
||||
struct accelerator_t
|
||||
{
|
||||
if (version.to_int () == 0x00010000)
|
||||
inline void init (const post *table, unsigned int post_len)
|
||||
{
|
||||
if (glyph >= NUM_FORMAT1_NAMES)
|
||||
return false;
|
||||
version = table->version.to_int ();
|
||||
index_to_offset.init ();
|
||||
if (version != 0x00020000)
|
||||
return;
|
||||
|
||||
if (!buffer_length)
|
||||
const postV2Tail &v2 = StructAfter<postV2Tail> (*table);
|
||||
|
||||
glyphNameIndex = &v2.glyphNameIndex;
|
||||
pool = &StructAfter<uint8_t> (v2.glyphNameIndex);
|
||||
|
||||
const uint8_t *end = (uint8_t *) table + post_len;
|
||||
for (const uint8_t *data = pool; data < end && data + *data <= end; data += 1 + *data)
|
||||
{
|
||||
uint32_t *offset = index_to_offset.push ();
|
||||
if (unlikely (!offset))
|
||||
break;
|
||||
*offset = data - pool;
|
||||
}
|
||||
}
|
||||
inline void fini (void)
|
||||
{
|
||||
index_to_offset.finish ();
|
||||
free (gids_sorted_by_name);
|
||||
}
|
||||
|
||||
inline bool get_glyph_name (hb_codepoint_t glyph,
|
||||
char *buf, unsigned int buf_len) const
|
||||
{
|
||||
hb_string_t s = find_glyph_name (glyph);
|
||||
if (!s.len)
|
||||
return false;
|
||||
if (!buf_len)
|
||||
return true;
|
||||
strncpy (buffer, format1_names[glyph], buffer_length);
|
||||
buffer[buffer_length - 1] = '\0';
|
||||
if (buf_len <= s.len) /* What to do with truncation? Returning false for now. */
|
||||
return false;
|
||||
strncpy (buf, s.bytes, s.len);
|
||||
buf[s.len] = '\0';
|
||||
return true;
|
||||
}
|
||||
|
||||
if (version.to_int () == 0x00020000)
|
||||
inline bool get_glyph_from_name (const char *name, int len,
|
||||
hb_codepoint_t *glyph) const
|
||||
{
|
||||
const postV2Tail &v2 = StructAfter<postV2Tail> (*this);
|
||||
unsigned int count = get_glyph_count ();
|
||||
if (unlikely (!count))
|
||||
return false;
|
||||
|
||||
if (glyph >= v2.numberOfGlyphs)
|
||||
if (len < 0)
|
||||
len = strlen (name);
|
||||
|
||||
if (unlikely (!len))
|
||||
return false;
|
||||
|
||||
if (!buffer_length)
|
||||
return true;
|
||||
retry:
|
||||
uint16_t *gids = (uint16_t *) hb_atomic_ptr_get (&gids_sorted_by_name);
|
||||
|
||||
unsigned int index = v2.glyphNameIndex[glyph];
|
||||
if (index < NUM_FORMAT1_NAMES)
|
||||
if (unlikely (!gids))
|
||||
{
|
||||
if (!buffer_length)
|
||||
return true;
|
||||
strncpy (buffer, format1_names[index], buffer_length);
|
||||
buffer[buffer_length - 1] = '\0';
|
||||
gids = (uint16_t *) malloc (count * sizeof (gids[0]));
|
||||
if (unlikely (!gids))
|
||||
return false; /* Anything better?! */
|
||||
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
gids[i] = i;
|
||||
hb_sort_r (gids, count, sizeof (gids[0]), cmp_gids, (void *) this);
|
||||
|
||||
if (!hb_atomic_ptr_cmpexch (&gids_sorted_by_name, nullptr, gids)) {
|
||||
free (gids);
|
||||
goto retry;
|
||||
}
|
||||
}
|
||||
|
||||
hb_string_t st (name, len);
|
||||
const uint16_t *gid = (const uint16_t *) hb_bsearch_r (&st, gids, count, sizeof (gids[0]), cmp_key, (void *) this);
|
||||
if (gid)
|
||||
{
|
||||
*glyph = *gid;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
inline unsigned int get_glyph_count (void) const
|
||||
{
|
||||
if (version == 0x00010000)
|
||||
return NUM_FORMAT1_NAMES;
|
||||
|
||||
if (version == 0x00020000)
|
||||
return glyphNameIndex->len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int cmp_gids (const void *pa, const void *pb, void *arg)
|
||||
{
|
||||
const accelerator_t *thiz = (const accelerator_t *) arg;
|
||||
uint16_t a = * (const uint16_t *) pa;
|
||||
uint16_t b = * (const uint16_t *) pb;
|
||||
return thiz->find_glyph_name (b).cmp (thiz->find_glyph_name (a));
|
||||
}
|
||||
|
||||
static inline int cmp_key (const void *pk, const void *po, void *arg)
|
||||
{
|
||||
const accelerator_t *thiz = (const accelerator_t *) arg;
|
||||
const hb_string_t *key = (const hb_string_t *) pk;
|
||||
uint16_t o = * (const uint16_t *) po;
|
||||
return thiz->find_glyph_name (o).cmp (*key);
|
||||
}
|
||||
|
||||
inline hb_string_t find_glyph_name (hb_codepoint_t glyph) const
|
||||
{
|
||||
if (version == 0x00010000)
|
||||
{
|
||||
if (glyph >= NUM_FORMAT1_NAMES)
|
||||
return hb_string_t ();
|
||||
|
||||
return format1_names (glyph);
|
||||
}
|
||||
|
||||
if (version != 0x00020000 || glyph >= glyphNameIndex->len)
|
||||
return hb_string_t ();
|
||||
|
||||
unsigned int index = glyphNameIndex->array[glyph];
|
||||
if (index < NUM_FORMAT1_NAMES)
|
||||
return format1_names (index);
|
||||
index -= NUM_FORMAT1_NAMES;
|
||||
|
||||
unsigned int offset = min_size + v2.min_size + 2 * v2.numberOfGlyphs;
|
||||
unsigned char *data = (unsigned char *) this + offset;
|
||||
unsigned char *end = (unsigned char *) this + blob_len;
|
||||
for (unsigned int i = 0; data < end; i++)
|
||||
{
|
||||
unsigned int name_length = data[0];
|
||||
data++;
|
||||
if (i == index)
|
||||
{
|
||||
if (unlikely (!name_length))
|
||||
return false;
|
||||
if (index >= index_to_offset.len)
|
||||
return hb_string_t ();
|
||||
unsigned int offset = index_to_offset.array[index];
|
||||
|
||||
unsigned int remaining = end - data;
|
||||
name_length = MIN (name_length, buffer_length - 1);
|
||||
name_length = MIN (name_length, remaining);
|
||||
memcpy (buffer, data, name_length);
|
||||
buffer[name_length] = '\0';
|
||||
return true;
|
||||
}
|
||||
data += name_length;
|
||||
}
|
||||
const uint8_t *data = pool + offset;
|
||||
unsigned int name_length = *data;
|
||||
data++;
|
||||
|
||||
return false;
|
||||
return hb_string_t ((const char *) data, name_length);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool get_glyph_from_name (const char *name, int len,
|
||||
hb_codepoint_t *glyph,
|
||||
unsigned int blob_len) const
|
||||
{
|
||||
if (len < 0)
|
||||
len = strlen (name);
|
||||
|
||||
if (version.to_int () == 0x00010000)
|
||||
{
|
||||
for (int i = 0; i < NUM_FORMAT1_NAMES; i++)
|
||||
{
|
||||
if (strncmp (name, format1_names[i], len) == 0 && format1_names[i][len] == '\0')
|
||||
{
|
||||
*glyph = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (version.to_int () == 0x00020000)
|
||||
{
|
||||
const postV2Tail &v2 = StructAfter<postV2Tail> (*this);
|
||||
unsigned int offset = min_size + v2.min_size + 2 * v2.numberOfGlyphs;
|
||||
char* data = (char*) this + offset;
|
||||
|
||||
|
||||
/* XXX The following code is wrong. */
|
||||
return false;
|
||||
for (hb_codepoint_t gid = 0; gid < v2.numberOfGlyphs; gid++)
|
||||
{
|
||||
unsigned int index = v2.glyphNameIndex[gid];
|
||||
if (index < NUM_FORMAT1_NAMES)
|
||||
{
|
||||
if (strncmp (name, format1_names[index], len) == 0 && format1_names[index][len] == '\0')
|
||||
{
|
||||
*glyph = gid;
|
||||
return true;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
index -= NUM_FORMAT1_NAMES;
|
||||
|
||||
for (unsigned int i = 0; data < (char*) this + blob_len; i++)
|
||||
{
|
||||
unsigned int name_length = data[0];
|
||||
unsigned int remaining = (char*) this + blob_len - data - 1;
|
||||
name_length = MIN (name_length, remaining);
|
||||
if (name_length == (unsigned int) len && strncmp (name, data + 1, len) == 0)
|
||||
{
|
||||
*glyph = gid;
|
||||
return true;
|
||||
}
|
||||
data += name_length + 1;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
uint32_t version;
|
||||
const ArrayOf<USHORT> *glyphNameIndex;
|
||||
hb_prealloced_array_t<uint32_t, 1> index_to_offset;
|
||||
const uint8_t *pool;
|
||||
mutable uint16_t *gids_sorted_by_name;
|
||||
};
|
||||
|
||||
public:
|
||||
FixedVersion<>version; /* 0x00010000 for version 1.0
|
||||
|
|
|
@ -24,15 +24,12 @@
|
|||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-private.hh"
|
||||
#include "hb-debug.hh"
|
||||
#include "hb-ot-shape-complex-arabic-private.hh"
|
||||
#include "hb-ot-shape-private.hh"
|
||||
|
||||
|
||||
#ifndef HB_DEBUG_ARABIC
|
||||
#define HB_DEBUG_ARABIC (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
|
||||
/* buffer var allocations */
|
||||
#define arabic_shaping_action() complex_var_u8_0() /* arabic shaping action */
|
||||
|
||||
|
@ -563,6 +560,7 @@ apply_stch (const hb_ot_shape_plan_t *plan,
|
|||
}
|
||||
else
|
||||
{
|
||||
buffer->unsafe_to_break (context, end);
|
||||
hb_position_t x_offset = 0;
|
||||
for (unsigned int k = end; k > start; k--)
|
||||
{
|
||||
|
@ -689,7 +687,6 @@ reorder_marks_arabic (const hb_ot_shape_plan_t *plan,
|
|||
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_arabic =
|
||||
{
|
||||
"arabic",
|
||||
collect_features_arabic,
|
||||
nullptr, /* override_features */
|
||||
data_create_arabic,
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_default =
|
||||
{
|
||||
"default",
|
||||
nullptr, /* collect_features */
|
||||
nullptr, /* override_features */
|
||||
nullptr, /* data_create */
|
||||
|
|
|
@ -414,7 +414,6 @@ setup_masks_hangul (const hb_ot_shape_plan_t *plan,
|
|||
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hangul =
|
||||
{
|
||||
"hangul",
|
||||
collect_features_hangul,
|
||||
override_features_hangul,
|
||||
data_create_hangul,
|
||||
|
|
|
@ -169,7 +169,6 @@ disable_otl_hebrew (const hb_ot_shape_plan_t *plan)
|
|||
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew =
|
||||
{
|
||||
"hebrew",
|
||||
nullptr, /* collect_features */
|
||||
nullptr, /* override_features */
|
||||
nullptr, /* data_create */
|
||||
|
|
|
@ -217,7 +217,7 @@ set_indic_properties (hb_glyph_info_t &info)
|
|||
|
||||
/* According to ScriptExtensions.txt, these Grantha marks may also be used in Tamil,
|
||||
* so the Indic shaper needs to know their categories. */
|
||||
else if (unlikely (u == 0x11303u)) cat = OT_SM;
|
||||
else if (unlikely (u == 0x11301u || u == 0x11303u)) cat = OT_SM;
|
||||
else if (unlikely (u == 0x1133cu)) cat = OT_N;
|
||||
|
||||
else if (unlikely (u == 0x0AFBu)) cat = OT_N; /* https://github.com/behdad/harfbuzz/issues/552 */
|
||||
|
@ -508,7 +508,7 @@ struct indic_shape_plan_t
|
|||
|
||||
/* 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! */
|
||||
(const_cast<indic_shape_plan_t *> (this))->virama_glyph = glyph;
|
||||
virama_glyph = glyph;
|
||||
}
|
||||
|
||||
*pglyph = glyph;
|
||||
|
@ -518,7 +518,7 @@ struct indic_shape_plan_t
|
|||
const indic_config_t *config;
|
||||
|
||||
bool is_old_spec;
|
||||
hb_codepoint_t virama_glyph;
|
||||
mutable hb_codepoint_t virama_glyph;
|
||||
|
||||
would_substitute_feature_t rphf;
|
||||
would_substitute_feature_t pref;
|
||||
|
@ -692,7 +692,7 @@ initial_reordering_consonant_syllable (const hb_ot_shape_plan_t *plan,
|
|||
hb_glyph_info_t *info = buffer->info;
|
||||
|
||||
/* https://github.com/behdad/harfbuzz/issues/435#issuecomment-335560167
|
||||
* // For compatibility with legacy useage in Kannada,
|
||||
* // For compatibility with legacy usage in Kannada,
|
||||
* // Ra+h+ZWJ must behave like Ra+ZWJ+h...
|
||||
*/
|
||||
if (buffer->props.script == HB_SCRIPT_KANNADA &&
|
||||
|
@ -1686,11 +1686,15 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
|||
|
||||
|
||||
/* Apply 'init' to the Left Matra if it's a word start. */
|
||||
if (info[start].indic_position () == POS_PRE_M &&
|
||||
(!start ||
|
||||
!(FLAG_UNSAFE (_hb_glyph_info_get_general_category (&info[start - 1])) &
|
||||
FLAG_RANGE (HB_UNICODE_GENERAL_CATEGORY_FORMAT, HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK))))
|
||||
info[start].mask |= indic_plan->mask_array[INIT];
|
||||
if (info[start].indic_position () == POS_PRE_M)
|
||||
{
|
||||
if (!start ||
|
||||
!(FLAG_UNSAFE (_hb_glyph_info_get_general_category (&info[start - 1])) &
|
||||
FLAG_RANGE (HB_UNICODE_GENERAL_CATEGORY_FORMAT, HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))
|
||||
info[start].mask |= indic_plan->mask_array[INIT];
|
||||
else
|
||||
buffer->unsafe_to_break (start - 1, start + 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
@ -1843,7 +1847,6 @@ compose_indic (const hb_ot_shape_normalize_context_t *c,
|
|||
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_indic =
|
||||
{
|
||||
"indic",
|
||||
collect_features_indic,
|
||||
override_features_indic,
|
||||
data_create_indic,
|
||||
|
|
|
@ -512,7 +512,6 @@ final_reordering (const hb_ot_shape_plan_t *plan,
|
|||
* generic shaper, except that it zeros mark advances GDEF_LATE. */
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_old =
|
||||
{
|
||||
"default",
|
||||
nullptr, /* collect_features */
|
||||
nullptr, /* override_features */
|
||||
nullptr, /* data_create */
|
||||
|
@ -531,7 +530,6 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_old =
|
|||
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
|
||||
{
|
||||
"myanmar",
|
||||
collect_features_myanmar,
|
||||
override_features_myanmar,
|
||||
nullptr, /* data_create */
|
||||
|
|
|
@ -65,8 +65,6 @@ enum hb_ot_shape_zero_width_marks_type_t {
|
|||
|
||||
struct hb_ot_complex_shaper_t
|
||||
{
|
||||
char name[8];
|
||||
|
||||
/* collect_features()
|
||||
* Called during shape_plan().
|
||||
* Shapers should use plan->map to add their features and callbacks.
|
||||
|
|
|
@ -366,7 +366,6 @@ preprocess_text_thai (const hb_ot_shape_plan_t *plan,
|
|||
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_thai =
|
||||
{
|
||||
"thai",
|
||||
nullptr, /* collect_features */
|
||||
nullptr, /* override_features */
|
||||
nullptr, /* data_create */
|
||||
|
|
|
@ -46,7 +46,6 @@ collect_features_tibetan (hb_ot_shape_planner_t *plan)
|
|||
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_tibetan =
|
||||
{
|
||||
"default",
|
||||
collect_features_tibetan,
|
||||
nullptr, /* override_features */
|
||||
nullptr, /* data_create */
|
||||
|
|
|
@ -595,7 +595,6 @@ compose_use (const hb_ot_shape_normalize_context_t *c,
|
|||
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_use =
|
||||
{
|
||||
"use",
|
||||
collect_features_use,
|
||||
nullptr, /* override_features */
|
||||
data_create_use,
|
||||
|
|
|
@ -210,7 +210,7 @@ position_mark (const hb_ot_shape_plan_t *plan,
|
|||
pos.x_offset = pos.y_offset = 0;
|
||||
|
||||
|
||||
/* We dont position LEFT and RIGHT marks. */
|
||||
/* We don't position LEFT and RIGHT marks. */
|
||||
|
||||
/* X positioning */
|
||||
switch (combining_class)
|
||||
|
|
|
@ -99,7 +99,9 @@ struct hb_ot_shape_planner_t
|
|||
}
|
||||
|
||||
private:
|
||||
NO_COPY (hb_ot_shape_planner_t);
|
||||
/* No copy. */
|
||||
hb_ot_shape_planner_t (const hb_ot_shape_planner_t &);
|
||||
hb_ot_shape_planner_t &operator = (const hb_ot_shape_planner_t &);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -879,9 +879,11 @@ static const LangTagLong ot_languages_zh[] = {
|
|||
};
|
||||
|
||||
static int
|
||||
lang_compare_first_component (const char *a,
|
||||
const char *b)
|
||||
lang_compare_first_component (const void *pa,
|
||||
const void *pb)
|
||||
{
|
||||
const char *a = (const char *) pa;
|
||||
const char *b = (const char *) pb;
|
||||
unsigned int da, db;
|
||||
const char *p;
|
||||
|
||||
|
@ -923,7 +925,7 @@ hb_ot_tag_from_language (hb_language_t language)
|
|||
if (i) {
|
||||
for (; i < 4; i++)
|
||||
tag[i] = ' ';
|
||||
return HB_TAG_CHAR4 (tag);
|
||||
return HB_TAG (tag[0], tag[1], tag[2], tag[3]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -972,7 +974,7 @@ hb_ot_tag_from_language (hb_language_t language)
|
|||
const LangTag *lang_tag;
|
||||
lang_tag = (LangTag *) bsearch (lang_str, ot_languages,
|
||||
ARRAY_LENGTH (ot_languages), sizeof (LangTag),
|
||||
(hb_compare_func_t) lang_compare_first_component);
|
||||
lang_compare_first_component);
|
||||
if (lang_tag)
|
||||
return lang_tag->tag;
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ struct MVAR
|
|||
const VariationValueRecord *record;
|
||||
record = (VariationValueRecord *) bsearch (&tag, values,
|
||||
valueRecordCount, valueRecordSize,
|
||||
(hb_compare_func_t) tag_compare);
|
||||
tag_compare);
|
||||
if (!record)
|
||||
return 0.;
|
||||
|
||||
|
@ -85,8 +85,12 @@ struct MVAR
|
|||
}
|
||||
|
||||
protected:
|
||||
static inline int tag_compare (const hb_tag_t *a, const Tag *b)
|
||||
{ return b->cmp (*a); }
|
||||
static inline int tag_compare (const void *pa, const void *pb)
|
||||
{
|
||||
const hb_tag_t *a = (const hb_tag_t *) pa;
|
||||
const Tag *b = (const Tag *) pb;
|
||||
return b->cmp (*a);
|
||||
}
|
||||
|
||||
protected:
|
||||
FixedVersion<>version; /* Version of the metrics variation table
|
||||
|
|
|
@ -44,16 +44,14 @@
|
|||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
/* We only use these two for debug output. However, the debug code is
|
||||
* always seen by the compiler (and optimized out in non-debug builds.
|
||||
* If including these becomes a problem, we can start thinking about
|
||||
* someway around that. */
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
#define HB_PASTE1(a,b) a##b
|
||||
#define HB_PASTE(a,b) HB_PASTE1(a,b)
|
||||
|
||||
/* Compile-time custom allocator support. */
|
||||
|
||||
#if defined(hb_malloc_impl) \
|
||||
|
@ -76,36 +74,19 @@ extern "C" void hb_free_impl(void *ptr);
|
|||
|
||||
#if __cplusplus < 201103L
|
||||
|
||||
// Null pointer literal
|
||||
// Source: SC22/WG21/N2431 = J16/07-0301
|
||||
// http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2431.pdf
|
||||
|
||||
const // this is a const object...
|
||||
class {
|
||||
public:
|
||||
template<class T> // convertible to any type
|
||||
operator T*() const { // of null non-member
|
||||
return 0; // pointer...
|
||||
}
|
||||
template<class C, class T> // or any type of null
|
||||
operator T C::*() const { // member pointer...
|
||||
return 0;
|
||||
}
|
||||
private:
|
||||
void operator&() const; // whose address can't be taken
|
||||
} _hb_nullptr = {}; // and whose name is nullptr
|
||||
#define nullptr _hb_nullptr
|
||||
#ifndef nullptr
|
||||
#define nullptr NULL
|
||||
#endif
|
||||
|
||||
// Static assertions
|
||||
#ifndef static_assert
|
||||
#define _PASTE1(a,b) a##b
|
||||
#define _PASTE(a,b) _PASTE1(a,b)
|
||||
#define static_assert(e, msg) \
|
||||
HB_UNUSED typedef int _PASTE(static_assertion_failed_at_line_, __LINE__) [(e) ? 1 : -1]
|
||||
HB_UNUSED typedef int HB_PASTE(static_assertion_failed_at_line_, __LINE__) [(e) ? 1 : -1]
|
||||
#endif // static_assert
|
||||
|
||||
#endif // __cplusplus < 201103L
|
||||
|
||||
#define _GNU_SOURCE 1
|
||||
|
||||
#if (defined(__GNUC__) || defined(__clang__)) && defined(__OPTIMIZE__)
|
||||
#define likely(expr) (__builtin_expect (!!(expr), 1))
|
||||
|
@ -386,11 +367,6 @@ _hb_unsigned_int_mul_overflows (unsigned int count, unsigned int size)
|
|||
}
|
||||
|
||||
|
||||
/* Type of bsearch() / qsort() compare function */
|
||||
typedef int (*hb_compare_func_t) (const void *, const void *);
|
||||
|
||||
|
||||
|
||||
|
||||
/* arrays and maps */
|
||||
|
||||
|
@ -494,12 +470,12 @@ struct hb_prealloced_array_t
|
|||
|
||||
inline void qsort (void)
|
||||
{
|
||||
::qsort (array, len, sizeof (Type), (hb_compare_func_t) Type::cmp);
|
||||
::qsort (array, len, sizeof (Type), Type::cmp);
|
||||
}
|
||||
|
||||
inline void qsort (unsigned int start, unsigned int end)
|
||||
{
|
||||
::qsort (array + start, end - start, sizeof (Type), (hb_compare_func_t) Type::cmp);
|
||||
::qsort (array + start, end - start, sizeof (Type), Type::cmp);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -559,7 +535,7 @@ struct hb_auto_array_t : hb_prealloced_array_t <Type>
|
|||
template <typename item_t, typename lock_t>
|
||||
struct hb_lockable_set_t
|
||||
{
|
||||
hb_prealloced_array_t <item_t, 2> items;
|
||||
hb_prealloced_array_t <item_t, 1> items;
|
||||
|
||||
inline void init (void) { items.init (); }
|
||||
|
||||
|
@ -664,22 +640,6 @@ static inline unsigned char TOUPPER (unsigned char c)
|
|||
static inline unsigned char TOLOWER (unsigned char c)
|
||||
{ return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; }
|
||||
|
||||
#define HB_TAG_CHAR4(s) (HB_TAG(((const char *) s)[0], \
|
||||
((const char *) s)[1], \
|
||||
((const char *) s)[2], \
|
||||
((const char *) s)[3]))
|
||||
|
||||
|
||||
/* C++ helpers */
|
||||
|
||||
/* Makes class uncopyable. Use in private: section. */
|
||||
#define NO_COPY(T) \
|
||||
T (const T &o); \
|
||||
T &operator = (const T &o)
|
||||
|
||||
|
||||
/* Debug */
|
||||
|
||||
|
||||
/* HB_NDEBUG disables some sanity checks that are very safe to disable and
|
||||
* should be disabled in production systems. If NDEBUG is defined, enable
|
||||
|
@ -690,255 +650,6 @@ static inline unsigned char TOLOWER (unsigned char c)
|
|||
#define HB_NDEBUG
|
||||
#endif
|
||||
|
||||
#ifndef HB_DEBUG
|
||||
#define HB_DEBUG 0
|
||||
#endif
|
||||
|
||||
static inline bool
|
||||
_hb_debug (unsigned int level,
|
||||
unsigned int max_level)
|
||||
{
|
||||
return level < max_level;
|
||||
}
|
||||
|
||||
#define DEBUG_LEVEL_ENABLED(WHAT, LEVEL) (_hb_debug ((LEVEL), HB_DEBUG_##WHAT))
|
||||
#define DEBUG_ENABLED(WHAT) (DEBUG_LEVEL_ENABLED (WHAT, 0))
|
||||
|
||||
static inline void
|
||||
_hb_print_func (const char *func)
|
||||
{
|
||||
if (func)
|
||||
{
|
||||
unsigned int func_len = strlen (func);
|
||||
/* Skip "static" */
|
||||
if (0 == strncmp (func, "static ", 7))
|
||||
func += 7;
|
||||
/* Skip "typename" */
|
||||
if (0 == strncmp (func, "typename ", 9))
|
||||
func += 9;
|
||||
/* Skip return type */
|
||||
const char *space = strchr (func, ' ');
|
||||
if (space)
|
||||
func = space + 1;
|
||||
/* Skip parameter list */
|
||||
const char *paren = strchr (func, '(');
|
||||
if (paren)
|
||||
func_len = paren - func;
|
||||
fprintf (stderr, "%.*s", func_len, func);
|
||||
}
|
||||
}
|
||||
|
||||
template <int max_level> static inline void
|
||||
_hb_debug_msg_va (const char *what,
|
||||
const void *obj,
|
||||
const char *func,
|
||||
bool indented,
|
||||
unsigned int level,
|
||||
int level_dir,
|
||||
const char *message,
|
||||
va_list ap) HB_PRINTF_FUNC(7, 0);
|
||||
template <int max_level> static inline void
|
||||
_hb_debug_msg_va (const char *what,
|
||||
const void *obj,
|
||||
const char *func,
|
||||
bool indented,
|
||||
unsigned int level,
|
||||
int level_dir,
|
||||
const char *message,
|
||||
va_list ap)
|
||||
{
|
||||
if (!_hb_debug (level, max_level))
|
||||
return;
|
||||
|
||||
fprintf (stderr, "%-10s", what ? what : "");
|
||||
|
||||
if (obj)
|
||||
fprintf (stderr, "(%0*lx) ", (unsigned int) (2 * sizeof (void *)), (unsigned long) obj);
|
||||
else
|
||||
fprintf (stderr, " %*s ", (unsigned int) (2 * sizeof (void *)), "");
|
||||
|
||||
if (indented) {
|
||||
#define VBAR "\342\224\202" /* U+2502 BOX DRAWINGS LIGHT VERTICAL */
|
||||
#define VRBAR "\342\224\234" /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
|
||||
#define DLBAR "\342\225\256" /* U+256E BOX DRAWINGS LIGHT ARC DOWN AND LEFT */
|
||||
#define ULBAR "\342\225\257" /* U+256F BOX DRAWINGS LIGHT ARC UP AND LEFT */
|
||||
#define LBAR "\342\225\264" /* U+2574 BOX DRAWINGS LIGHT LEFT */
|
||||
static const char bars[] =
|
||||
VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR
|
||||
VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR
|
||||
VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR
|
||||
VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR
|
||||
VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR VBAR;
|
||||
fprintf (stderr, "%2u %s" VRBAR "%s",
|
||||
level,
|
||||
bars + sizeof (bars) - 1 - MIN ((unsigned int) sizeof (bars) - 1, (unsigned int) (sizeof (VBAR) - 1) * level),
|
||||
level_dir ? (level_dir > 0 ? DLBAR : ULBAR) : LBAR);
|
||||
} else
|
||||
fprintf (stderr, " " VRBAR LBAR);
|
||||
|
||||
_hb_print_func (func);
|
||||
|
||||
if (message)
|
||||
{
|
||||
fprintf (stderr, ": ");
|
||||
vfprintf (stderr, message, ap);
|
||||
}
|
||||
|
||||
fprintf (stderr, "\n");
|
||||
}
|
||||
template <> inline void
|
||||
_hb_debug_msg_va<0> (const char *what HB_UNUSED,
|
||||
const void *obj HB_UNUSED,
|
||||
const char *func HB_UNUSED,
|
||||
bool indented HB_UNUSED,
|
||||
unsigned int level HB_UNUSED,
|
||||
int level_dir HB_UNUSED,
|
||||
const char *message HB_UNUSED,
|
||||
va_list ap HB_UNUSED) {}
|
||||
|
||||
template <int max_level> static inline void
|
||||
_hb_debug_msg (const char *what,
|
||||
const void *obj,
|
||||
const char *func,
|
||||
bool indented,
|
||||
unsigned int level,
|
||||
int level_dir,
|
||||
const char *message,
|
||||
...) HB_PRINTF_FUNC(7, 8);
|
||||
template <int max_level> static inline void
|
||||
_hb_debug_msg (const char *what,
|
||||
const void *obj,
|
||||
const char *func,
|
||||
bool indented,
|
||||
unsigned int level,
|
||||
int level_dir,
|
||||
const char *message,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start (ap, message);
|
||||
_hb_debug_msg_va<max_level> (what, obj, func, indented, level, level_dir, message, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
template <> inline void
|
||||
_hb_debug_msg<0> (const char *what HB_UNUSED,
|
||||
const void *obj HB_UNUSED,
|
||||
const char *func HB_UNUSED,
|
||||
bool indented HB_UNUSED,
|
||||
unsigned int level HB_UNUSED,
|
||||
int level_dir HB_UNUSED,
|
||||
const char *message HB_UNUSED,
|
||||
...) HB_PRINTF_FUNC(7, 8);
|
||||
template <> inline void
|
||||
_hb_debug_msg<0> (const char *what HB_UNUSED,
|
||||
const void *obj HB_UNUSED,
|
||||
const char *func HB_UNUSED,
|
||||
bool indented HB_UNUSED,
|
||||
unsigned int level HB_UNUSED,
|
||||
int level_dir HB_UNUSED,
|
||||
const char *message HB_UNUSED,
|
||||
...) {}
|
||||
|
||||
#define DEBUG_MSG_LEVEL(WHAT, OBJ, LEVEL, LEVEL_DIR, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), nullptr, true, (LEVEL), (LEVEL_DIR), __VA_ARGS__)
|
||||
#define DEBUG_MSG(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), nullptr, false, 0, 0, __VA_ARGS__)
|
||||
#define DEBUG_MSG_FUNC(WHAT, OBJ, ...) _hb_debug_msg<HB_DEBUG_##WHAT> (#WHAT, (OBJ), HB_FUNC, false, 0, 0, __VA_ARGS__)
|
||||
|
||||
|
||||
/*
|
||||
* Printer
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
struct hb_printer_t {
|
||||
const char *print (const T&) { return "something"; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hb_printer_t<bool> {
|
||||
const char *print (bool v) { return v ? "true" : "false"; }
|
||||
};
|
||||
|
||||
template <>
|
||||
struct hb_printer_t<hb_void_t> {
|
||||
const char *print (hb_void_t) { return ""; }
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Trace
|
||||
*/
|
||||
|
||||
template <typename T>
|
||||
static inline void _hb_warn_no_return (bool returned)
|
||||
{
|
||||
if (unlikely (!returned)) {
|
||||
fprintf (stderr, "OUCH, returned with no call to return_trace(). This is a bug, please report.\n");
|
||||
}
|
||||
}
|
||||
template <>
|
||||
/*static*/ inline void _hb_warn_no_return<hb_void_t> (bool returned HB_UNUSED)
|
||||
{}
|
||||
|
||||
template <int max_level, typename ret_t>
|
||||
struct hb_auto_trace_t {
|
||||
explicit inline hb_auto_trace_t (unsigned int *plevel_,
|
||||
const char *what_,
|
||||
const void *obj_,
|
||||
const char *func,
|
||||
const char *message,
|
||||
...) : plevel (plevel_), what (what_), obj (obj_), returned (false)
|
||||
{
|
||||
if (plevel) ++*plevel;
|
||||
|
||||
va_list ap;
|
||||
va_start (ap, message);
|
||||
_hb_debug_msg_va<max_level> (what, obj, func, true, plevel ? *plevel : 0, +1, message, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
inline ~hb_auto_trace_t (void)
|
||||
{
|
||||
_hb_warn_no_return<ret_t> (returned);
|
||||
if (!returned) {
|
||||
_hb_debug_msg<max_level> (what, obj, nullptr, true, plevel ? *plevel : 1, -1, " ");
|
||||
}
|
||||
if (plevel) --*plevel;
|
||||
}
|
||||
|
||||
inline ret_t ret (ret_t v, unsigned int line = 0)
|
||||
{
|
||||
if (unlikely (returned)) {
|
||||
fprintf (stderr, "OUCH, double calls to return_trace(). This is a bug, please report.\n");
|
||||
return v;
|
||||
}
|
||||
|
||||
_hb_debug_msg<max_level> (what, obj, nullptr, true, plevel ? *plevel : 1, -1,
|
||||
"return %s (line %d)",
|
||||
hb_printer_t<ret_t>().print (v), line);
|
||||
if (plevel) --*plevel;
|
||||
plevel = nullptr;
|
||||
returned = true;
|
||||
return v;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int *plevel;
|
||||
const char *what;
|
||||
const void *obj;
|
||||
bool returned;
|
||||
};
|
||||
template <typename ret_t> /* Optimize when tracing is disabled */
|
||||
struct hb_auto_trace_t<0, ret_t> {
|
||||
explicit inline hb_auto_trace_t (unsigned int *plevel_ HB_UNUSED,
|
||||
const char *what HB_UNUSED,
|
||||
const void *obj HB_UNUSED,
|
||||
const char *func HB_UNUSED,
|
||||
const char *message HB_UNUSED,
|
||||
...) {}
|
||||
|
||||
inline ret_t ret (ret_t v, unsigned int line HB_UNUSED = 0) { return v; }
|
||||
};
|
||||
|
||||
#define return_trace(RET) return trace.ret (RET, __LINE__)
|
||||
|
||||
/* Misc */
|
||||
|
||||
|
@ -1156,4 +867,31 @@ hb_options (void)
|
|||
/* Size signifying variable-sized array */
|
||||
#define VAR 1
|
||||
|
||||
|
||||
/* String type. */
|
||||
|
||||
struct hb_string_t
|
||||
{
|
||||
inline hb_string_t (void) : bytes (nullptr), len (0) {}
|
||||
inline hb_string_t (const char *bytes_, unsigned int len_) : bytes (bytes_), len (len_) {}
|
||||
|
||||
inline int cmp (const hb_string_t &a) const
|
||||
{
|
||||
if (len != a.len)
|
||||
return (int) a.len - (int) len;
|
||||
|
||||
return memcmp (a.bytes, bytes, len);
|
||||
}
|
||||
static inline int cmp (const void *pa, const void *pb)
|
||||
{
|
||||
hb_string_t *a = (hb_string_t *) pa;
|
||||
hb_string_t *b = (hb_string_t *) pb;
|
||||
return b->cmp (*a);
|
||||
}
|
||||
|
||||
const char *bytes;
|
||||
unsigned int len;
|
||||
};
|
||||
|
||||
|
||||
#endif /* HB_PRIVATE_HH */
|
||||
|
|
|
@ -24,17 +24,14 @@
|
|||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-private.hh"
|
||||
#include "hb-debug.hh"
|
||||
#include "hb-shape-plan-private.hh"
|
||||
#include "hb-shaper-private.hh"
|
||||
#include "hb-font-private.hh"
|
||||
#include "hb-buffer-private.hh"
|
||||
|
||||
|
||||
#ifndef HB_DEBUG_SHAPE_PLAN
|
||||
#define HB_DEBUG_SHAPE_PLAN (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
hb_shape_plan_plan (hb_shape_plan_t *shape_plan,
|
||||
const hb_feature_t *user_features,
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* 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_STRING_ARRAY_HH
|
||||
#if 0 /* Make checks happy. */
|
||||
#define HB_STRING_ARRAY_HH
|
||||
#endif
|
||||
|
||||
#include "hb-private.hh"
|
||||
|
||||
/* Based on Bruno Haible's code in Appendix B of Ulrich Drepper's dsohowto.pdf:
|
||||
* https://software.intel.com/sites/default/files/m/a/1/e/dsohowto.pdf */
|
||||
|
||||
#define HB_STRING_ARRAY_TYPE_NAME HB_PASTE(HB_STRING_ARRAY_NAME, _msgstr_t)
|
||||
#define HB_STRING_ARRAY_POOL_NAME HB_PASTE(HB_STRING_ARRAY_NAME, _msgstr)
|
||||
#define HB_STRING_ARRAY_OFFS_NAME HB_PASTE(HB_STRING_ARRAY_NAME, _msgidx)
|
||||
|
||||
static const union HB_STRING_ARRAY_TYPE_NAME {
|
||||
struct {
|
||||
/* I like to avoid storing the nul-termination byte since we don't need it,
|
||||
* but C++ does not allow that.
|
||||
* https://stackoverflow.com/questions/28433862/why-initializer-string-for-array-of-chars-is-too-long-compiles-fine-in-c-not
|
||||
*/
|
||||
#define _S(s) char HB_PASTE (str, __LINE__)[sizeof (s)];
|
||||
#include HB_STRING_ARRAY_LIST
|
||||
#undef _S
|
||||
} st;
|
||||
char str[0];
|
||||
}
|
||||
HB_STRING_ARRAY_POOL_NAME =
|
||||
{
|
||||
{
|
||||
#define _S(s) s,
|
||||
#include HB_STRING_ARRAY_LIST
|
||||
#undef _S
|
||||
}
|
||||
};
|
||||
static const unsigned int HB_STRING_ARRAY_OFFS_NAME[] =
|
||||
{
|
||||
#define _S(s) offsetof (union HB_STRING_ARRAY_TYPE_NAME, st.HB_PASTE(str, __LINE__)),
|
||||
#include HB_STRING_ARRAY_LIST
|
||||
#undef _S
|
||||
sizeof (HB_STRING_ARRAY_TYPE_NAME)
|
||||
};
|
||||
|
||||
static inline hb_string_t
|
||||
HB_STRING_ARRAY_NAME (unsigned int i)
|
||||
{
|
||||
assert (i < ARRAY_LENGTH (HB_STRING_ARRAY_OFFS_NAME) - 1);
|
||||
return hb_string_t (HB_STRING_ARRAY_POOL_NAME.str + HB_STRING_ARRAY_OFFS_NAME[i],
|
||||
HB_STRING_ARRAY_OFFS_NAME[i + 1] - HB_STRING_ARRAY_OFFS_NAME[i] - 1);
|
||||
}
|
||||
|
||||
#undef HB_STRING_ARRAY_TYPE_NAME
|
||||
#undef HB_STRING_ARRAY_POOL_NAME
|
||||
#undef HB_STRING_ARRAY_OFFS_NAME
|
||||
|
||||
#endif /* HB_STRING_ARRAY_HH */
|
|
@ -231,22 +231,43 @@ hb_ucdn_decompose_compatibility(hb_unicode_funcs_t *ufuncs HB_UNUSED,
|
|||
return ucdn_compat_decompose(u, decomposed);
|
||||
}
|
||||
|
||||
static hb_unicode_funcs_t *static_ucdn_funcs = nullptr;
|
||||
|
||||
#ifdef HB_USE_ATEXIT
|
||||
static
|
||||
void free_static_ucdn_funcs (void)
|
||||
{
|
||||
hb_unicode_funcs_destroy (static_ucdn_funcs);
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C" HB_INTERNAL
|
||||
hb_unicode_funcs_t *
|
||||
hb_ucdn_get_unicode_funcs (void)
|
||||
{
|
||||
static const hb_unicode_funcs_t _hb_ucdn_unicode_funcs = {
|
||||
HB_OBJECT_HEADER_STATIC,
|
||||
retry:
|
||||
hb_unicode_funcs_t *funcs = (hb_unicode_funcs_t *) hb_atomic_ptr_get (&static_ucdn_funcs);
|
||||
|
||||
nullptr, /* parent */
|
||||
true, /* immutable */
|
||||
{
|
||||
#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_ucdn_##name,
|
||||
if (unlikely (!funcs))
|
||||
{
|
||||
funcs = hb_unicode_funcs_create (nullptr);
|
||||
|
||||
#define HB_UNICODE_FUNC_IMPLEMENT(name) \
|
||||
hb_unicode_funcs_set_##name##_func (funcs, hb_ucdn_##name, nullptr, nullptr);
|
||||
HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
|
||||
#undef HB_UNICODE_FUNC_IMPLEMENT
|
||||
|
||||
hb_unicode_funcs_make_immutable (funcs);
|
||||
|
||||
if (!hb_atomic_ptr_cmpexch (&static_ucdn_funcs, nullptr, funcs)) {
|
||||
hb_unicode_funcs_destroy (funcs);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
#ifdef HB_USE_ATEXIT
|
||||
atexit (free_static_ucdn_funcs); /* First person registers atexit() callback. */
|
||||
#endif
|
||||
};
|
||||
|
||||
return const_cast<hb_unicode_funcs_t *> (&_hb_ucdn_unicode_funcs);
|
||||
return hb_unicode_funcs_reference (funcs);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#include "hb-private.hh"
|
||||
#include "hb-debug.hh"
|
||||
#define HB_SHAPER uniscribe
|
||||
#include "hb-shaper-impl-private.hh"
|
||||
|
||||
|
@ -38,11 +40,6 @@
|
|||
#include "hb-ot-tag.h"
|
||||
|
||||
|
||||
#ifndef HB_DEBUG_UNISCRIBE
|
||||
#define HB_DEBUG_UNISCRIBE (HB_DEBUG+0)
|
||||
#endif
|
||||
|
||||
|
||||
static inline uint16_t hb_uint16_swap (const uint16_t v)
|
||||
{ return (v >> 8) | (v << 8); }
|
||||
static inline uint32_t hb_uint32_swap (const uint32_t v)
|
||||
|
@ -264,7 +261,9 @@ struct active_feature_t {
|
|||
OPENTYPE_FEATURE_RECORD rec;
|
||||
unsigned int order;
|
||||
|
||||
static int cmp (const active_feature_t *a, const active_feature_t *b) {
|
||||
static int cmp (const void *pa, const void *pb) {
|
||||
const active_feature_t *a = (const active_feature_t *) pa;
|
||||
const active_feature_t *b = (const active_feature_t *) pb;
|
||||
return a->rec.tagFeature < b->rec.tagFeature ? -1 : a->rec.tagFeature > b->rec.tagFeature ? 1 :
|
||||
a->order < b->order ? -1 : a->order > b->order ? 1 :
|
||||
a->rec.lParameter < b->rec.lParameter ? -1 : a->rec.lParameter > b->rec.lParameter ? 1 :
|
||||
|
@ -280,7 +279,9 @@ struct feature_event_t {
|
|||
bool start;
|
||||
active_feature_t feature;
|
||||
|
||||
static int cmp (const feature_event_t *a, const feature_event_t *b) {
|
||||
static int cmp (const void *pa, const void *pb) {
|
||||
const feature_event_t *a = (const feature_event_t *) pa;
|
||||
const feature_event_t *b = (const feature_event_t *) pb;
|
||||
return a->index < b->index ? -1 : a->index > b->index ? 1 :
|
||||
a->start < b->start ? -1 : a->start > b->start ? 1 :
|
||||
active_feature_t::cmp (&a->feature, &b->feature);
|
||||
|
@ -495,7 +496,7 @@ populate_log_font (LOGFONTW *lf,
|
|||
unsigned int font_size)
|
||||
{
|
||||
memset (lf, 0, sizeof (*lf));
|
||||
lf->lfHeight = -font_size;
|
||||
lf->lfHeight = - (int) font_size;
|
||||
lf->lfCharSet = DEFAULT_CHARSET;
|
||||
|
||||
hb_face_t *face = font->face;
|
||||
|
@ -854,7 +855,7 @@ retry:
|
|||
unsigned int glyphs_offset = 0;
|
||||
unsigned int glyphs_len;
|
||||
bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
|
||||
for (unsigned int i = 0; i < item_count; i++)
|
||||
for (int i = 0; i < item_count; i++)
|
||||
{
|
||||
unsigned int chars_offset = items[i].iCharPos;
|
||||
unsigned int item_chars_len = items[i + 1].iCharPos - chars_offset;
|
||||
|
@ -1031,6 +1032,8 @@ retry:
|
|||
if (backward)
|
||||
hb_buffer_reverse (buffer);
|
||||
|
||||
buffer->unsafe_to_break_all ();
|
||||
|
||||
/* Wow, done! */
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -37,10 +37,10 @@ HB_BEGIN_DECLS
|
|||
|
||||
|
||||
#define HB_VERSION_MAJOR 1
|
||||
#define HB_VERSION_MINOR 6
|
||||
#define HB_VERSION_MICRO 3
|
||||
#define HB_VERSION_MINOR 7
|
||||
#define HB_VERSION_MICRO 1
|
||||
|
||||
#define HB_VERSION_STRING "1.6.3"
|
||||
#define HB_VERSION_STRING "1.7.1"
|
||||
|
||||
#define HB_VERSION_ATLEAST(major,minor,micro) \
|
||||
((major)*10000+(minor)*100+(micro) <= \
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
using namespace OT;
|
||||
|
||||
const void * const OT::_hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
|
|
|
@ -24,11 +24,10 @@
|
|||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb.h"
|
||||
#include "hb-ot.h"
|
||||
#ifdef HAVE_FREETYPE
|
||||
#include "hb-ft.h"
|
||||
#endif
|
||||
|
@ -92,8 +91,9 @@ main (int argc, char **argv)
|
|||
hb_font_t *font = hb_font_create (face);
|
||||
hb_face_destroy (face);
|
||||
hb_font_set_scale (font, upem, upem);
|
||||
hb_ot_font_set_funcs (font);
|
||||
#ifdef HAVE_FREETYPE
|
||||
hb_ft_font_set_funcs (font);
|
||||
//hb_ft_font_set_funcs (font);
|
||||
#endif
|
||||
|
||||
hb_buffer_t *buf;
|
||||
|
|
|
@ -24,9 +24,7 @@
|
|||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb.h"
|
||||
#include "hb-ot.h"
|
||||
|
|
|
@ -24,9 +24,7 @@
|
|||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb.h"
|
||||
#include "hb-ot.h"
|
||||
|
|
|
@ -24,9 +24,7 @@
|
|||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include "hb-private.hh"
|
||||
|
||||
#include "hb.h"
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче