Bug 1560439 - Update HarfBuzz to 2.5.3. r=jfkthame

Differential Revision: https://phabricator.services.mozilla.com/D36282

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Ryan VanderMeulen 2019-06-29 17:29:36 +00:00
parent 6a9aec8195
commit 1a0a648052
97 changed files with 4146 additions and 2188 deletions

View File

@ -13,6 +13,7 @@ EXTRA_DIST = \
README.mingw.md \
README.python.md \
BUILD.md \
CONFIG.md \
RELEASING.md \
TESTING.md \
CMakeLists.txt \

View File

@ -1,3 +1,22 @@
Overview of changes leading to 2.5.3
Wednesday, June 26, 2019
====================================
- Fix UCD script data for Unicode 10+ scripts. This was broken since 2.5.0.
- More optimizations for HB_TINY.
Overview of changes leading to 2.5.2
Thursday, June 20, 2019
====================================
- More hb-config.hh facilities to shrink library size, namely when built as
HB_TINY.
- New documentation of custom configurations in CONFIG.md.
- Fix build on gcc 4.8. That's supported again.
- Universal Shaping Engine improvements thanks to David Corbett.
- API Changes: Undeprecate some horizontal-kerning API and re-enable in hb-ft,
such that Type1 fonts will continue kerning.
Overview of changes leading to 2.5.1
Friday, May 31, 2019
====================================

View File

@ -1,7 +1,7 @@
This directory contains the HarfBuzz source from the upstream repo:
https://github.com/harfbuzz/harfbuzz
Current version: 2.5.1 [commit 93c455567fe3d92a7efe65bf0e9ac2af794e2c4f]
Current version: 2.5.3 [commit b14e413fae8f14b75c5956e9b38e413c878ded0c]
UPDATING:

View File

@ -17,6 +17,8 @@ For license information, see [COPYING](COPYING).
For build information, see [BUILD.md](BUILD.md).
For custom configurations, see [CONFIG.md](CONFIG.md).
For test execution, see [TESTING.md](TESTING.md).
Documentation: https://harfbuzz.github.io

View File

@ -1,6 +1,6 @@
AC_PREREQ([2.64])
AC_INIT([HarfBuzz],
[2.5.1],
[2.5.3],
[https://github.com/harfbuzz/harfbuzz/issues/new],
[harfbuzz],
[http://harfbuzz.org/])
@ -77,13 +77,7 @@ GTK_DOC_CHECK([1.15],[--flavour no-tmpl])
])
# Functions and headers
AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l posix_memalign)
save_libs="$LIBS"
LIBS="$LIBS -lm"
AC_CHECK_FUNCS([round], ,[AC_CHECK_DECLS([round], , ,[#include <math.h>])])
LIBS="$save_libs"
AC_CHECK_FUNCS(atexit mprotect sysconf getpagesize mmap isatty newlocale strtod_l)
AC_CHECK_HEADERS(unistd.h sys/mman.h xlocale.h stdbool.h)
# Compiler flags
@ -142,14 +136,6 @@ AM_CONDITIONAL(HAVE_PTHREAD, $have_pthread)
dnl ==========================================================================
have_fallback=true
if $have_fallback; then
AC_DEFINE(HAVE_FALLBACK, 1, [Have simple TrueType Layout backend])
fi
AM_CONDITIONAL(HAVE_FALLBACK, $have_fallback)
dnl ===========================================================================
AC_ARG_WITH(glib,
[AS_HELP_STRING([--with-glib=@<:@yes/no/auto@:>@],
[Use glib @<:@default=auto@:>@])],,

View File

@ -28,10 +28,6 @@ HBSOURCES = $(HB_BASE_sources)
HBSOURCES += $(HB_BASE_RAGEL_GENERATED_sources)
HBHEADERS = $(HB_BASE_headers)
if HAVE_FALLBACK
HBSOURCES += $(HB_FALLBACK_sources)
endif
if HAVE_PTHREAD
HBCFLAGS += $(PTHREAD_CFLAGS)
HBNONPCLIBS += $(PTHREAD_LIBS)
@ -428,6 +424,7 @@ HarfBuzz_0_0_gir_CFLAGS = \
-DHB_AAT_H_IN \
-DHB_GOBJECT_H \
-DHB_GOBJECT_H_IN \
-DHAVE_GOBJECT \
-DHB_EXTERN= \
$(NULL)
HarfBuzz_0_0_gir_LIBS = \

View File

@ -36,6 +36,7 @@ HB_BASE_sources = \
hb-dispatch.hh \
hb-face.cc \
hb-face.hh \
hb-fallback-shape.cc \
hb-font.cc \
hb-font.hh \
hb-iter.hh \
@ -43,6 +44,7 @@ HB_BASE_sources = \
hb-machinery.hh \
hb-map.cc \
hb-map.hh \
hb-bimap.hh \
hb-meta.hh \
hb-mutex.hh \
hb-null.hh \
@ -63,6 +65,7 @@ HB_BASE_sources = \
hb-ot-color.cc \
hb-ot-face.cc \
hb-ot-face.hh \
hb-ot-face-table-list.hh \
hb-ot-font.cc \
hb-ot-gasp-table.hh \
hb-ot-glyf-table.hh \
@ -200,10 +203,6 @@ HB_BASE_headers = \
hb.h \
$(NULL)
HB_FALLBACK_sources = \
hb-fallback-shape.cc \
$(NULL)
# Optional Sources and Headers with external deps
HB_FT_sources = hb-ft.cc

View File

@ -3,19 +3,22 @@
from __future__ import print_function, division, absolute_import
import io, os.path, sys, re
import logging
logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
if len (sys.argv) != 2:
print("usage: ./gen-ucd-table ucd.nonunihan.grouped.xml", file=sys.stderr)
print("usage: ./gen-ucd-table ucd.nounihan.grouped.xml", file=sys.stderr)
sys.exit(1)
# https://github.com/harfbuzz/packtab
import packTab
import packTab.ucdxml
logging.info('Loading UCDXML...')
ucdxml = packTab.ucdxml.load_ucdxml(sys.argv[1])
ucd = packTab.ucdxml.ucdxml_get_repertoire(ucdxml)
logging.info('Preparing data tables...')
gc = [u['gc'] for u in ucd]
ccc = [int(u['ccc']) for u in ucd]
@ -31,93 +34,129 @@ ce = {i for i,u in enumerate(ucd) if u['Comp_Ex'] == 'Y'}
assert not any(v for v in dm.values() if len(v) not in (1,2))
dm1 = sorted(set(v for v in dm.values() if len(v) == 1))
dm1_array = ['0x%04Xu' % v for v in dm1]
assert all((v[0] >> 16) in (0,2) for v in dm1)
dm1_p0_array = ['0x%04Xu' % (v[0] & 0xFFFF) for v in dm1 if (v[0] >> 16) == 0]
dm1_p2_array = ['0x%04Xu' % (v[0] & 0xFFFF) for v in dm1 if (v[0] >> 16) == 2]
dm1_order = {v:i+1 for i,v in enumerate(dm1)}
dm2 = sorted((v, i) for i,v in dm.items() if len(v) == 2)
dm2 = [("HB_CODEPOINT_ENCODE3 (0x%04Xu, 0x%04Xu, 0x%04Xu)" %
(v+(i if i not in ce and not ccc[i] else 0,)), v)
for v,i in dm2]
dm2_array = [s for s,v in dm2]
l = 1 + len(dm1_array)
dm2 = sorted((v+(i if i not in ce and not ccc[i] else 0,), v)
for i,v in dm.items() if len(v) == 2)
filt = lambda v: ((v[0] & 0xFFFFF800) == 0x0000 and
(v[1] & 0xFFFFFF80) == 0x0300 and
(v[2] & 0xFFF0C000) == 0x0000)
dm2_u32_array = [v for v in dm2 if filt(v[0])]
dm2_u64_array = [v for v in dm2 if not filt(v[0])]
assert dm2_u32_array + dm2_u64_array == dm2
dm2_u32_array = ["HB_CODEPOINT_ENCODE3_11_7_14 (0x%04Xu, 0x%04Xu, 0x%04Xu)" % v[0] for v in dm2_u32_array]
dm2_u64_array = ["HB_CODEPOINT_ENCODE3 (0x%04Xu, 0x%04Xu, 0x%04Xu)" % v[0] for v in dm2_u64_array]
l = 1 + len(dm1_p0_array) + len(dm1_p2_array)
dm2_order = {v[1]:i+l for i,v in enumerate(dm2)}
dm_order = {None: 0}
dm_order.update(dm1_order)
dm_order.update(dm2_order)
gc_order = packTab.AutoMapping()
for _ in ('Cc', 'Cf', 'Cn', 'Co', 'Cs', 'Ll', 'Lm', 'Lo', 'Lt', 'Lu',
'Mc', 'Me', 'Mn', 'Nd', 'Nl', 'No', 'Pc', 'Pd', 'Pe', 'Pf',
'Pi', 'Po', 'Ps', 'Sc', 'Sk', 'Sm', 'So', 'Zl', 'Zp', 'Zs',):
gc_order[_]
gc_order = dict()
for i,v in enumerate(('Cc', 'Cf', 'Cn', 'Co', 'Cs', 'Ll', 'Lm', 'Lo', 'Lt', 'Lu',
'Mc', 'Me', 'Mn', 'Nd', 'Nl', 'No', 'Pc', 'Pd', 'Pe', 'Pf',
'Pi', 'Po', 'Ps', 'Sc', 'Sk', 'Sm', 'So', 'Zl', 'Zp', 'Zs',)):
gc_order[i] = v
gc_order[v] = i
sc_order = packTab.AutoMapping()
sc_order = dict()
sc_array = []
sc_re = re.compile(" (HB_SCRIPT_[_A-Z]*).*HB_TAG [(]'(.)','(.)','(.)','(.)'[)]")
sc_re = re.compile(r"\b(HB_SCRIPT_[_A-Z]*).*HB_TAG [(]'(.)','(.)','(.)','(.)'[)]")
for line in open('hb-common.h'):
m = sc_re.search (line)
if not m: continue
name = m.group(1)
tag = ''.join(m.group(i) for i in range(2, 6))
i = sc_order[tag]
assert i == len(sc_array)
i = len(sc_array)
sc_order[tag] = i
sc_order[i] = tag
sc_array.append(name)
# TODO Currently if gc_order or sc_order do not capture all values, we get in
# trouble because they silently add new values. We should be able to "freeze"
# them, or just do the mapping ourselves.
DEFAULT = 1
COMPACT = 3
SLOPPY = 5
logging.info('Generating output...')
print("/* == Start of generated table == */")
print("/*")
print(" * The following table is generated by running:")
print(" *")
print(" * ./gen-ucd-table.py ucd.nonunihan.grouped.xml")
print(" * ./gen-ucd-table.py ucd.nounihan.grouped.xml")
print(" *")
print(" * on file with this description:", ucdxml.description)
print(" */")
print()
print("#ifndef HB_UCD_TABLE_HH")
print("#define HB_UCD_TABLE_HH")
print()
print()
print('#include "hb.hh"')
print()
code = packTab.Code('_hb_ucd')
sc_array, _ = code.addArray('hb_script_t', 'sc_map', sc_array)
dm1_array, _ = code.addArray('hb_codepoint_t', 'dm1_map', dm1_array)
dm2_array, _ = code.addArray('uint64_t', 'dm2_map', dm2_array)
dm1_p0_array, _ = code.addArray('uint16_t', 'dm1_p0_map', dm1_p0_array)
dm1_p2_array, _ = code.addArray('uint16_t', 'dm1_p2_map', dm1_p2_array)
dm2_u32_array, _ = code.addArray('uint32_t', 'dm2_u32_map', dm2_u32_array)
dm2_u64_array, _ = code.addArray('uint64_t', 'dm2_u64_map', dm2_u64_array)
code.print_c(linkage='static inline')
for compression in (DEFAULT, COMPACT):
datasets = [
('gc', gc, 'Cn', gc_order),
('ccc', ccc, 0, None),
('bmg', bmg, 0, None),
('sc', sc, 'Zzzz', sc_order),
('dm', dm, None, dm_order),
]
for compression in (DEFAULT, COMPACT, SLOPPY):
logging.info(' Compression=%d:' % compression)
print()
if compression == DEFAULT:
print('#ifndef HB_OPTIMIZE_SIZE')
elif compression == COMPACT:
print('#elif !defined(HB_NO_UCD_UNASSIGNED)')
else:
print('#else')
print()
if compression == SLOPPY:
for i in range(len(gc)):
if (i % 128) and gc[i] == 'Cn':
gc[i] = gc[i - 1]
for i in range(len(gc) - 2, -1, -1):
if ((i + 1) % 128) and gc[i] == 'Cn':
gc[i] = gc[i + 1]
for i in range(len(sc)):
if (i % 128) and sc[i] == 'Zzzz':
sc[i] = sc[i - 1]
for i in range(len(sc) - 2, -1, -1):
if ((i + 1) % 128) and sc[i] == 'Zzzz':
sc[i] = sc[i + 1]
code = packTab.Code('_hb_ucd')
packTab.pack_table(gc, 'Cn', mapping=gc_order, compression=compression).genCode(code, 'gc')
packTab.pack_table(ccc, 0, compression=compression).genCode(code, 'ccc')
packTab.pack_table(bmg, 0, compression=compression).genCode(code, 'bmg')
packTab.pack_table(sc, 'Zzzz', mapping=sc_order, compression=compression).genCode(code, 'sc')
packTab.pack_table(dm, None, mapping=dm_order, compression=compression).genCode(code, 'dm')
for name,data,default,mapping in datasets:
sol = packTab.pack_table(data, default, mapping=mapping, compression=compression)
logging.info(' Dataset=%-8s FullCost=%d' % (name, sol.fullCost))
sol.genCode(code, name)
code.print_c(linkage='static inline')
if compression != DEFAULT:
print()
print('#endif')
print()
print('#endif')
print()
print()
print("#endif /* HB_UCD_TABLE_HH */")
print()
print("/* == End of generated table == */")
logging.info('Done.')

View File

@ -25,9 +25,8 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb-open-type.hh"
#include "hb.hh"
#include "hb-ot-face.hh"
#include "hb-aat-layout.hh"
#include "hb-aat-fdsc-table.hh" // Just so we compile it; unused otherwise.
#include "hb-aat-layout-ankr-table.hh"
@ -40,6 +39,45 @@
#include "hb-aat-ltag-table.hh"
/*
* hb_aat_apply_context_t
*/
/* Note: This context is used for kerning, even without AAT, hence the condition. */
#if !defined(HB_NO_AAT) || !defined(HB_NO_OT_KERN)
AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_,
hb_font_t *font_,
hb_buffer_t *buffer_,
hb_blob_t *blob) :
plan (plan_),
font (font_),
face (font->face),
buffer (buffer_),
sanitizer (),
ankr_table (&Null(AAT::ankr)),
lookup_index (0),
debug_depth (0)
{
sanitizer.init (blob);
sanitizer.set_num_glyphs (face->get_num_glyphs ());
sanitizer.start_processing ();
sanitizer.set_max_ops (HB_SANITIZE_MAX_OPS_MAX);
}
AAT::hb_aat_apply_context_t::~hb_aat_apply_context_t ()
{ sanitizer.end_processing (); }
void
AAT::hb_aat_apply_context_t::set_ankr_table (const AAT::ankr *ankr_table_)
{ ankr_table = ankr_table_; }
#endif
#ifndef HB_NO_AAT
/**
* SECTION:hb-aat-layout
* @title: hb-aat-layout
@ -135,51 +173,14 @@ static const hb_aat_feature_mapping_t feature_mappings[] =
const hb_aat_feature_mapping_t *
hb_aat_layout_find_feature_mapping (hb_tag_t tag)
{
#ifdef HB_NO_SHAPE_AAT
return nullptr;
#endif
return (const hb_aat_feature_mapping_t *) bsearch (&tag,
feature_mappings,
ARRAY_LENGTH (feature_mappings),
sizeof (feature_mappings[0]),
hb_aat_feature_mapping_t::cmp);
return (const hb_aat_feature_mapping_t *) hb_bsearch (&tag,
feature_mappings,
ARRAY_LENGTH (feature_mappings),
sizeof (feature_mappings[0]),
hb_aat_feature_mapping_t::cmp);
}
/*
* hb_aat_apply_context_t
*/
/* Note: This context is used for kerning, even without AAT. */
AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_,
hb_font_t *font_,
hb_buffer_t *buffer_,
hb_blob_t *blob) :
plan (plan_),
font (font_),
face (font->face),
buffer (buffer_),
sanitizer (),
ankr_table (&Null(AAT::ankr)),
lookup_index (0),
debug_depth (0)
{
sanitizer.init (blob);
sanitizer.set_num_glyphs (face->get_num_glyphs ());
sanitizer.start_processing ();
sanitizer.set_max_ops (HB_SANITIZE_MAX_OPS_MAX);
}
AAT::hb_aat_apply_context_t::~hb_aat_apply_context_t ()
{ sanitizer.end_processing (); }
void
AAT::hb_aat_apply_context_t::set_ankr_table (const AAT::ankr *ankr_table_)
{ ankr_table = ankr_table_; }
/*
* mort/morx/kerx/trak
*/
@ -189,10 +190,6 @@ void
hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper,
hb_aat_map_t *map)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
const AAT::morx& morx = *mapper->face->table.morx;
if (morx.has_data ())
{
@ -219,10 +216,6 @@ hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper,
hb_bool_t
hb_aat_layout_has_substitution (hb_face_t *face)
{
#ifdef HB_NO_SHAPE_AAT
return false;
#endif
return face->table.morx->has_data () ||
face->table.mort->has_data ();
}
@ -232,10 +225,6 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
hb_blob_t *morx_blob = font->face->table.morx.get_blob ();
const AAT::morx& morx = *morx_blob->as<AAT::morx> ();
if (morx.has_data ())
@ -258,10 +247,6 @@ hb_aat_layout_substitute (const hb_ot_shape_plan_t *plan,
void
hb_aat_layout_zero_width_deleted_glyphs (hb_buffer_t *buffer)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
unsigned int count = buffer->len;
hb_glyph_info_t *info = buffer->info;
hb_glyph_position_t *pos = buffer->pos;
@ -279,10 +264,6 @@ is_deleted_glyph (const hb_glyph_info_t *info)
void
hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
hb_ot_layout_delete_glyphs_inplace (buffer, is_deleted_glyph);
}
@ -296,10 +277,6 @@ hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer)
hb_bool_t
hb_aat_layout_has_positioning (hb_face_t *face)
{
#ifdef HB_NO_SHAPE_AAT
return false;
#endif
return face->table.kerx->has_data ();
}
@ -308,10 +285,6 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
hb_blob_t *kerx_blob = font->face->table.kerx.get_blob ();
const AAT::kerx& kerx = *kerx_blob->as<AAT::kerx> ();
@ -331,10 +304,6 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan,
hb_bool_t
hb_aat_layout_has_tracking (hb_face_t *face)
{
#ifdef HB_NO_SHAPE_AAT
return false;
#endif
return face->table.trak->has_data ();
}
@ -343,10 +312,6 @@ hb_aat_layout_track (const hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
const AAT::trak& trak = *font->face->table.trak;
AAT::hb_aat_apply_context_t c (plan, font, buffer);
@ -370,12 +335,6 @@ hb_aat_layout_get_feature_types (hb_face_t *face,
unsigned int *feature_count, /* IN/OUT. May be NULL. */
hb_aat_layout_feature_type_t *features /* OUT. May be NULL. */)
{
#ifdef HB_NO_SHAPE_AAT
if (feature_count)
*feature_count = 0;
return 0;
#endif
return face->table.feat->get_feature_types (start_offset, feature_count, features);
}
@ -392,10 +351,6 @@ hb_ot_name_id_t
hb_aat_layout_feature_type_get_name_id (hb_face_t *face,
hb_aat_layout_feature_type_t feature_type)
{
#ifdef HB_NO_SHAPE_AAT
return HB_OT_NAME_ID_INVALID;
#endif
return face->table.feat->get_feature_name_id (feature_type);
}
@ -424,11 +379,8 @@ hb_aat_layout_feature_type_get_selector_infos (hb_face_t
hb_aat_layout_feature_selector_info_t *selectors, /* OUT. May be NULL. */
unsigned int *default_index /* OUT. May be NULL. */)
{
#ifdef HB_NO_SHAPE_AAT
if (selector_count)
*selector_count = 0;
return 0;
#endif
return face->table.feat->get_selector_infos (feature_type, start_offset, selector_count, selectors, default_index);
}
#endif

View File

@ -78,12 +78,4 @@ hb_aat_layout_track (const hb_ot_shape_plan_t *plan,
hb_buffer_t *buffer);
inline hb_language_t
_hb_aat_language_get (hb_face_t *face,
unsigned int i)
{
return face->table.ltag->get_language (i);
}
#endif /* HB_AAT_LAYOUT_HH */

View File

@ -26,6 +26,10 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb.hh"
#ifndef HB_NO_SHAPE_AAT
#include "hb-aat-map.hh"
#include "hb-aat-layout.hh"
@ -34,10 +38,6 @@
void hb_aat_map_builder_t::add_feature (hb_tag_t tag,
unsigned int value)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
if (tag == HB_TAG ('a','a','l','t'))
{
feature_info_t *info = features.push();
@ -57,10 +57,6 @@ void hb_aat_map_builder_t::add_feature (hb_tag_t tag,
void
hb_aat_map_builder_t::compile (hb_aat_map_t &m)
{
#ifdef HB_NO_SHAPE_AAT
return;
#endif
/* Sort features and merge duplicates */
if (features.length)
{
@ -74,3 +70,6 @@ hb_aat_map_builder_t::compile (hb_aat_map_t &m)
hb_aat_layout_compile_map (this, &m);
}
#endif

View File

@ -1,6 +1,6 @@
/*
* Copyright © 2017 Google, Inc.
* Copyright © 2019 Google, Inc.
* Copyright © 2019 Facebook, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
@ -41,6 +41,11 @@
#define HB_CODEPOINT_DECODE3_2(v) ((hb_codepoint_t) ((v) >> 21) & 0x1FFFFFu)
#define HB_CODEPOINT_DECODE3_3(v) ((hb_codepoint_t) (v) & 0x1FFFFFu)
/* Custom encoding used by hb-ucd. */
#define HB_CODEPOINT_ENCODE3_11_7_14(x,y,z) (((uint32_t) ((x) & 0x07FFu) << 21) | (((uint32_t) (y) & 0x007Fu) << 14) | (uint32_t) ((z) & 0x3FFFu))
#define HB_CODEPOINT_DECODE3_11_7_14_1(v) ((hb_codepoint_t) ((v) >> 21))
#define HB_CODEPOINT_DECODE3_11_7_14_2(v) ((hb_codepoint_t) (((v) >> 14) & 0x007Fu) | 0x0300)
#define HB_CODEPOINT_DECODE3_11_7_14_3(v) ((hb_codepoint_t) (v) & 0x3FFFu)
struct
{
@ -167,19 +172,37 @@ template <unsigned Pos=1, typename Appl, typename V>
auto hb_partial (Appl&& a, V&& v) HB_AUTO_RETURN
(( hb_partial_t<Pos, Appl, V> (a, v) ))
/* The following hacky replacement version is to make Visual Stuiod build:. */ \
/* https://github.com/harfbuzz/harfbuzz/issues/1730 */ \
/* The following, HB_PARTIALIZE, macro uses a particular corner-case
* of C++11 that is not particularly well-supported by all compilers.
* What's happening is that it's using "this" in a trailing return-type
* via decltype(). Broken compilers deduce the type of "this" pointer
* in that context differently from what it resolves to in the body
* of the function.
*
* One probable cause of this is that at the time of trailing return
* type declaration, "this" points to an incomplete type, whereas in
* the function body the type is complete. That doesn't justify the
* error in any way, but is probably what's happening.
*
* In the case of MSVC, we get around this by using C++14 "decltype(auto)"
* which deduces the type from the actual return statement. For gcc 4.8
* we use "+this" instead of "this" which produces an rvalue that seems
* to be deduced as the same type with this particular compiler, and seem
* to be fine as default code path as well.
*/
#ifdef _MSC_VER
/* https://github.com/harfbuzz/harfbuzz/issues/1730 */ \
#define HB_PARTIALIZE(Pos) \
template <typename _T> \
decltype(auto) operator () (_T&& _v) const \
{ return hb_partial<Pos> (this, hb_forward<_T> (_v)); } \
static_assert (true, "")
#else
/* https://github.com/harfbuzz/harfbuzz/issues/1724 */
#define HB_PARTIALIZE(Pos) \
template <typename _T> \
auto operator () (_T&& _v) const HB_AUTO_RETURN \
(hb_partial<Pos> (this, hb_forward<_T> (_v))) \
(hb_partial<Pos> (+this, hb_forward<_T> (_v))) \
static_assert (true, "")
#endif
@ -400,7 +423,7 @@ hb_bit_storage (T v)
return sizeof (unsigned long long) * 8 - __builtin_clzll (v);
#endif
#if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__)
#if (defined(_MSC_VER) && _MSC_VER >= 1500) || (defined(__MINGW32__) && (__GNUC__ < 4))
if (sizeof (T) <= sizeof (unsigned int))
{
unsigned long where;
@ -474,7 +497,7 @@ hb_ctz (T v)
return __builtin_ctzll (v);
#endif
#if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__)
#if (defined(_MSC_VER) && _MSC_VER >= 1500) || (defined(__MINGW32__) && (__GNUC__ < 4))
if (sizeof (T) <= sizeof (unsigned int))
{
unsigned long where;
@ -603,40 +626,19 @@ hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3)
/*
* Sort and search.
*/
template <typename ...Ts>
static inline void *
hb_bsearch (const void *key, const void *base,
size_t nmemb, size_t size,
int (*compar)(const void *_key, const void *_item))
{
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);
if (c < 0)
max = mid - 1;
else if (c > 0)
min = mid + 1;
else
return (void *) p;
}
return nullptr;
}
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 (*compar)(const void *_key, const void *_item, Ts... _ds),
Ts... ds)
{
int min = 0, max = (int) nmemb - 1;
while (min <= max)
{
int mid = ((unsigned int) min + (unsigned int) max) / 2;
const void *p = (const void *) (((const char *) base) + (mid * size));
int c = compar (key, p, arg);
int c = compar (key, p, ds...);
if (c < 0)
max = mid - 1;
else if (c > 0)
@ -649,115 +651,213 @@ hb_bsearch_r (const void *key, const void *base,
/* From https://github.com/noporpoise/sort_r
* With following modifications:
*
* 10 November 2018:
* https://github.com/noporpoise/sort_r/issues/7
*/
Feb 5, 2019 (c8c65c1e)
Modified to support optional argument using templates */
/* Isaac Turner 29 April 2014 Public Domain */
/*
hb_sort_r function to be exported.
hb_qsort 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
arg (optional) 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);
void hb_qsort(void *base, size_t nel, size_t width,
int (*compar)(const void *_a, const void *_b, [void *_arg]),
[void *arg]);
*/
#define SORT_R_SWAP(a,b,tmp) ((tmp) = (a), (a) = (b), (b) = (tmp))
/* 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)
/* swap a and b */
/* a and b must not be equal! */
static inline void sort_r_swap(char *__restrict a, char *__restrict b,
size_t w)
{
char tmp, *end = a+w;
if(compar(a, b, arg) > 0) {
for(; a < end; a++, b++) { tmp = *a; *a = *b; *b = tmp; }
for(; a < end; a++, b++) { SORT_R_SWAP(*a, *b, tmp); }
}
/* swap a, b iff a>b */
/* a and b must not be equal! */
/* __restrict is same as restrict but better support on old machines */
template <typename ...Ts>
static inline int sort_r_cmpswap(char *__restrict a,
char *__restrict b, size_t w,
int (*compar)(const void *_a,
const void *_b,
Ts... _ds),
Ts... ds)
{
if(compar(a, b, ds...) > 0) {
sort_r_swap(a, b, w);
return 1;
}
return 0;
}
/*
Swap consecutive blocks of bytes of size na and nb starting at memory addr ptr,
with the smallest swap so that the blocks are in the opposite order. Blocks may
be internally re-ordered e.g.
12345ab -> ab34512
123abc -> abc123
12abcde -> deabc12
*/
static inline void sort_r_swap_blocks(char *ptr, size_t na, size_t nb)
{
if(na > 0 && nb > 0) {
if(na > nb) { sort_r_swap(ptr, ptr+na, nb); }
else { sort_r_swap(ptr, ptr+nb, na); }
}
}
/* Implement recursive quicksort ourselves */
/* Note: quicksort is not stable, equivalent values may be swapped */
template <typename ...Ts>
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)
int (*compar)(const void *_a,
const void *_b,
Ts... _ds),
Ts... ds)
{
char *b = (char *)base, *end = b + nel*w;
if(nel < 7) {
/* for(size_t i=0; i<nel; i++) {printf("%4i", *(int*)(b + i*sizeof(int)));}
printf("\n"); */
if(nel < 10) {
/* 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) {}
for(pj = pi; pj > b && sort_r_cmpswap(pj-w,pj,w,compar,ds...); pj -= w) {}
}
}
else
{
/* nel > 6; Quicksort */
/* nel > 9; Quicksort */
/* Use median of first, middle and last items as pivot */
char *x, *y, *xend, ch;
char *pl, *pm, *pr;
int cmp;
char *pl, *ple, *pr, *pre, *pivot;
char *last = b+w*(nel-1), *tmp;
/*
Use median of second, middle and second-last items as pivot.
First and last may have been swapped with pivot and therefore be extreme
*/
char *l[3];
l[0] = b;
l[0] = b + w;
l[1] = b+w*(nel/2);
l[2] = last;
l[2] = last - w;
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; }
/* printf("pivots: %i, %i, %i\n", *(int*)l[0], *(int*)l[1], *(int*)l[2]); */
if(compar(l[0],l[1],ds...) > 0) { SORT_R_SWAP(l[0], l[1], tmp); }
if(compar(l[1],l[2],ds...) > 0) {
SORT_R_SWAP(l[1], l[2], tmp);
if(compar(l[0],l[1],ds...) > 0) { SORT_R_SWAP(l[0], 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;
}
/* swap mid value (l[1]), and last element to put pivot as last element */
if(l[1] != last) { sort_r_swap(l[1], last, w); }
pl = b;
pr = last;
/*
pl is the next item on the left to be compared to the pivot
pr is the last item on the right that was compared to the pivot
ple is the left position to put the next item that equals the pivot
ple is the last right position where we put an item that equals the pivot
v- end (beyond the array)
EEEEEELLLLLLLLuuuuuuuuGGGGGGGEEEEEEEE.
^- b ^- ple ^- pl ^- pr ^- pre ^- last (where the pivot is)
Pivot comparison key:
E = equal, L = less than, u = unknown, G = greater than, E = equal
*/
pivot = last;
ple = pl = b;
pre = pr = last;
/*
Strategy:
Loop into the list from the left and right at the same time to find:
- an item on the left that is greater than the pivot
- an item on the right that is less than the pivot
Once found, they are swapped and the loop continues.
Meanwhile items that are equal to the pivot are moved to the edges of the
array.
*/
while(pl < pr) {
pm = pl+((pr-pl+1)>>1);
for(; pl < pm; pl += w) {
if(sort_r_cmpswap(pl, pr, w, compar, arg)) {
pr -= w; /* pivot now at pl */
break;
/* Move left hand items which are equal to the pivot to the far left.
break when we find an item that is greater than the pivot */
for(; pl < pr; pl += w) {
cmp = compar(pl, pivot, ds...);
if(cmp > 0) { break; }
else if(cmp == 0) {
if(ple < pl) { sort_r_swap(ple, pl, w); }
ple += w;
}
}
pm = pl+((pr-pl)>>1);
for(; pm < pr; pr -= w) {
if(sort_r_cmpswap(pl, pr, w, compar, arg)) {
pl += w; /* pivot now at pr */
/* break if last batch of left hand items were equal to pivot */
if(pl >= pr) { break; }
/* Move right hand items which are equal to the pivot to the far right.
break when we find an item that is less than the pivot */
for(; pl < pr; ) {
pr -= w; /* Move right pointer onto an unprocessed item */
cmp = compar(pr, pivot, ds...);
if(cmp == 0) {
pre -= w;
if(pr < pre) { sort_r_swap(pr, pre, w); }
}
else if(cmp < 0) {
if(pl < pr) { sort_r_swap(pl, pr, w); }
pl += w;
break;
}
}
}
sort_r_simple(b, (pl-b)/w, w, compar, arg);
sort_r_simple(pl+w, (end-(pl+w))/w, w, compar, arg);
pl = pr; /* pr may have gone below pl */
/*
Now we need to go from: EEELLLGGGGEEEE
to: LLLEEEEEEEGGGG
Pivot comparison key:
E = equal, L = less than, u = unknown, G = greater than, E = equal
*/
sort_r_swap_blocks(b, ple-b, pl-ple);
sort_r_swap_blocks(pr, pre-pr, end-pre);
/*for(size_t i=0; i<nel; i++) {printf("%4i", *(int*)(b + i*sizeof(int)));}
printf("\n");*/
sort_r_simple(b, (pl-ple)/w, w, compar, ds...);
sort_r_simple(end-(pre-pr), (pre-pr)/w, w, compar, ds...);
}
}
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)
hb_qsort (void *base, size_t nel, size_t width,
int (*compar)(const void *_a, const void *_b))
{
sort_r_simple(base, nel, width, compar, arg);
#if defined(__OPTIMIZE_SIZE__) && !defined(HB_USE_INTERNAL_QSORT)
qsort (base, nel, width, compar);
#else
sort_r_simple (base, nel, width, compar);
#endif
}
static inline void
hb_qsort (void *base, size_t nel, size_t width,
int (*compar)(const void *_a, const void *_b, void *_arg),
void *arg)
{
#ifdef HAVE_GNU_QSORT_R
qsort_r (base, nel, width, compar, arg);
#else
sort_r_simple (base, nel, width, compar, arg);
#endif
}
@ -845,6 +945,12 @@ struct hb_bitwise_sub
operator () (const T &a, const T &b) const HB_AUTO_RETURN (a & ~b)
}
HB_FUNCOBJ (hb_bitwise_sub);
struct
{
template <typename T> auto
operator () (const T &a) const HB_AUTO_RETURN (~a)
}
HB_FUNCOBJ (hb_bitwise_neg);
struct
{ HB_PARTIALIZE(2);
@ -893,28 +999,29 @@ HB_FUNCOBJ (hb_neg);
/* Compiler-assisted vectorization. */
/* Type behaving similar to vectorized vars defined using __attribute__((vector_size(...))),
* using vectorized operations if HB_VECTOR_SIZE is set to **bit** numbers (eg 128).
* Define that to 0 to disable. */
* basically a fixed-size bitset. */
template <typename elt_t, unsigned int byte_size>
struct hb_vector_size_t
{
elt_t& operator [] (unsigned int i) { return u.v[i]; }
const elt_t& operator [] (unsigned int i) const { return u.v[i]; }
elt_t& operator [] (unsigned int i) { return v[i]; }
const elt_t& operator [] (unsigned int i) const { return v[i]; }
void clear (unsigned char v = 0) { memset (this, v, sizeof (*this)); }
template <typename Op>
hb_vector_size_t process (const Op& op) const
{
hb_vector_size_t r;
for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
r.v[i] = op (v[i]);
return r;
}
template <typename Op>
hb_vector_size_t process (const Op& op, const hb_vector_size_t &o) const
{
hb_vector_size_t r;
#if HB_VECTOR_SIZE
if (HB_VECTOR_SIZE && 0 == (byte_size * 8) % HB_VECTOR_SIZE)
for (unsigned int i = 0; i < ARRAY_LENGTH (u.vec); i++)
r.u.vec[i] = op (u.vec[i], o.u.vec[i]);
else
#endif
for (unsigned int i = 0; i < ARRAY_LENGTH (u.v); i++)
r.u.v[i] = op (u.v[i], o.u.v[i]);
for (unsigned int i = 0; i < ARRAY_LENGTH (v); i++)
r.v[i] = op (v[i], o.v[i]);
return r;
}
hb_vector_size_t operator | (const hb_vector_size_t &o) const
@ -924,27 +1031,11 @@ struct hb_vector_size_t
hb_vector_size_t operator ^ (const hb_vector_size_t &o) const
{ return process (hb_bitwise_xor, o); }
hb_vector_size_t operator ~ () const
{
hb_vector_size_t r;
#if HB_VECTOR_SIZE && 0
if (HB_VECTOR_SIZE && 0 == (byte_size * 8) % HB_VECTOR_SIZE)
for (unsigned int i = 0; i < ARRAY_LENGTH (u.vec); i++)
r.u.vec[i] = ~u.vec[i];
else
#endif
for (unsigned int i = 0; i < ARRAY_LENGTH (u.v); i++)
r.u.v[i] = ~u.v[i];
return r;
}
{ return process (hb_bitwise_neg); }
private:
static_assert (byte_size / sizeof (elt_t) * sizeof (elt_t) == byte_size, "");
union {
elt_t v[byte_size / sizeof (elt_t)];
#if HB_VECTOR_SIZE
hb_vector_size_impl_t vec[byte_size / sizeof (hb_vector_size_impl_t)];
#endif
} u;
static_assert (0 == byte_size % sizeof (elt_t), "");
elt_t v[byte_size / sizeof (elt_t)];
};

View File

@ -141,13 +141,13 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
hb_sorted_array_t<Type> qsort (int (*cmp_)(const void*, const void*))
{
if (likely (length))
::qsort (arrayZ, length, this->item_size, cmp_);
hb_qsort (arrayZ, length, this->item_size, cmp_);
return hb_sorted_array_t<Type> (*this);
}
hb_sorted_array_t<Type> qsort ()
{
if (likely (length))
::qsort (arrayZ, length, this->item_size, Type::cmp);
hb_qsort (arrayZ, length, this->item_size, Type::cmp);
return hb_sorted_array_t<Type> (*this);
}
void qsort (unsigned int start, unsigned int end)
@ -155,7 +155,7 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
end = hb_min (end, length);
assert (start <= end);
if (likely (start < end))
::qsort (arrayZ + start, end - start, this->item_size, Type::cmp);
hb_qsort (arrayZ + start, end - start, this->item_size, Type::cmp);
}
/*

View File

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

View File

@ -0,0 +1,139 @@
/*
* Copyright © 2019 Adobe 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.
*
* Adobe Author(s): Michiharu Ariza
*/
#ifndef HB_BIMAP_HH
#define HB_BIMAP_HH
#include "hb.hh"
/* Bi-directional map */
struct hb_bimap_t
{
hb_bimap_t () { init (); }
~hb_bimap_t () { fini (); }
void init ()
{
forw_map.init ();
back_map.init ();
}
void fini ()
{
forw_map.fini ();
back_map.fini ();
}
void reset ()
{
forw_map.reset ();
back_map.reset ();
}
bool in_error () const { return forw_map.in_error () || back_map.in_error (); }
void set (hb_codepoint_t lhs, hb_codepoint_t rhs)
{
forw_map.set (lhs, rhs);
back_map.set (rhs, lhs);
}
hb_codepoint_t get (hb_codepoint_t lhs) const { return forw_map.get (lhs); }
hb_codepoint_t backward (hb_codepoint_t rhs) const { return back_map.get (rhs); }
hb_codepoint_t operator [] (hb_codepoint_t lhs) const { return get (lhs); }
bool has (hb_codepoint_t lhs, hb_codepoint_t *vp = nullptr) const { return forw_map.has (lhs, vp); }
void del (hb_codepoint_t lhs)
{
back_map.del (get (lhs));
forw_map.del (lhs);
}
void clear ()
{
forw_map.clear ();
back_map.clear ();
}
bool is_empty () const { return get_population () == 0; }
unsigned int get_population () const { return forw_map.get_population (); }
protected:
hb_map_t forw_map;
hb_map_t back_map;
};
/* Inremental bimap: only lhs is given, rhs is incrementally assigned */
struct hb_inc_bimap_t : hb_bimap_t
{
/* Add a mapping from lhs to rhs with a unique value if lhs is unknown.
* Return the rhs value as the result.
*/
hb_codepoint_t add (hb_codepoint_t lhs)
{
hb_codepoint_t rhs = forw_map[lhs];
if (rhs == HB_MAP_VALUE_INVALID)
{
rhs = get_population ();
set (lhs, rhs);
}
return rhs;
}
/* Create an identity map. */
bool identity (unsigned int size)
{
clear ();
for (hb_codepoint_t i = 0; i < size; i++) set (i, i);
return !in_error ();
}
protected:
static int cmp_id (const void* a, const void* b)
{ return (int)*(const hb_codepoint_t *)a - (int)*(const hb_codepoint_t *)b; }
public:
/* Optional: after finished adding all mappings in a random order,
* reassign rhs to lhs so that they are in the same order. */
void sort ()
{
hb_codepoint_t count = get_population ();
hb_vector_t <hb_codepoint_t> work;
work.resize (count);
for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
work[rhs] = back_map[rhs];
work.qsort (cmp_id);
for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
set (work[rhs], rhs);
}
};
#endif /* HB_BIMAP_HH */

View File

@ -487,6 +487,7 @@ hb_blob_t::try_make_writable ()
* Mmap
*/
#ifndef HB_NO_OPEN
#ifdef HAVE_MMAP
# include <sys/types.h>
# include <sys/stat.h>
@ -676,3 +677,4 @@ fread_fail_without_close:
free (data);
return hb_blob_get_empty ();
}
#endif /* !HB_NO_OPEN */

View File

@ -24,14 +24,16 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb.hh"
#ifndef HB_NO_BUFFER_SERIALIZE
#include "hb-buffer.hh"
static const char *serialize_formats[] = {
#ifndef HB_NO_BUFFER_SERIALIZE
"text",
"json",
#endif
nullptr
};
@ -89,10 +91,8 @@ hb_buffer_serialize_format_to_string (hb_buffer_serialize_format_t format)
{
switch ((unsigned) format)
{
#ifndef HB_NO_BUFFER_SERIALIZE
case HB_BUFFER_SERIALIZE_FORMAT_TEXT: return serialize_formats[0];
case HB_BUFFER_SERIALIZE_FORMAT_JSON: return serialize_formats[1];
#endif
default:
case HB_BUFFER_SERIALIZE_FORMAT_INVALID: return nullptr;
}
@ -348,10 +348,6 @@ hb_buffer_serialize_glyphs (hb_buffer_t *buffer,
if (buf_size)
*buf = '\0';
#ifdef HB_NO_BUFFER_SERIALIZE
return 0;
#endif
assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
@ -457,10 +453,6 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
end_ptr = &end;
*end_ptr = buf;
#ifdef HB_NO_BUFFER_SERIALIZE
return false;
#endif
assert ((!buffer->len && buffer->content_type == HB_BUFFER_CONTENT_TYPE_INVALID) ||
buffer->content_type == HB_BUFFER_CONTENT_TYPE_GLYPHS);
@ -496,3 +488,6 @@ hb_buffer_deserialize_glyphs (hb_buffer_t *buffer,
}
}
#endif

View File

@ -1993,6 +1993,7 @@ hb_buffer_diff (hb_buffer_t *buffer,
* Debugging.
*/
#ifndef HB_NO_BUFFER_MESSAGE
/**
* hb_buffer_set_message_func:
* @buffer: an #hb_buffer_t.
@ -2022,11 +2023,11 @@ hb_buffer_set_message_func (hb_buffer_t *buffer,
buffer->message_destroy = nullptr;
}
}
bool
hb_buffer_t::message_impl (hb_font_t *font, const char *fmt, va_list ap)
{
char buf[100];
vsnprintf (buf, sizeof (buf), fmt, ap);
vsnprintf (buf, sizeof (buf), fmt, ap);
return (bool) this->message_func (this, font, buf, this->message_data);
}
#endif

View File

@ -124,7 +124,9 @@ struct hb_buffer_t
unsigned int context_len[2];
/* Debugging API */
#ifndef HB_NO_BUFFER_MESSAGE
hb_buffer_message_func_t message_func;
#endif
void *message_data;
hb_destroy_func_t message_destroy;
@ -347,9 +349,19 @@ struct hb_buffer_t
HB_INTERNAL void sort (unsigned int start, unsigned int end, int(*compar)(const hb_glyph_info_t *, const hb_glyph_info_t *));
bool messaging () { return unlikely (message_func); }
bool messaging ()
{
#ifdef HB_NO_BUFFER_MESSAGE
return false;
#else
return unlikely (message_func);
#endif
}
bool message (hb_font_t *font, const char *fmt, ...) HB_PRINTF_FUNC(3, 4)
{
#ifdef HB_NO_BUFFER_MESSAGE
return true;
#else
if (!messaging ())
return true;
va_list ap;
@ -357,6 +369,7 @@ struct hb_buffer_t
bool ret = message_impl (font, fmt, ap);
va_end (ap);
return ret;
#endif
}
HB_INTERNAL bool message_impl (hb_font_t *font, const char *fmt, va_list ap) HB_PRINTF_FUNC(3, 0);

View File

@ -76,8 +76,8 @@ struct biased_subrs_t
void fini () {}
unsigned int get_count () const { return (subrs == nullptr)? 0: subrs->count; }
unsigned int get_bias () const { return bias; }
unsigned int get_count () const { return (subrs == nullptr) ? 0 : subrs->count; }
unsigned int get_bias () const { return bias; }
byte_str_t operator [] (unsigned int index) const
{

View File

@ -134,10 +134,10 @@ struct dict_opset_t : opset_t<number_t>
return value;
case END:
value = (double)(neg? -int_part: int_part);
value = (double) (neg ? -int_part : int_part);
if (frac_count > 0)
{
double frac = (frac_part / pow (10.0, (double)frac_count));
double frac = (frac_part / pow (10.0, (double) frac_count));
if (neg) frac = -frac;
value += frac;
}
@ -146,16 +146,16 @@ struct dict_opset_t : opset_t<number_t>
if (value == 0.0)
return value;
if (exp_neg)
return neg? -DBL_MIN: DBL_MIN;
return neg ? -DBL_MIN : DBL_MIN;
else
return neg? -DBL_MAX: DBL_MAX;
return neg ? -DBL_MAX : DBL_MAX;
}
if (exp_part != 0)
{
if (exp_neg)
value /= pow (10.0, (double)exp_part);
value /= pow (10.0, (double) exp_part);
else
value *= pow (10.0, (double)exp_part);
value *= pow (10.0, (double) exp_part);
}
return value;

View File

@ -35,6 +35,9 @@
#include <xlocale.h>
#endif
#ifdef HB_NO_SETLOCALE
#define setlocale(Category, Locale) "C"
#endif
/**
* SECTION:hb-common
@ -67,7 +70,7 @@ _hb_options_init ()
p = c + strlen (c);
#define OPTION(name, symbol) \
if (0 == strncmp (c, name, p - c) && strlen (name) == p - c) do { u.opts.symbol = true; } while (0)
if (0 == strncmp (c, name, p - c) && strlen (name) == static_cast<size_t>(p - c)) do { u.opts.symbol = true; } while (0)
OPTION ("uniscribe-bug-compatible", uniscribe_bug_compatible);
OPTION ("aat", aat);

View File

@ -40,6 +40,7 @@
#define HB_LEAN
#define HB_MINI
#define HB_NO_MT
#define HB_NO_UCD_UNASSIGNED
#ifndef NDEBUG
#define NDEBUG
#endif
@ -52,15 +53,28 @@
#define HB_DISABLE_DEPRECATED
#define HB_NDEBUG
#define HB_NO_ATEXIT
#define HB_NO_BUFFER_MESSAGE
#define HB_NO_BUFFER_SERIALIZE
#define HB_NO_BITMAP
#define HB_NO_CFF
#define HB_NO_COLOR
#define HB_NO_FACE_COLLECT_UNICODES
#define HB_NO_GETENV
#define HB_NO_HINTING
#define HB_NO_LANGUAGE_PRIVATE_SUBTAG
#define HB_NO_LAYOUT_FEATURE_PARAMS
#define HB_NO_LAYOUT_COLLECT_GLYPHS
#define HB_NO_LAYOUT_UNUSED
#define HB_NO_MATH
#define HB_NO_MMAP
#define HB_NO_NAME
#define HB_NO_OPEN
#define HB_NO_SETLOCALE
#define HB_NO_OT_FONT_GLYPH_NAMES
#define HB_NO_OT_SHAPE_FRACTIONS
#define HB_NO_STAT
#define HB_NO_SUBSET_LAYOUT
#define HB_NO_VAR
#endif
#ifdef HB_MINI
@ -68,7 +82,8 @@
#define HB_NO_LEGACY
#endif
/* Closure. */
/* Closure of options. */
#ifdef HB_DISABLE_DEPRECATED
#define HB_IF_NOT_DEPRECATED(x)
@ -95,6 +110,9 @@
#endif
#ifdef HB_NO_LEGACY
#define HB_NO_CMAP_LEGACY_SUBTABLES
#define HB_NO_FALLBACK_SHAPE
#define HB_NO_OT_KERN
#define HB_NO_OT_LAYOUT_BLACKLIST
#define HB_NO_OT_SHAPE_FALLBACK
#endif

View File

@ -27,6 +27,9 @@
*/
#include "hb.hh"
#ifdef HAVE_CORETEXT
#include "hb-shaper-impl.hh"
#include "hb-coretext.h"
@ -649,7 +652,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
DEBUG_MSG (CORETEXT, nullptr, __VA_ARGS__); \
ret = false; \
goto fail; \
} HB_STMT_END;
} HB_STMT_END
bool ret = true;
CFStringRef string_ref = nullptr;
@ -977,7 +980,7 @@ resize_and_retry:
#define SCRATCH_RESTORE() \
scratch_size = scratch_size_saved; \
scratch = scratch_saved;
scratch = scratch_saved
{ /* Setup glyphs */
SCRATCH_SAVE();
@ -1148,3 +1151,6 @@ fail:
return ret;
}
#endif

View File

@ -165,29 +165,8 @@ hb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t *decomposed);
typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
void *user_data);
typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_v_kerning_func_t;
/**
* hb_font_funcs_set_glyph_h_kerning_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
*
*
* Since: 0.9.2
* Deprecated: 2.0.0
**/
HB_EXTERN void
hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_h_kerning_func_t func,
void *user_data, hb_destroy_func_t destroy);
/**
* hb_font_funcs_set_glyph_v_kerning_func:
* @ffuncs: font functions.
@ -206,19 +185,9 @@ hb_font_funcs_set_glyph_v_kerning_func (hb_font_funcs_t *ffuncs,
void *user_data, hb_destroy_func_t destroy);
HB_EXTERN hb_position_t
hb_font_get_glyph_h_kerning (hb_font_t *font,
hb_codepoint_t left_glyph, hb_codepoint_t right_glyph);
HB_EXTERN hb_position_t
hb_font_get_glyph_v_kerning (hb_font_t *font,
hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph);
HB_EXTERN void
hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
hb_direction_t direction,
hb_position_t *x, hb_position_t *y);
#endif
HB_END_DECLS

View File

@ -23,6 +23,9 @@
*/
#include "hb.hh"
#ifdef HAVE_DIRECTWRITE
#include "hb-shaper-impl.hh"
#include <DWrite_1.h>
@ -173,7 +176,7 @@ _hb_directwrite_shaper_face_data_create (hb_face_t *face)
HB_STMT_START { \
DEBUG_MSG (DIRECTWRITE, nullptr, __VA_ARGS__); \
return nullptr; \
} HB_STMT_END;
} HB_STMT_END
if (FAILED (hr))
FAIL ("Failed to load font file from data!");
@ -951,10 +954,13 @@ hb_directwrite_face_create (IDWriteFontFace *font_face)
*
* Return value: DirectWrite IDWriteFontFace object corresponding to the given input
*
* Since: REPLACEME
* Since: 2.5.0
**/
IDWriteFontFace *
hb_directwrite_face_get_font_face (hb_face_t *face)
{
return face->data.directwrite->fontFace;
}
#endif

View File

@ -531,6 +531,7 @@ hb_face_get_table_tags (const hb_face_t *face,
*/
#ifndef HB_NO_FACE_COLLECT_UNICODES
/**
* hb_face_collect_unicodes:
* @face: font face.
@ -544,7 +545,6 @@ hb_face_collect_unicodes (hb_face_t *face,
{
face->table.cmap->collect_unicodes (out);
}
/**
* hb_face_collect_variation_selectors:
* @face: font face.
@ -560,7 +560,6 @@ hb_face_collect_variation_selectors (hb_face_t *face,
{
face->table.cmap->collect_variation_selectors (out);
}
/**
* hb_face_collect_variation_unicodes:
* @face: font face.
@ -577,7 +576,7 @@ hb_face_collect_variation_unicodes (hb_face_t *face,
{
face->table.cmap->collect_variation_unicodes (variation_selector, out);
}
#endif
/*

View File

@ -26,6 +26,7 @@
#include "hb-shaper-impl.hh"
#ifndef HB_NO_FALLBACK_SHAPE
/*
* shaper face data
@ -120,3 +121,5 @@ _hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
return true;
}
#endif

View File

@ -336,7 +336,6 @@ hb_font_get_glyph_v_origin_default (hb_font_t *font,
return ret;
}
#ifndef HB_DISABLE_DEPRECATED
static hb_position_t
hb_font_get_glyph_h_kerning_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
@ -356,6 +355,7 @@ hb_font_get_glyph_h_kerning_default (hb_font_t *font,
return font->parent_scale_x_distance (font->parent->get_glyph_h_kerning (left_glyph, right_glyph));
}
#ifndef HB_DISABLE_DEPRECATED
static hb_position_t
hb_font_get_glyph_v_kerning_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
@ -927,7 +927,6 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
return font->get_glyph_v_origin (glyph, x, y);
}
#ifndef HB_DISABLE_DEPRECATED
/**
* hb_font_get_glyph_h_kerning:
* @font: a font.
@ -939,7 +938,6 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
* Return value:
*
* Since: 0.9.2
* Deprecated: 2.0.0
**/
hb_position_t
hb_font_get_glyph_h_kerning (hb_font_t *font,
@ -948,6 +946,7 @@ hb_font_get_glyph_h_kerning (hb_font_t *font,
return font->get_glyph_h_kerning (left_glyph, right_glyph);
}
#ifndef HB_DISABLE_DEPRECATED
/**
* hb_font_get_glyph_v_kerning:
* @font: a font.
@ -1177,7 +1176,6 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
return font->subtract_glyph_origin_for_direction (glyph, direction, x, y);
}
#ifndef HB_DISABLE_DEPRECATED
/**
* hb_font_get_glyph_kerning_for_direction:
* @font: a font.
@ -1190,7 +1188,6 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
*
*
* Since: 0.9.2
* Deprecated: 2.0.0
**/
void
hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
@ -1200,7 +1197,6 @@ hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
{
return font->get_glyph_kerning_for_direction (first_glyph, second_glyph, direction, x, y);
}
#endif
/**
* hb_font_get_glyph_extents_for_origin:
@ -1828,6 +1824,7 @@ _hb_font_adopt_var_coords_normalized (hb_font_t *font,
font->num_coords = coords_length;
}
#ifndef HB_NO_VAR
/**
* hb_font_set_variations:
*
@ -1858,7 +1855,6 @@ hb_font_set_variations (hb_font_t *font,
normalized, coords_length);
_hb_font_adopt_var_coords_normalized (font, normalized, coords_length);
}
/**
* hb_font_set_var_coords_design:
*
@ -1879,6 +1875,7 @@ hb_font_set_var_coords_design (hb_font_t *font,
hb_ot_var_normalize_coords (font->face, coords_length, coords, normalized);
_hb_font_adopt_var_coords_normalized (font, normalized, coords_length);
}
#endif
/**
* hb_font_set_var_coords_normalized:

View File

@ -157,6 +157,11 @@ typedef hb_bool_t (*hb_font_get_glyph_origin_func_t) (hb_font_t *font, void *fon
typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_h_origin_func_t;
typedef hb_font_get_glyph_origin_func_t hb_font_get_glyph_v_origin_func_t;
typedef hb_position_t (*hb_font_get_glyph_kerning_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
void *user_data);
typedef hb_font_get_glyph_kerning_func_t hb_font_get_glyph_h_kerning_func_t;
typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
@ -356,6 +361,22 @@ hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_v_origin_func_t func,
void *user_data, hb_destroy_func_t destroy);
/**
* hb_font_funcs_set_glyph_h_kerning_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
*
*
* Since: 0.9.2
**/
HB_EXTERN void
hb_font_funcs_set_glyph_h_kerning_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_h_kerning_func_t func,
void *user_data, hb_destroy_func_t destroy);
/**
* hb_font_funcs_set_glyph_extents_func:
* @ffuncs: font functions.
@ -469,6 +490,10 @@ hb_font_get_glyph_v_origin (hb_font_t *font,
hb_codepoint_t glyph,
hb_position_t *x, hb_position_t *y);
HB_EXTERN hb_position_t
hb_font_get_glyph_h_kerning (hb_font_t *font,
hb_codepoint_t left_glyph, hb_codepoint_t right_glyph);
HB_EXTERN hb_bool_t
hb_font_get_glyph_extents (hb_font_t *font,
hb_codepoint_t glyph,
@ -531,6 +556,12 @@ hb_font_subtract_glyph_origin_for_direction (hb_font_t *font,
hb_direction_t direction,
hb_position_t *x, hb_position_t *y);
HB_EXTERN void
hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
hb_direction_t direction,
hb_position_t *x, hb_position_t *y);
HB_EXTERN hb_bool_t
hb_font_get_glyph_extents_for_origin (hb_font_t *font,
hb_codepoint_t glyph,

View File

@ -51,7 +51,7 @@
HB_FONT_FUNC_IMPLEMENT (glyph_v_advances) \
HB_FONT_FUNC_IMPLEMENT (glyph_h_origin) \
HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \
HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning)) \
HB_FONT_FUNC_IMPLEMENT (glyph_h_kerning) \
HB_IF_NOT_DEPRECATED (HB_FONT_FUNC_IMPLEMENT (glyph_v_kerning)) \
HB_FONT_FUNC_IMPLEMENT (glyph_extents) \
HB_FONT_FUNC_IMPLEMENT (glyph_contour_point) \

View File

@ -29,6 +29,8 @@
#include "hb.hh"
#ifdef HAVE_FREETYPE
#include "hb-ft.h"
#include "hb-font.hh"
@ -346,6 +348,25 @@ hb_ft_get_glyph_v_origin (hb_font_t *font,
return true;
}
#ifndef HB_NO_OT_SHAPE_FALLBACK
static hb_position_t
hb_ft_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_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
FT_Vector kerningv;
FT_Kerning_Mode mode = font->x_ppem ? FT_KERNING_DEFAULT : FT_KERNING_UNFITTED;
if (FT_Get_Kerning (ft_font->ft_face, left_glyph, right_glyph, mode, &kerningv))
return 0;
return kerningv.x;
}
#endif
static hb_bool_t
hb_ft_get_glyph_extents (hb_font_t *font,
void *font_data,
@ -497,6 +518,10 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft
hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ft_get_glyph_v_advance, nullptr, nullptr);
//hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ft_get_glyph_h_origin, nullptr, nullptr);
hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ft_get_glyph_v_origin, nullptr, nullptr);
#ifndef HB_NO_OT_SHAPE_FALLBACK
hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ft_get_glyph_h_kerning, nullptr, nullptr);
#endif
//hb_font_funcs_set_glyph_v_kerning_func (funcs, hb_ft_get_glyph_v_kerning, nullptr, nullptr);
hb_font_funcs_set_glyph_extents_func (funcs, hb_ft_get_glyph_extents, nullptr, nullptr);
hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ft_get_glyph_contour_point, nullptr, nullptr);
hb_font_funcs_set_glyph_name_func (funcs, hb_ft_get_glyph_name, nullptr, nullptr);
@ -854,3 +879,6 @@ hb_ft_font_set_funcs (hb_font_t *font)
_hb_ft_font_set_funcs (font, ft_face, true);
hb_ft_font_set_load_flags (font, FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING);
}
#endif

View File

@ -28,6 +28,8 @@
#include "hb.hh"
#ifdef HAVE_GLIB
#include "hb-glib.h"
#include "hb-machinery.hh"
@ -404,3 +406,6 @@ hb_glib_blob_create (GBytes *gbytes)
_hb_g_bytes_unref);
}
#endif
#endif

View File

@ -27,6 +27,8 @@
#include "hb.hh"
#ifdef HAVE_GOBJECT
/* g++ didn't like older gtype.h gcc-only code path. */
#include <glib.h>
#if !GLIB_CHECK_VERSION(2,29,16)
@ -44,6 +46,11 @@
/* enumerations from "@filename@" */
/*** END file-production ***/
/*** BEGIN file-tail ***/
#endif
/*** END file-tail ***/
/*** BEGIN value-header ***/
GType
@enum_name@_get_type ()

View File

@ -26,6 +26,8 @@
#include "hb.hh"
#ifdef HAVE_GOBJECT
/**
* SECTION:hb-gobject
@ -94,3 +96,6 @@ HB_DEFINE_VALUE_TYPE (user_data_key)
HB_DEFINE_VALUE_TYPE (ot_math_glyph_variant)
HB_DEFINE_VALUE_TYPE (ot_math_glyph_part)
#endif

View File

@ -26,6 +26,10 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb.hh"
#ifdef HAVE_GRAPHITE2
#include "hb-shaper-impl.hh"
#include "hb-graphite2.h"
@ -447,3 +451,6 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
return true;
}
#endif

View File

@ -29,6 +29,8 @@
#include "hb.hh"
#ifdef HAVE_ICU
#include "hb-icu.h"
#include "hb-machinery.hh"
@ -351,3 +353,6 @@ hb_icu_get_unicode_funcs ()
{
return static_icu_funcs.get_unconst ();
}
#endif

View File

@ -106,7 +106,7 @@ typedef volatile int hb_mutex_impl_t;
#define HB_MUTEX_IMPL_INIT 0
#define hb_mutex_impl_init(M) *(M) = 0
#define hb_mutex_impl_lock(M) HB_STMT_START { while (*(M)) HB_SCHED_YIELD (); (*(M))++; } HB_STMT_END
#define hb_mutex_impl_unlock(M) (*(M))--;
#define hb_mutex_impl_unlock(M) (*(M))--
#define hb_mutex_impl_finish(M) HB_STMT_START {} HB_STMT_END

View File

@ -74,7 +74,7 @@ using hb_static_size = _hb_static_size<T, void>;
*/
extern HB_INTERNAL
hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)];
uint64_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)];
/* Generic nul-content Null objects. */
template <typename Type>
@ -128,7 +128,7 @@ struct NullHelper
* causing bad memory access. So, races there are not actually introducing incorrectness
* in the code. Has ~12kb binary size overhead to have it, also clang build fails with it. */
extern HB_INTERNAL
/*thread_local*/ hb_vector_size_impl_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)];
/*thread_local*/ uint64_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)];
/* CRAP pool: Common Region for Access Protection. */
template <typename Type>

View File

@ -59,11 +59,11 @@ struct IntType
typedef Type type;
typedef hb_conditional<hb_is_signed (Type), signed, unsigned> wide_type;
IntType<Type, Size>& operator = (wide_type i) { v = i; return *this; }
IntType& operator = (wide_type i) { v = i; return *this; }
operator wide_type () const { return v; }
bool operator == (const IntType<Type,Size> &o) const { return (Type) v == (Type) o.v; }
bool operator != (const IntType<Type,Size> &o) const { return !(*this == o); }
HB_INTERNAL static int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b)
bool operator == (const IntType &o) const { return (Type) v == (Type) o.v; }
bool operator != (const IntType &o) const { return !(*this == o); }
HB_INTERNAL static int cmp (const IntType *a, const IntType *b)
{ return b->cmp (*a); }
template <typename Type2>
int cmp (Type2 a) const
@ -146,7 +146,7 @@ struct LONGDATETIME
* system, feature, or baseline */
struct Tag : HBUINT32
{
Tag& operator = (uint32_t i) { HBUINT32::operator= (i); return *this; }
Tag& operator = (hb_tag_t i) { HBUINT32::operator= (i); return *this; }
/* What the char* converters return is NOT nul-terminated. Print using "%.4s" */
operator const char* () const { return reinterpret_cast<const char *> (&this->v); }
operator char* () { return reinterpret_cast<char *> (&this->v); }

View File

@ -27,6 +27,7 @@
#define HB_OT_CFF_COMMON_HH
#include "hb-open-type.hh"
#include "hb-bimap.hh"
#include "hb-ot-layout-common.hh"
#include "hb-cff-interp-dict-common.hh"
#include "hb-subset-plan.hh"
@ -82,22 +83,14 @@ struct str_buff_vec_t : hb_vector_t<str_buff_t>
template <typename COUNT>
struct CFFIndex
{
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (likely ((count.sanitize (c) && count == 0) || /* empty INDEX */
(c->check_struct (this) && offSize >= 1 && offSize <= 4 &&
c->check_array (offsets, offSize, count + 1) &&
c->check_array ((const HBUINT8*)data_base (), 1, max_offset () - 1))));
}
static unsigned int calculate_offset_array_size (unsigned int offSize, unsigned int count)
{ return offSize * (count + 1); }
unsigned int offset_array_size () const
{ return calculate_offset_array_size (offSize, count); }
static unsigned int calculate_serialized_size (unsigned int offSize_, unsigned int count, unsigned int dataSize)
static unsigned int calculate_serialized_size (unsigned int offSize_, unsigned int count,
unsigned int dataSize)
{
if (count == 0)
return COUNT::static_size;
@ -199,11 +192,11 @@ struct CFFIndex
unsigned int length_at (unsigned int index) const
{
if (likely ((offset_at (index + 1) >= offset_at (index)) &&
(offset_at (index + 1) <= offset_at (count))))
return offset_at (index + 1) - offset_at (index);
else
return 0;
if (likely ((offset_at (index + 1) >= offset_at (index)) &&
(offset_at (index + 1) <= offset_at (count))))
return offset_at (index + 1) - offset_at (index);
else
return 0;
}
const unsigned char *data_base () const
@ -216,12 +209,12 @@ struct CFFIndex
if (likely (index < count))
return byte_str_t (data_base () + offset_at (index) - 1, length_at (index));
else
return Null(byte_str_t);
return Null (byte_str_t);
}
unsigned int get_size () const
{
if (this != &Null(CFFIndex))
if (this != &Null (CFFIndex))
{
if (count > 0)
return min_size + offset_array_size () + (offset_at (count) - 1);
@ -232,6 +225,15 @@ struct CFFIndex
return 0;
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (likely ((count.sanitize (c) && count == 0) || /* empty INDEX */
(c->check_struct (this) && offSize >= 1 && offSize <= 4 &&
c->check_array (offsets, offSize, count + 1) &&
c->check_array ((const HBUINT8*) data_base (), 1, max_offset () - 1))));
}
protected:
unsigned int max_offset () const
{
@ -245,10 +247,10 @@ struct CFFIndex
}
public:
COUNT count; /* Number of object data. Note there are (count+1) offsets */
HBUINT8 offSize; /* The byte size of each offset in the offsets array. */
HBUINT8 offsets[VAR]; /* The array of (count + 1) offsets into objects array (1-base). */
/* HBUINT8 data[VAR]; Object data */
COUNT count; /* Number of object data. Note there are (count+1) offsets */
HBUINT8 offSize; /* The byte size of each offset in the offsets array. */
HBUINT8 offsets[VAR]; /* The array of (count + 1) offsets into objects array (1-base). */
/* HBUINT8 data[VAR]; Object data */
public:
DEFINE_SIZE_ARRAY (COUNT::static_size + HBUINT8::static_size, offsets);
};
@ -293,7 +295,7 @@ struct CFFIndexOf : CFFIndex<COUNT>
/* serialize data */
for (unsigned int i = 0; i < dataArrayLen; i++)
{
TYPE *dest = c->start_embed<TYPE> ();
TYPE *dest = c->start_embed<TYPE> ();
if (unlikely (dest == nullptr ||
!dest->serialize (c, dataArray[i], param1, param2)))
return_trace (false);
@ -310,7 +312,7 @@ struct CFFIndexOf : CFFIndex<COUNT>
const PARAM &param)
{
/* determine offset size */
unsigned int totalDataSize = 0;
unsigned int totalDataSize = 0;
for (unsigned int i = 0; i < dataArrayLen; i++)
{
unsigned int dataSize = TYPE::calculate_serialized_size (dataArray[i], param);
@ -334,10 +336,9 @@ struct Dict : UnsizedByteStr
{
TRACE_SERIALIZE (this);
for (unsigned int i = 0; i < dictval.get_count (); i++)
{
if (unlikely (!opszr.serialize (c, dictval[i], param)))
return_trace (false);
}
return_trace (true);
}
@ -391,14 +392,10 @@ struct Dict : UnsizedByteStr
{ return serialize_int_op<HBUINT16, 0, 0x7FFF> (c, op, value, OpCode_shortint); }
static bool serialize_offset4_op (hb_serialize_context_t *c, op_code_t op, int value)
{
return serialize_uint4_op (c, op, value);
}
{ return serialize_uint4_op (c, op, value); }
static bool serialize_offset2_op (hb_serialize_context_t *c, op_code_t op, int value)
{
return serialize_uint2_op (c, op, value);
}
{ return serialize_uint2_op (c, op, value); }
};
struct TopDict : Dict {};
@ -414,57 +411,6 @@ struct table_info_t
unsigned int offSize;
};
/* used to remap font index or SID from fullset to subset.
* set to CFF_UNDEF_CODE if excluded from subset */
struct remap_t : hb_vector_t<hb_codepoint_t>
{
void init () { SUPER::init (); }
void fini () { SUPER::fini (); }
bool reset (unsigned int size)
{
if (unlikely (!SUPER::resize (size)))
return false;
for (unsigned int i = 0; i < length; i++)
(*this)[i] = CFF_UNDEF_CODE;
count = 0;
return true;
}
bool identity (unsigned int size)
{
if (unlikely (!SUPER::resize (size)))
return false;
unsigned int i;
for (i = 0; i < length; i++)
(*this)[i] = i;
count = i;
return true;
}
bool excludes (hb_codepoint_t id) const
{ return (id < length) && ((*this)[id] == CFF_UNDEF_CODE); }
bool includes (hb_codepoint_t id) const
{ return !excludes (id); }
unsigned int add (unsigned int i)
{
if ((*this)[i] == CFF_UNDEF_CODE)
(*this)[i] = count++;
return (*this)[i];
}
hb_codepoint_t get_count () const { return count; }
protected:
hb_codepoint_t count;
private:
typedef hb_vector_t<hb_codepoint_t> SUPER;
};
template <typename COUNT>
struct FDArray : CFFIndexOf<COUNT, FontDict>
{
@ -483,7 +429,7 @@ struct FDArray : CFFIndexOf<COUNT, FontDict>
return_trace (false);
/* serialize font dict offsets */
unsigned int offset = 1;
unsigned int offset = 1;
unsigned int fid = 0;
for (; fid < fontDicts.length; fid++)
{
@ -508,7 +454,7 @@ struct FDArray : CFFIndexOf<COUNT, FontDict>
unsigned int offSize_,
const hb_vector_t<DICTVAL> &fontDicts,
unsigned int fdCount,
const remap_t &fdmap,
const hb_inc_bimap_t &fdmap,
OP_SERIALIZER& opszr,
const hb_vector_t<table_info_t> &privateInfos)
{
@ -523,7 +469,7 @@ struct FDArray : CFFIndexOf<COUNT, FontDict>
unsigned int offset = 1;
unsigned int fid = 0;
for (unsigned i = 0; i < fontDicts.length; i++)
if (fdmap.includes (i))
if (fdmap.has (i))
{
if (unlikely (fid >= fdCount)) return_trace (false);
CFFIndexOf<COUNT, FontDict>::set_offset_at (fid++, offset);
@ -533,7 +479,7 @@ struct FDArray : CFFIndexOf<COUNT, FontDict>
/* serialize font dicts */
for (unsigned int i = 0; i < fontDicts.length; i++)
if (fdmap.includes (i))
if (fdmap.has (i))
{
FontDict *dict = c->start_embed<FontDict> ();
if (unlikely (!dict->serialize (c, fontDicts[i], opszr, privateInfos[fdmap[i]])))
@ -547,12 +493,12 @@ struct FDArray : CFFIndexOf<COUNT, FontDict>
static unsigned int calculate_serialized_size (unsigned int &offSize_ /* OUT */,
const hb_vector_t<DICTVAL> &fontDicts,
unsigned int fdCount,
const remap_t &fdmap,
const hb_inc_bimap_t &fdmap,
OP_SERIALIZER& opszr)
{
unsigned int dictsSize = 0;
for (unsigned int i = 0; i < fontDicts.len; i++)
if (fdmap.includes (i))
if (fdmap.has (i))
dictsSize += FontDict::calculate_serialized_size (fontDicts[i], opszr);
offSize_ = calcOffSize (dictsSize);
@ -575,9 +521,7 @@ struct FDSelect0 {
}
hb_codepoint_t get_fd (hb_codepoint_t glyph) const
{
return (hb_codepoint_t)fds[glyph];
}
{ return (hb_codepoint_t) fds[glyph]; }
unsigned int get_size (unsigned int num_glyphs) const
{ return HBUINT8::static_size * num_glyphs; }
@ -588,7 +532,8 @@ struct FDSelect0 {
};
template <typename GID_TYPE, typename FD_TYPE>
struct FDSelect3_4_Range {
struct FDSelect3_4_Range
{
bool sanitize (hb_sanitize_context_t *c, const void * /*nullptr*/, unsigned int fdcount) const
{
TRACE_SANITIZE (this);
@ -597,12 +542,13 @@ struct FDSelect3_4_Range {
GID_TYPE first;
FD_TYPE fd;
public:
DEFINE_SIZE_STATIC (GID_TYPE::static_size + FD_TYPE::static_size);
};
template <typename GID_TYPE, typename FD_TYPE>
struct FDSelect3_4 {
struct FDSelect3_4
{
unsigned int get_size () const
{ return GID_TYPE::static_size * 2 + ranges.get_size (); }
@ -614,10 +560,8 @@ struct FDSelect3_4 {
return_trace (false);
for (unsigned int i = 1; i < nRanges (); i++)
{
if (unlikely (ranges[i - 1].first >= ranges[i].first))
return_trace (false);
}
return_trace (false);
if (unlikely (!sentinel().sanitize (c) || (sentinel() != c->get_num_glyphs ())))
return_trace (false);
@ -649,17 +593,8 @@ struct FDSelect3_4 {
typedef FDSelect3_4<HBUINT16, HBUINT8> FDSelect3;
typedef FDSelect3_4_Range<HBUINT16, HBUINT8> FDSelect3_Range;
struct FDSelect {
bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
{
TRACE_SANITIZE (this);
return_trace (likely (c->check_struct (this) && (format == 0 || format == 3) &&
(format == 0)?
u.format0.sanitize (c, fdcount):
u.format3.sanitize (c, fdcount)));
}
struct FDSelect
{
bool serialize (hb_serialize_context_t *c, const FDSelect &src, unsigned int num_glyphs)
{
TRACE_SERIALIZE (this);
@ -675,30 +610,46 @@ struct FDSelect {
unsigned int get_size (unsigned int num_glyphs) const
{
unsigned int size = format.static_size;
if (format == 0)
size += u.format0.get_size (num_glyphs);
else
size += u.format3.get_size ();
return size;
switch (format)
{
case 0: return format.static_size + u.format0.get_size (num_glyphs);
case 3: return format.static_size + u.format3.get_size ();
default:return 0;
}
}
hb_codepoint_t get_fd (hb_codepoint_t glyph) const
{
if (this == &Null(FDSelect))
if (this == &Null (FDSelect))
return 0;
if (format == 0)
return u.format0.get_fd (glyph);
else
return u.format3.get_fd (glyph);
switch (format)
{
case 0: return u.format0.get_fd (glyph);
case 3: return u.format3.get_fd (glyph);
default:return 0;
}
}
HBUINT8 format;
union {
FDSelect0 format0;
FDSelect3 format3;
} u;
bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
{
TRACE_SANITIZE (this);
if (unlikely (!c->check_struct (this)))
return_trace (false);
switch (format)
{
case 0: return_trace (u.format0.sanitize (c, fdcount));
case 3: return_trace (u.format3.sanitize (c, fdcount));
default:return_trace (false);
}
}
HBUINT8 format;
union {
FDSelect0 format0;
FDSelect3 format3;
} u;
public:
DEFINE_SIZE_MIN (1);
};

View File

@ -24,11 +24,13 @@
* Adobe Author(s): Michiharu Ariza
*/
#include "hb-ot-cff1-table.hh"
#include "hb-cff1-interp-cs.hh"
#include "hb.hh"
#ifndef HB_NO_CFF
#include "hb-ot-cff1-table.hh"
#include "hb-cff1-interp-cs.hh"
using namespace CFF;
/* SID to code */
@ -391,4 +393,5 @@ bool OT::cff1::accelerator_t::get_seac_components (hb_codepoint_t glyph, hb_code
return false;
}
#endif

View File

@ -161,21 +161,8 @@ struct CFF1SuppEncData {
DEFINE_SIZE_ARRAY_SIZED (1, supps);
};
struct Encoding {
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (unlikely (!c->check_struct (this)))
return_trace (false);
unsigned int fmt = format & 0x7F;
if (unlikely (fmt > 1))
return_trace (false);
if (unlikely (!((fmt == 0)? u.format0.sanitize (c): u.format1.sanitize (c))))
return_trace (false);
return_trace (((format & 0x80) == 0) || suppEncData ().sanitize (c));
}
struct Encoding
{
/* serialize a fullset Encoding */
bool serialize (hb_serialize_context_t *c, const Encoding &src)
{
@ -197,11 +184,12 @@ struct Encoding {
TRACE_SERIALIZE (this);
Encoding *dest = c->extend_min (*this);
if (unlikely (dest == nullptr)) return_trace (false);
dest->format = format | ((supp_codes.length > 0)? 0x80: 0);
if (format == 0)
dest->format = format | ((supp_codes.length > 0) ? 0x80 : 0);
switch (format) {
case 0:
{
Encoding0 *fmt0 = c->allocate_size<Encoding0> (Encoding0::min_size + HBUINT8::static_size * enc_count);
if (unlikely (fmt0 == nullptr)) return_trace (false);
if (unlikely (fmt0 == nullptr)) return_trace (false);
fmt0->nCodes () = enc_count;
unsigned int glyph = 0;
for (unsigned int i = 0; i < code_ranges.length; i++)
@ -213,7 +201,9 @@ struct Encoding {
return_trace (false);
}
}
else
break;
case 1:
{
Encoding1 *fmt1 = c->allocate_size<Encoding1> (Encoding1::min_size + Encoding1_Range::static_size * code_ranges.length);
if (unlikely (fmt1 == nullptr)) return_trace (false);
@ -226,7 +216,11 @@ struct Encoding {
fmt1->ranges[i].nLeft = code_ranges[i].glyph;
}
}
if (supp_codes.length > 0)
break;
}
if (supp_codes.length)
{
CFF1SuppEncData *suppData = c->allocate_size<CFF1SuppEncData> (CFF1SuppEncData::min_size + SuppEncoding::static_size * supp_codes.length);
if (unlikely (suppData == nullptr)) return_trace (false);
@ -237,6 +231,7 @@ struct Encoding {
suppData->supps[i].glyph = supp_codes[i].glyph; /* actually SID */
}
}
return_trace (true);
}
@ -245,11 +240,13 @@ struct Encoding {
unsigned int enc_count,
unsigned int supp_count)
{
unsigned int size = min_size;
if (format == 0)
size += Encoding0::min_size + HBUINT8::static_size * enc_count;
else
size += Encoding1::min_size + Encoding1_Range::static_size * enc_count;
unsigned int size = min_size;
switch (format)
{
case 0: size += Encoding0::min_size + HBUINT8::static_size * enc_count; break;
case 1: size += Encoding1::min_size + Encoding1_Range::static_size * enc_count; break;
default:return 0;
}
if (supp_count > 0)
size += CFF1SuppEncData::min_size + SuppEncoding::static_size * supp_count;
return size;
@ -258,10 +255,11 @@ struct Encoding {
unsigned int get_size () const
{
unsigned int size = min_size;
if (table_format () == 0)
size += u.format0.get_size ();
else
size += u.format1.get_size ();
switch (table_format ())
{
case 0: size += u.format0.get_size (); break;
case 1: size += u.format1.get_size (); break;
}
if (has_supplement ())
size += suppEncData ().get_size ();
return size;
@ -269,14 +267,16 @@ struct Encoding {
hb_codepoint_t get_code (hb_codepoint_t glyph) const
{
if (table_format () == 0)
return u.format0.get_code (glyph);
else
return u.format1.get_code (glyph);
switch (table_format ())
{
case 0: return u.format0.get_code (glyph);
case 1: return u.format1.get_code (glyph);
default:return 0;
}
}
uint8_t table_format () const { return (format & 0x7F); }
bool has_supplement () const { return (format & 0x80) != 0; }
uint8_t table_format () const { return format & 0x7F; }
bool has_supplement () const { return format & 0x80; }
void get_supplement_codes (hb_codepoint_t sid, hb_vector_t<hb_codepoint_t> &codes) const
{
@ -285,21 +285,37 @@ struct Encoding {
suppEncData().get_codes (sid, codes);
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (unlikely (!c->check_struct (this)))
return_trace (false);
switch (table_format ())
{
case 0: if (unlikely (!u.format0.sanitize (c))) { return_trace (false); } break;
case 1: if (unlikely (!u.format1.sanitize (c))) { return_trace (false); } break;
default:return_trace (false);
}
return_trace (likely (!has_supplement () || suppEncData ().sanitize (c)));
}
protected:
const CFF1SuppEncData &suppEncData () const
{
if ((format & 0x7F) == 0)
return StructAfter<CFF1SuppEncData> (u.format0.codes[u.format0.nCodes ()-1]);
else
return StructAfter<CFF1SuppEncData> (u.format1.ranges[u.format1.nRanges ()-1]);
switch (table_format ())
{
case 0: return StructAfter<CFF1SuppEncData> (u.format0.codes[u.format0.nCodes ()-1]);
case 1: return StructAfter<CFF1SuppEncData> (u.format1.ranges[u.format1.nRanges ()-1]);
default:return Null (CFF1SuppEncData);
}
}
public:
HBUINT8 format;
HBUINT8 format;
union {
Encoding0 format0;
Encoding1 format1;
Encoding0 format0;
Encoding1 format1;
} u;
/* CFF1SuppEncData suppEncData; */
@ -433,23 +449,8 @@ typedef Charset1_2<HBUINT16> Charset2;
typedef Charset_Range<HBUINT8> Charset1_Range;
typedef Charset_Range<HBUINT16> Charset2_Range;
struct Charset {
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (unlikely (!c->check_struct (this)))
return_trace (false);
if (format == 0)
return_trace (u.format0.sanitize (c, c->get_num_glyphs ()));
else if (format == 1)
return_trace (u.format1.sanitize (c, c->get_num_glyphs ()));
else if (likely (format == 2))
return_trace (u.format2.sanitize (c, c->get_num_glyphs ()));
else
return_trace (false);
}
struct Charset
{
/* serialize a fullset Charset */
bool serialize (hb_serialize_context_t *c, const Charset &src, unsigned int num_glyphs)
{
@ -471,10 +472,12 @@ struct Charset {
Charset *dest = c->extend_min (*this);
if (unlikely (dest == nullptr)) return_trace (false);
dest->format = format;
if (format == 0)
switch (format)
{
case 0:
{
Charset0 *fmt0 = c->allocate_size<Charset0> (Charset0::min_size + HBUINT16::static_size * (num_glyphs - 1));
if (unlikely (fmt0 == nullptr)) return_trace (false);
if (unlikely (fmt0 == nullptr)) return_trace (false);
unsigned int glyph = 0;
for (unsigned int i = 0; i < sid_ranges.length; i++)
{
@ -483,7 +486,9 @@ struct Charset {
fmt0->sids[glyph++] = sid++;
}
}
else if (format == 1)
break;
case 1:
{
Charset1 *fmt1 = c->allocate_size<Charset1> (Charset1::min_size + Charset1_Range::static_size * sid_ranges.length);
if (unlikely (fmt1 == nullptr)) return_trace (false);
@ -495,7 +500,9 @@ struct Charset {
fmt1->ranges[i].nLeft = sid_ranges[i].glyph;
}
}
else /* format 2 */
break;
case 2:
{
Charset2 *fmt2 = c->allocate_size<Charset2> (Charset2::min_size + Charset2_Range::static_size * sid_ranges.length);
if (unlikely (fmt2 == nullptr)) return_trace (false);
@ -506,56 +513,72 @@ struct Charset {
fmt2->ranges[i].first = sid_ranges[i].code;
fmt2->ranges[i].nLeft = sid_ranges[i].glyph;
}
}
break;
}
return_trace (true);
}
/* parallel to above: calculate the size of a subset Charset */
static unsigned int calculate_serialized_size (
uint8_t format,
unsigned int count)
static unsigned int calculate_serialized_size (uint8_t format,
unsigned int count)
{
unsigned int size = min_size;
if (format == 0)
size += Charset0::min_size + HBUINT16::static_size * (count - 1);
else if (format == 1)
size += Charset1::min_size + Charset1_Range::static_size * count;
else
size += Charset2::min_size + Charset2_Range::static_size * count;
return size;
switch (format)
{
case 0: return min_size + Charset0::min_size + HBUINT16::static_size * (count - 1);
case 1: return min_size + Charset1::min_size + Charset1_Range::static_size * count;
case 2: return min_size + Charset2::min_size + Charset2_Range::static_size * count;
default:return 0;
}
}
unsigned int get_size (unsigned int num_glyphs) const
{
unsigned int size = min_size;
if (format == 0)
size += u.format0.get_size (num_glyphs);
else if (format == 1)
size += u.format1.get_size (num_glyphs);
else
size += u.format2.get_size (num_glyphs);
return size;
switch (format)
{
case 0: return min_size + u.format0.get_size (num_glyphs);
case 1: return min_size + u.format1.get_size (num_glyphs);
case 2: return min_size + u.format2.get_size (num_glyphs);
default:return 0;
}
}
hb_codepoint_t get_sid (hb_codepoint_t glyph) const
{
if (format == 0)
return u.format0.get_sid (glyph);
else if (format == 1)
return u.format1.get_sid (glyph);
else
return u.format2.get_sid (glyph);
switch (format)
{
case 0: return u.format0.get_sid (glyph);
case 1: return u.format1.get_sid (glyph);
case 2: return u.format2.get_sid (glyph);
default:return 0;
}
}
hb_codepoint_t get_glyph (hb_codepoint_t sid, unsigned int num_glyphs) const
{
if (format == 0)
return u.format0.get_glyph (sid, num_glyphs);
else if (format == 1)
return u.format1.get_glyph (sid, num_glyphs);
else
return u.format2.get_glyph (sid, num_glyphs);
switch (format)
{
case 0: return u.format0.get_glyph (sid, num_glyphs);
case 1: return u.format1.get_glyph (sid, num_glyphs);
case 2: return u.format2.get_glyph (sid, num_glyphs);
default:return 0;
}
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (unlikely (!c->check_struct (this)))
return_trace (false);
switch (format)
{
case 0: return_trace (u.format0.sanitize (c, c->get_num_glyphs ()));
case 1: return_trace (u.format1.sanitize (c, c->get_num_glyphs ()));
case 2: return_trace (u.format2.sanitize (c, c->get_num_glyphs ()));
default:return_trace (false);
}
}
HBUINT8 format;
@ -571,10 +594,10 @@ struct Charset {
struct CFF1StringIndex : CFF1Index
{
bool serialize (hb_serialize_context_t *c, const CFF1StringIndex &strings,
unsigned int offSize_, const remap_t &sidmap)
unsigned int offSize_, const hb_inc_bimap_t &sidmap)
{
TRACE_SERIALIZE (this);
if (unlikely ((strings.count == 0) || (sidmap.get_count () == 0)))
if (unlikely ((strings.count == 0) || (sidmap.get_population () == 0)))
{
if (unlikely (!c->extend_min (this->count)))
return_trace (false);
@ -584,7 +607,7 @@ struct CFF1StringIndex : CFF1Index
byte_str_array_t bytesArray;
bytesArray.init ();
if (!bytesArray.resize (sidmap.get_count ()))
if (!bytesArray.resize (sidmap.get_population ()))
return_trace (false);
for (unsigned int i = 0; i < strings.count; i++)
{
@ -599,10 +622,10 @@ struct CFF1StringIndex : CFF1Index
}
/* in parallel to above */
unsigned int calculate_serialized_size (unsigned int &offSize_ /*OUT*/, const remap_t &sidmap) const
unsigned int calculate_serialized_size (unsigned int &offSize_ /*OUT*/, const hb_inc_bimap_t &sidmap) const
{
offSize_ = 0;
if ((count == 0) || (sidmap.get_count () == 0))
if ((count == 0) || (sidmap.get_population () == 0))
return count.static_size;
unsigned int dataSize = 0;
@ -611,7 +634,7 @@ struct CFF1StringIndex : CFF1Index
dataSize += length_at (i);
offSize_ = calcOffSize(dataSize);
return CFF1Index::calculate_serialized_size (offSize_, sidmap.get_count (), dataSize);
return CFF1Index::calculate_serialized_size (offSize_, sidmap.get_population (), dataSize);
}
};

View File

@ -24,11 +24,13 @@
* Adobe Author(s): Michiharu Ariza
*/
#include "hb-ot-cff2-table.hh"
#include "hb-cff2-interp-cs.hh"
#include "hb.hh"
#ifndef HB_NO_OT_FONT_CFF
#include "hb-ot-cff2-table.hh"
#include "hb-cff2-interp-cs.hh"
using namespace CFF;
struct extents_param_t
@ -142,4 +144,5 @@ bool OT::cff2::accelerator_t::get_extents (hb_font_t *font,
return true;
}
#endif

View File

@ -51,18 +51,6 @@ typedef FDSelect3_4_Range<HBUINT32, HBUINT16> FDSelect4_Range;
struct CFF2FDSelect
{
bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
{
TRACE_SANITIZE (this);
return_trace (likely (c->check_struct (this) && (format == 0 || format == 3 || format == 4) &&
(format == 0)?
u.format0.sanitize (c, fdcount):
((format == 3)?
u.format3.sanitize (c, fdcount):
u.format4.sanitize (c, fdcount))));
}
bool serialize (hb_serialize_context_t *c, const CFF2FDSelect &src, unsigned int num_glyphs)
{
TRACE_SERIALIZE (this);
@ -78,35 +66,51 @@ struct CFF2FDSelect
unsigned int get_size (unsigned int num_glyphs) const
{
unsigned int size = format.static_size;
if (format == 0)
size += u.format0.get_size (num_glyphs);
else if (format == 3)
size += u.format3.get_size ();
else
size += u.format4.get_size ();
return size;
switch (format)
{
case 0: return format.static_size + u.format0.get_size (num_glyphs);
case 3: return format.static_size + u.format3.get_size ();
case 4: return format.static_size + u.format4.get_size ();
default:return 0;
}
}
hb_codepoint_t get_fd (hb_codepoint_t glyph) const
{
if (this == &Null(CFF2FDSelect))
if (this == &Null (CFF2FDSelect))
return 0;
if (format == 0)
return u.format0.get_fd (glyph);
else if (format == 3)
return u.format3.get_fd (glyph);
else
return u.format4.get_fd (glyph);
switch (format)
{
case 0: return u.format0.get_fd (glyph);
case 3: return u.format3.get_fd (glyph);
case 4: return u.format4.get_fd (glyph);
default:return 0;
}
}
HBUINT8 format;
union {
FDSelect0 format0;
FDSelect3 format3;
FDSelect4 format4;
} u;
bool sanitize (hb_sanitize_context_t *c, unsigned int fdcount) const
{
TRACE_SANITIZE (this);
if (unlikely (!c->check_struct (this)))
return_trace (false);
switch (format)
{
case 0: return_trace (u.format0.sanitize (c, fdcount));
case 3: return_trace (u.format3.sanitize (c, fdcount));
case 4: return_trace (u.format4.sanitize (c, fdcount));
default:return_trace (false);
}
}
HBUINT8 format;
union {
FDSelect0 format0;
FDSelect3 format3;
FDSelect4 format4;
} u;
public:
DEFINE_SIZE_MIN (2);
};

View File

@ -756,10 +756,12 @@ struct CmapSubtable
hb_codepoint_t *glyph) const
{
switch (u.format) {
#ifndef HB_NO_CMAP_LEGACY_SUBTABLES
case 0: return u.format0 .get_glyph (codepoint, glyph);
case 4: return u.format4 .get_glyph (codepoint, glyph);
case 6: return u.format6 .get_glyph (codepoint, glyph);
case 10: return u.format10.get_glyph (codepoint, glyph);
#endif
case 4: return u.format4 .get_glyph (codepoint, glyph);
case 12: return u.format12.get_glyph (codepoint, glyph);
case 13: return u.format13.get_glyph (codepoint, glyph);
case 14:
@ -769,10 +771,12 @@ struct CmapSubtable
void collect_unicodes (hb_set_t *out) const
{
switch (u.format) {
#ifndef HB_NO_CMAP_LEGACY_SUBTABLES
case 0: u.format0 .collect_unicodes (out); return;
case 4: u.format4 .collect_unicodes (out); return;
case 6: u.format6 .collect_unicodes (out); return;
case 10: u.format10.collect_unicodes (out); return;
#endif
case 4: u.format4 .collect_unicodes (out); return;
case 12: u.format12.collect_unicodes (out); return;
case 13: u.format13.collect_unicodes (out); return;
case 14:
@ -785,10 +789,12 @@ struct CmapSubtable
TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return_trace (false);
switch (u.format) {
#ifndef HB_NO_CMAP_LEGACY_SUBTABLES
case 0: return_trace (u.format0 .sanitize (c));
case 4: return_trace (u.format4 .sanitize (c));
case 6: return_trace (u.format6 .sanitize (c));
case 10: return_trace (u.format10.sanitize (c));
#endif
case 4: return_trace (u.format4 .sanitize (c));
case 12: return_trace (u.format12.sanitize (c));
case 13: return_trace (u.format13.sanitize (c));
case 14: return_trace (u.format14.sanitize (c));
@ -799,10 +805,12 @@ struct CmapSubtable
public:
union {
HBUINT16 format; /* Format identifier */
#ifndef HB_NO_CMAP_LEGACY_SUBTABLES
CmapSubtableFormat0 format0;
CmapSubtableFormat4 format4;
CmapSubtableFormat6 format6;
CmapSubtableFormat10 format10;
#endif
CmapSubtableFormat4 format4;
CmapSubtableFormat12 format12;
CmapSubtableFormat13 format13;
CmapSubtableFormat14 format14;
@ -848,11 +856,16 @@ struct cmap
size_t final_size () const
{
return 4 // header
+ 8 * 3 // 3 EncodingRecord
+ 8 * num_enc_records
+ CmapSubtableFormat4::get_sub_table_size (this->format4_segments)
+ CmapSubtableFormat12::get_sub_table_size (this->format12_groups);
}
unsigned int num_enc_records;
bool has_unicode_bmp;
bool has_unicode_ucs4;
bool has_ms_bmp;
bool has_ms_ucs4;
hb_sorted_vector_t<CmapSubtableFormat4::segment_plan> format4_segments;
hb_sorted_vector_t<CmapSubtableLongGroup> format12_groups;
};
@ -860,6 +873,12 @@ struct cmap
bool _create_plan (const hb_subset_plan_t *plan,
subset_plan *cmap_plan) const
{
cmap_plan->has_unicode_bmp = find_subtable (0, 3);
cmap_plan->has_unicode_ucs4 = find_subtable (0, 4);
cmap_plan->has_ms_bmp = find_subtable (3, 1);
cmap_plan->has_ms_ucs4 = find_subtable (3, 10);
cmap_plan->num_enc_records = cmap_plan->has_unicode_bmp + cmap_plan->has_unicode_ucs4 + cmap_plan->has_ms_bmp + cmap_plan->has_ms_ucs4;
if (unlikely (!CmapSubtableFormat4::create_sub_table_plan (plan, &cmap_plan->format4_segments)))
return false;
@ -882,32 +901,60 @@ struct cmap
table->version = 0;
if (unlikely (!table->encodingRecord.serialize (&c, /* numTables */ cmap_subset_plan.format12_groups ? 3 : 2))) return false;
if (unlikely (!table->encodingRecord.serialize (&c, cmap_subset_plan.num_enc_records))) return false;
// TODO(grieger): Convert the below to a for loop
int enc_index = 0;
int unicode_bmp_index = 0;
int unicode_ucs4_index = 0;
int ms_bmp_index = 0;
int ms_ucs4_index = 0;
// Format 4, Plat 0 Encoding Record
EncodingRecord &format4_plat0_rec = table->encodingRecord[0];
format4_plat0_rec.platformID = 0; // Unicode
format4_plat0_rec.encodingID = 3;
if (cmap_subset_plan.has_unicode_bmp)
{
unicode_bmp_index = enc_index;
EncodingRecord &format4_plat0_rec = table->encodingRecord[enc_index++];
format4_plat0_rec.platformID = 0; // Unicode
format4_plat0_rec.encodingID = 3;
}
// Format 12, Plat 0 Encoding Record
if (cmap_subset_plan.has_unicode_ucs4)
{
unicode_ucs4_index = enc_index;
EncodingRecord &format12_rec = table->encodingRecord[enc_index++];
format12_rec.platformID = 0; // Unicode
format12_rec.encodingID = 4; // Unicode UCS-4
}
// Format 4, Plat 3 Encoding Record
EncodingRecord &format4_plat3_rec = table->encodingRecord[1];
format4_plat3_rec.platformID = 3; // Windows
format4_plat3_rec.encodingID = 1; // Unicode BMP
// Format 12 Encoding Record
if (cmap_subset_plan.format12_groups)
if (cmap_subset_plan.has_ms_bmp)
{
EncodingRecord &format12_rec = table->encodingRecord[2];
ms_bmp_index = enc_index;
EncodingRecord &format4_plat3_rec = table->encodingRecord[enc_index++];
format4_plat3_rec.platformID = 3; // Windows
format4_plat3_rec.encodingID = 1; // Unicode BMP
}
// Format 12, Plat 3 Encoding Record
if (cmap_subset_plan.has_ms_ucs4)
{
ms_ucs4_index = enc_index;
EncodingRecord &format12_rec = table->encodingRecord[enc_index++];
format12_rec.platformID = 3; // Windows
format12_rec.encodingID = 10; // Unicode UCS-4
}
// Write out format 4 sub table
{
CmapSubtable &subtable = format4_plat0_rec.subtable.serialize (&c, table);
format4_plat3_rec.subtable = (unsigned int) format4_plat0_rec.subtable;
if (unlikely (!cmap_subset_plan.has_unicode_bmp && !cmap_subset_plan.has_ms_bmp)) return false;
EncodingRecord &format4_rec = cmap_subset_plan.has_unicode_bmp?
table->encodingRecord[unicode_bmp_index]:
table->encodingRecord[ms_bmp_index];
CmapSubtable &subtable = format4_rec.subtable.serialize (&c, table);
if (cmap_subset_plan.has_unicode_bmp && cmap_subset_plan.has_ms_bmp)
table->encodingRecord[ms_bmp_index].subtable = (unsigned int) format4_rec.subtable;
subtable.u.format = 4;
CmapSubtableFormat4 &format4 = subtable.u.format4;
@ -918,8 +965,14 @@ struct cmap
// Write out format 12 sub table.
if (cmap_subset_plan.format12_groups)
{
EncodingRecord &format12_rec = table->encodingRecord[2];
if (unlikely (!cmap_subset_plan.has_unicode_ucs4 && !cmap_subset_plan.has_ms_ucs4)) return false;
EncodingRecord &format12_rec = cmap_subset_plan.has_unicode_ucs4?
table->encodingRecord[unicode_ucs4_index]:
table->encodingRecord[ms_ucs4_index];
CmapSubtable &subtable = format12_rec.subtable.serialize (&c, table);
if (cmap_subset_plan.has_unicode_ucs4 && cmap_subset_plan.has_ms_ucs4)
table->encodingRecord[ms_ucs4_index].subtable = (unsigned int) format12_rec.subtable;
subtable.u.format = 12;
CmapSubtableFormat12 &format12 = subtable.u.format12;

View File

@ -25,20 +25,21 @@
* Google Author(s): Sascha Brawer, Behdad Esfahbod
*/
#include "hb-open-type.hh"
#include "hb.hh"
#ifndef HB_NO_COLOR
#include "hb-ot.h"
#include "hb-ot-color-cbdt-table.hh"
#include "hb-ot-color-colr-table.hh"
#include "hb-ot-color-cpal-table.hh"
#include "hb-ot-color-sbix-table.hh"
#include "hb-ot-color-svg-table.hh"
#include "hb-ot-face.hh"
#include "hb-ot.h"
#include <stdlib.h>
#include <string.h>
#include "hb-ot-layout.hh"
/**
* SECTION:hb-ot-color
@ -70,9 +71,6 @@
hb_bool_t
hb_ot_color_has_palettes (hb_face_t *face)
{
#ifdef HB_NO_COLOR
return false;
#endif
return face->table.CPAL->has_data ();
}
@ -89,9 +87,6 @@ hb_ot_color_has_palettes (hb_face_t *face)
unsigned int
hb_ot_color_palette_get_count (hb_face_t *face)
{
#ifdef HB_NO_COLOR
return 0;
#endif
return face->table.CPAL->get_palette_count ();
}
@ -115,9 +110,6 @@ hb_ot_name_id_t
hb_ot_color_palette_get_name_id (hb_face_t *face,
unsigned int palette_index)
{
#ifdef HB_NO_COLOR
return HB_OT_NAME_ID_INVALID;
#endif
return face->table.CPAL->get_palette_name_id (palette_index);
}
@ -140,9 +132,6 @@ hb_ot_name_id_t
hb_ot_color_palette_color_get_name_id (hb_face_t *face,
unsigned int color_index)
{
#ifdef HB_NO_COLOR
return HB_OT_NAME_ID_INVALID;
#endif
return face->table.CPAL->get_color_name_id (color_index);
}
@ -161,9 +150,6 @@ hb_ot_color_palette_flags_t
hb_ot_color_palette_get_flags (hb_face_t *face,
unsigned int palette_index)
{
#ifdef HB_NO_COLOR
return HB_OT_COLOR_PALETTE_FLAG_DEFAULT;
#endif
return face->table.CPAL->get_palette_flags (palette_index);
}
@ -195,11 +181,6 @@ hb_ot_color_palette_get_colors (hb_face_t *face,
unsigned int *colors_count /* IN/OUT. May be NULL. */,
hb_color_t *colors /* OUT. May be NULL. */)
{
#ifdef HB_NO_COLOR
if (colors_count)
*colors_count = 0;
return 0;
#endif
return face->table.CPAL->get_palette_colors (palette_index, start_offset, colors_count, colors);
}
@ -221,9 +202,6 @@ hb_ot_color_palette_get_colors (hb_face_t *face,
hb_bool_t
hb_ot_color_has_layers (hb_face_t *face)
{
#ifdef HB_NO_COLOR
return false;
#endif
return face->table.COLR->has_data ();
}
@ -250,11 +228,6 @@ hb_ot_color_glyph_get_layers (hb_face_t *face,
unsigned int *layer_count, /* IN/OUT. May be NULL. */
hb_ot_color_layer_t *layers /* OUT. May be NULL. */)
{
#ifdef HB_NO_COLOR
if (layer_count)
*layer_count = 0;
return 0;
#endif
return face->table.COLR->get_glyph_layers (glyph, start_offset, layer_count, layers);
}
@ -276,9 +249,6 @@ hb_ot_color_glyph_get_layers (hb_face_t *face,
hb_bool_t
hb_ot_color_has_svg (hb_face_t *face)
{
#ifdef HB_NO_COLOR
return false;
#endif
return face->table.SVG->has_data ();
}
@ -296,9 +266,6 @@ hb_ot_color_has_svg (hb_face_t *face)
hb_blob_t *
hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph)
{
#ifdef HB_NO_COLOR
return hb_blob_get_empty ();
#endif
return face->table.SVG->reference_blob_for_glyph (glyph);
}
@ -320,9 +287,6 @@ hb_ot_color_glyph_reference_svg (hb_face_t *face, hb_codepoint_t glyph)
hb_bool_t
hb_ot_color_has_png (hb_face_t *face)
{
#ifdef HB_NO_COLOR
return false;
#endif
return face->table.CBDT->has_data () || face->table.sbix->has_data ();
}
@ -342,10 +306,6 @@ hb_ot_color_has_png (hb_face_t *face)
hb_blob_t *
hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph)
{
#ifdef HB_NO_COLOR
return hb_blob_get_empty ();
#endif
hb_blob_t *blob = hb_blob_get_empty ();
if (font->face->table.sbix->has_data ())
@ -356,3 +316,6 @@ hb_ot_color_glyph_reference_png (hb_font_t *font, hb_codepoint_t glyph)
return blob;
}
#endif

View File

@ -0,0 +1,126 @@
/*
* Copyright © 2007,2008,2009 Red Hat, Inc.
* Copyright © 2012,2013 Google, Inc.
* Copyright © 2019, Facebook Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
* Permission is hereby granted, without written agreement and without
* license or royalty fees, to use, copy, modify, and distribute this
* software and its documentation for any purpose, provided that the
* above copyright notice and the following two paragraphs appear in
* all copies of this software.
*
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Red Hat Author(s): Behdad Esfahbod
* Google Author(s): Behdad Esfahbod
* Facebook Author(s): Behdad Esfahbod
*/
#ifndef HB_OT_FACE_TABLE_LIST_HH
#define HB_OT_FACE_TABLE_LIST_HH
#endif /* HB_OT_FACE_TABLE_LIST_HH */ /* Dummy header guards */
#ifndef HB_OT_ACCELERATOR
#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type)
#define _HB_OT_ACCELERATOR_UNDEF
#endif
/* This lists font tables that the hb_face_t will contain and lazily
* load. Don't add a table unless it's used though. This is not
* exactly free. */
/* v--- Add new tables in the right place here. */
/* OpenType fundamentals. */
HB_OT_TABLE (OT, head)
#if !defined(HB_NO_FACE_COLLECT_UNICODES) || !defined(HB_NO_OT_FONT)
HB_OT_ACCELERATOR (OT, cmap)
#endif
HB_OT_ACCELERATOR (OT, hmtx)
HB_OT_TABLE (OT, OS2)
#ifndef HB_NO_OT_FONT_GLYPH_NAMES
HB_OT_ACCELERATOR (OT, post)
#endif
#ifndef HB_NO_NAME
HB_OT_ACCELERATOR (OT, name)
#endif
#ifndef HB_NO_STAT
HB_OT_TABLE (OT, STAT)
#endif
/* Vertical layout. */
HB_OT_ACCELERATOR (OT, vmtx)
/* TrueType outlines. */
HB_OT_ACCELERATOR (OT, glyf)
/* CFF outlines. */
#ifndef HB_NO_CFF
HB_OT_ACCELERATOR (OT, cff1)
HB_OT_ACCELERATOR (OT, cff2)
HB_OT_TABLE (OT, VORG)
#endif
/* OpenType variations. */
#ifndef HB_NO_VAR
HB_OT_TABLE (OT, fvar)
HB_OT_TABLE (OT, avar)
HB_OT_TABLE (OT, MVAR)
#endif
/* Legacy kern. */
#ifndef HB_NO_OT_KERN
HB_OT_TABLE (OT, kern)
#endif
/* OpenType shaping. */
HB_OT_ACCELERATOR (OT, GDEF)
HB_OT_ACCELERATOR (OT, GSUB)
HB_OT_ACCELERATOR (OT, GPOS)
//HB_OT_TABLE (OT, BASE)
//HB_OT_TABLE (OT, JSTF)
/* AAT shaping. */
#ifndef HB_NO_AAT
HB_OT_TABLE (AAT, morx)
HB_OT_TABLE (AAT, mort)
HB_OT_TABLE (AAT, kerx)
HB_OT_TABLE (AAT, ankr)
HB_OT_TABLE (AAT, trak)
HB_OT_TABLE (AAT, lcar)
HB_OT_TABLE (AAT, ltag)
HB_OT_TABLE (AAT, feat)
#endif
/* OpenType color fonts. */
#ifndef HB_NO_COLOR
HB_OT_TABLE (OT, COLR)
HB_OT_TABLE (OT, CPAL)
HB_OT_ACCELERATOR (OT, CBDT)
HB_OT_ACCELERATOR (OT, sbix)
HB_OT_ACCELERATOR (OT, SVG)
#endif
/* OpenType math. */
#ifndef HB_NO_MATH
HB_OT_TABLE (OT, MATH)
#endif
#ifdef _HB_OT_ACCELERATOR_UNDEF
#undef HB_OT_ACCELERATOR
#endif

View File

@ -46,16 +46,12 @@ void hb_ot_face_t::init0 (hb_face_t *face)
{
this->face = face;
#define HB_OT_TABLE(Namespace, Type) Type.init0 ();
#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type)
HB_OT_TABLES
#undef HB_OT_ACCELERATOR
#include "hb-ot-face-table-list.hh"
#undef HB_OT_TABLE
}
void hb_ot_face_t::fini ()
{
#define HB_OT_TABLE(Namespace, Type) Type.fini ();
#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type)
HB_OT_TABLES
#undef HB_OT_ACCELERATOR
#include "hb-ot-face-table-list.hh"
#undef HB_OT_TABLE
}

View File

@ -38,54 +38,10 @@
* hb_ot_face_t
*/
#define HB_OT_TABLES \
/* OpenType fundamentals. */ \
HB_OT_TABLE(OT, head) \
HB_OT_ACCELERATOR(OT, cmap) \
HB_OT_ACCELERATOR(OT, hmtx) \
HB_OT_ACCELERATOR(OT, vmtx) \
HB_OT_ACCELERATOR(OT, post) \
HB_OT_TABLE(OT, kern) \
HB_OT_ACCELERATOR(OT, glyf) \
HB_OT_ACCELERATOR(OT, cff1) \
HB_OT_ACCELERATOR(OT, cff2) \
HB_OT_TABLE(OT, VORG) \
HB_OT_ACCELERATOR(OT, name) \
HB_OT_TABLE(OT, OS2) \
HB_OT_TABLE(OT, STAT) \
/* OpenType shaping. */ \
HB_OT_ACCELERATOR(OT, GDEF) \
HB_OT_ACCELERATOR(OT, GSUB) \
HB_OT_ACCELERATOR(OT, GPOS) \
HB_OT_TABLE(OT, BASE) \
HB_OT_TABLE(OT, JSTF) \
/* AAT shaping. */ \
HB_OT_TABLE(AAT, mort) \
HB_OT_TABLE(AAT, morx) \
HB_OT_TABLE(AAT, kerx) \
HB_OT_TABLE(AAT, ankr) \
HB_OT_TABLE(AAT, trak) \
HB_OT_TABLE(AAT, lcar) \
HB_OT_TABLE(AAT, ltag) \
HB_OT_TABLE(AAT, feat) \
/* OpenType variations. */ \
HB_OT_TABLE(OT, fvar) \
HB_OT_TABLE(OT, avar) \
HB_OT_TABLE(OT, MVAR) \
/* OpenType math. */ \
HB_OT_TABLE(OT, MATH) \
/* OpenType color fonts. */ \
HB_OT_TABLE(OT, COLR) \
HB_OT_TABLE(OT, CPAL) \
HB_OT_ACCELERATOR(OT, CBDT) \
HB_OT_ACCELERATOR(OT, sbix) \
HB_OT_ACCELERATOR(OT, SVG) \
/* */
/* Declare tables. */
#define HB_OT_TABLE(Namespace, Type) namespace Namespace { struct Type; }
#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type##_accelerator_t)
HB_OT_TABLES
#include "hb-ot-face-table-list.hh"
#undef HB_OT_ACCELERATOR
#undef HB_OT_TABLE
@ -100,9 +56,7 @@ struct hb_ot_face_t
{
ORDER_ZERO,
#define HB_OT_TABLE(Namespace, Type) HB_OT_TABLE_ORDER (Namespace, Type),
#define HB_OT_ACCELERATOR(Namespace, Type) HB_OT_TABLE (Namespace, Type)
HB_OT_TABLES
#undef HB_OT_ACCELERATOR
#include "hb-ot-face-table-list.hh"
#undef HB_OT_TABLE
};
@ -111,7 +65,7 @@ struct hb_ot_face_t
hb_table_lazy_loader_t<Namespace::Type, HB_OT_TABLE_ORDER (Namespace, Type)> Type;
#define HB_OT_ACCELERATOR(Namespace, Type) \
hb_face_lazy_loader_t<Namespace::Type##_accelerator_t, HB_OT_TABLE_ORDER (Namespace, Type)> Type;
HB_OT_TABLES
#include "hb-ot-face-table-list.hh"
#undef HB_OT_ACCELERATOR
#undef HB_OT_TABLE
};

View File

@ -26,6 +26,8 @@
#include "hb.hh"
#ifndef HB_NO_OT_FONT
#include "hb-ot.h"
#include "hb-font.hh"
@ -37,7 +39,6 @@
#include "hb-ot-cff1-table.hh"
#include "hb-ot-cff2-table.hh"
#include "hb-ot-hmtx-table.hh"
#include "hb-ot-kern-table.hh"
#include "hb-ot-os2-table.hh"
#include "hb-ot-post-table.hh"
#include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise.
@ -149,12 +150,14 @@ hb_ot_get_glyph_v_origin (hb_font_t *font,
*x = font->get_glyph_h_advance (glyph) / 2;
#ifndef HB_NO_OT_FONT_CFF
const OT::VORG &VORG = *ot_face->VORG;
if (VORG.has_data ())
{
*y = font->em_scale_y (VORG.get_y_origin (glyph));
return true;
}
#endif
hb_glyph_extents_t extents = {0};
if (ot_face->glyf->get_extents (glyph, &extents))
@ -202,6 +205,7 @@ hb_ot_get_glyph_extents (hb_font_t *font,
return ret;
}
#ifndef HB_NO_OT_FONT_GLYPH_NAMES
static hb_bool_t
hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED,
void *font_data,
@ -212,7 +216,6 @@ hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED,
const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
return ot_face->post->get_glyph_name (glyph, name, size);
}
static hb_bool_t
hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED,
void *font_data,
@ -223,6 +226,7 @@ hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED,
const hb_ot_face_t *ot_face = (const hb_ot_face_t *) font_data;
return ot_face->post->get_glyph_from_name (name, len, glyph);
}
#endif
static hb_bool_t
hb_ot_get_font_h_extents (hb_font_t *font,
@ -275,8 +279,10 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot
hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, 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);
#ifndef HB_NO_OT_FONT_GLYPH_NAMES
hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr);
hb_font_funcs_set_glyph_from_name_func (funcs, hb_ot_get_glyph_from_name, nullptr, nullptr);
#endif
hb_font_funcs_make_immutable (funcs);
@ -316,3 +322,6 @@ hb_ot_font_set_funcs (hb_font_t *font)
&font->face->table,
nullptr);
}
#endif

View File

@ -180,7 +180,7 @@ struct glyf
+ hb_range (plan->num_output_glyphs ())
| hb_map ([&] (hb_codepoint_t new_gid) {
SubsetGlyph subset_glyph;
SubsetGlyph subset_glyph = {0};
subset_glyph.new_gid = new_gid;
// should never fail: all old gids should be mapped

View File

@ -86,74 +86,71 @@ struct hmtxvmtx
return result;
}
bool subset (hb_subset_plan_t *plan) const
template<typename Iterator,
hb_requires (hb_is_iterator (Iterator))>
void serialize (hb_serialize_context_t *c,
Iterator it,
unsigned num_advances)
{
typename T::accelerator_t _mtx;
_mtx.init (plan->source);
unsigned idx = 0;
+ it
| hb_apply ([c, &idx, num_advances] (const hb_item_type<Iterator>& _)
{
if (idx < num_advances)
{
LongMetric lm;
lm.advance = _.first;
lm.sb = _.second;
if (unlikely (!c->embed<LongMetric> (&lm))) return;
}
else
{
FWORD *sb = c->allocate_size<FWORD> (FWORD::static_size);
if (unlikely (!sb)) return;
*sb = _.second;
}
idx++;
})
;
}
/* All the trailing glyphs with the same advance can use one LongMetric
* and just keep LSB */
unsigned int num_output_glyphs = plan->num_output_glyphs ();
unsigned int num_advances = _mtx.num_advances_for_subset (plan);
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
/* alloc the new table */
size_t dest_sz = num_advances * 4
+ (num_output_glyphs - num_advances) * 2;
void *dest = (void *) malloc (dest_sz);
if (unlikely (!dest))
{
return false;
}
DEBUG_MSG(SUBSET, nullptr, "%c%c%c%c in src has %d advances, %d lsbs", HB_UNTAG(T::tableTag), _mtx.num_advances, _mtx.num_metrics - _mtx.num_advances);
DEBUG_MSG(SUBSET, nullptr, "%c%c%c%c in dest has %d advances, %d lsbs, %u bytes",
HB_UNTAG(T::tableTag), num_advances, num_output_glyphs - num_advances, (unsigned int) dest_sz);
T *table_prime = c->serializer->start_embed <T> ();
if (unlikely (!table_prime)) return_trace (false);
accelerator_t _mtx;
_mtx.init (c->plan->source);
unsigned num_advances = _mtx.num_advances_for_subset (c->plan);
auto it =
+ hb_range (c->plan->num_output_glyphs ())
| hb_map ([c, &_mtx] (unsigned _)
{
hb_codepoint_t old_gid;
if (c->plan->old_gid_for_new_gid (_, &old_gid))
return hb_pair (_mtx.get_advance (old_gid), _mtx.get_side_bearing (old_gid));
else
return hb_pair (0u, 0u);
})
;
// Copy everything over
char * dest_pos = (char *) dest;
table_prime->serialize (c->serializer, it, num_advances);
bool failed = false;
for (unsigned int i = 0; i < num_output_glyphs; i++)
{
unsigned int side_bearing = 0;
unsigned int advance = 0;
hb_codepoint_t old_gid;
if (plan->old_gid_for_new_gid (i, &old_gid))
{
// Glyph is not an empty glyph so copy advance and side bearing
// from the input font.
side_bearing = _mtx.get_side_bearing (old_gid);
advance = _mtx.get_advance (old_gid);
}
bool has_advance = i < num_advances;
if (has_advance)
{
((LongMetric *) dest_pos)->advance = advance;
((LongMetric *) dest_pos)->sb = side_bearing;
}
else
{
*((FWORD *) dest_pos) = side_bearing;
}
dest_pos += (has_advance ? 4 : 2);
}
_mtx.fini ();
if (unlikely (c->serializer->ran_out_of_room || c->serializer->in_error ()))
return_trace (false);
// Amend header num hmetrics
if (failed || unlikely (!subset_update_header (plan, num_advances)))
if (unlikely (!subset_update_header (c->plan, num_advances)))
{
free (dest);
return false;
return_trace (false);
}
hb_blob_t *result = hb_blob_create ((const char *)dest,
dest_sz,
HB_MEMORY_MODE_READONLY,
dest,
free);
bool success = plan->add_table (T::tableTag, result);
hb_blob_destroy (result);
return success;
return_trace (true);
}
struct accelerator_t

View File

@ -499,6 +499,9 @@ struct FeatureParams
{
bool sanitize (hb_sanitize_context_t *c, hb_tag_t tag) const
{
#ifdef HB_NO_LAYOUT_FEATURE_PARAMS
return true;
#endif
TRACE_SANITIZE (this);
if (tag == HB_TAG ('s','i','z','e'))
return_trace (u.size.sanitize (c));
@ -509,26 +512,26 @@ struct FeatureParams
return_trace (true);
}
#ifndef HB_NO_LAYOUT_FEATURE_PARAMS
const FeatureParamsSize& get_size_params (hb_tag_t tag) const
{
if (tag == HB_TAG ('s','i','z','e'))
return u.size;
return Null (FeatureParamsSize);
}
const FeatureParamsStylisticSet& get_stylistic_set_params (hb_tag_t tag) const
{
if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
return u.stylisticSet;
return Null (FeatureParamsStylisticSet);
}
const FeatureParamsCharacterVariants& get_character_variants_params (hb_tag_t tag) const
{
if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
return u.characterVariants;
return Null (FeatureParamsCharacterVariants);
}
#endif
private:
union {
@ -1747,11 +1750,11 @@ struct VarData
float *scalars /*OUT */,
unsigned int num_scalars) const
{
assert (num_scalars == regionIndices.len);
for (unsigned int i = 0; i < num_scalars; i++)
{
scalars[i] = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count);
}
unsigned count = hb_min (num_scalars, regionIndices.len);
for (unsigned int i = 0; i < count; i++)
scalars[i] = regions.evaluate (regionIndices.arrayZ[i], coords, coord_count);
for (unsigned int i = count; i < num_scalars; i++)
scalars[i] = 0.f;
}
bool sanitize (hb_sanitize_context_t *c) const
@ -1779,8 +1782,12 @@ struct VariationStore
float get_delta (unsigned int outer, unsigned int inner,
const int *coords, unsigned int coord_count) const
{
#ifdef HB_NO_VAR
return 0.f;
#endif
if (unlikely (outer >= dataSets.len))
return 0.;
return 0.f;
return (this+dataSets[outer]).get_delta (inner,
coords, coord_count,
@ -1797,6 +1804,10 @@ struct VariationStore
bool sanitize (hb_sanitize_context_t *c) const
{
#ifdef HB_NO_VAR
return true;
#endif
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
format == 1 &&
@ -1812,6 +1823,12 @@ struct VariationStore
float *scalars /*OUT*/,
unsigned int num_scalars) const
{
#ifdef HB_NO_VAR
for (unsigned i = 0; i < num_scalars; i++)
scalars[i] = 0.f;
return;
#endif
(this+dataSets[ivs]).get_scalars (coords, coord_count, this+regions,
&scalars[0], num_scalars);
}
@ -2152,10 +2169,14 @@ struct Device
{
switch (u.b.format)
{
#ifndef HB_NO_HINTING
case 1: case 2: case 3:
return u.hinting.get_x_delta (font);
#endif
#ifndef HB_NO_VAR
case 0x8000:
return u.variation.get_x_delta (font, store);
#endif
default:
return 0;
}
@ -2165,9 +2186,13 @@ struct Device
switch (u.b.format)
{
case 1: case 2: case 3:
#ifndef HB_NO_HINTING
return u.hinting.get_y_delta (font);
#endif
#ifndef HB_NO_VAR
case 0x8000:
return u.variation.get_y_delta (font, store);
#endif
default:
return 0;
}
@ -2178,10 +2203,14 @@ struct Device
TRACE_SANITIZE (this);
if (!u.b.format.sanitize (c)) return_trace (false);
switch (u.b.format) {
#ifndef HB_NO_HINTING
case 1: case 2: case 3:
return_trace (u.hinting.sanitize (c));
#endif
#ifndef HB_NO_VAR
case 0x8000:
return_trace (u.variation.sanitize (c));
#endif
default:
return_trace (true);
}
@ -2191,7 +2220,9 @@ struct Device
union {
DeviceHeader b;
HintingDevice hinting;
#ifndef HB_NO_VAR
VariationDevice variation;
#endif
} u;
public:
DEFINE_SIZE_UNION (6, b);

View File

@ -267,6 +267,13 @@ struct AnchorFormat2
float *x, float *y) const
{
hb_font_t *font = c->font;
#ifdef HB_NO_HINTING
*x = font->em_fscale_x (xCoordinate);
*y = font->em_fscale_y (yCoordinate);
return;
#endif
unsigned int x_ppem = font->x_ppem;
unsigned int y_ppem = font->y_ppem;
hb_position_t cx = 0, cy = 0;

View File

@ -2661,11 +2661,17 @@ struct GSUBGPOS
bool find_variations_index (const int *coords, unsigned int num_coords,
unsigned int *index) const
{ return (version.to_int () >= 0x00010001u ? this+featureVars : Null(FeatureVariations))
.find_index (coords, num_coords, index); }
{
#ifdef HB_NOVAR
return false;
#endif
return (version.to_int () >= 0x00010001u ? this+featureVars : Null(FeatureVariations))
.find_index (coords, num_coords, index);
}
const Feature& get_feature_variation (unsigned int feature_index,
unsigned int variations_index) const
{
#ifndef HB_NO_VAR
if (FeatureVariations::NOT_FOUND_INDEX != variations_index &&
version.to_int () >= 0x00010001u)
{
@ -2674,6 +2680,7 @@ struct GSUBGPOS
if (feature)
return *feature;
}
#endif
return get_feature (feature_index);
}
@ -2695,8 +2702,10 @@ struct GSUBGPOS
this,
out);
#ifndef HB_NO_VAR
if (version.to_int () >= 0x00010001u)
out->featureVars.serialize_copy (c->serializer, featureVars, this, out);
#endif
return_trace (true);
}
@ -2712,12 +2721,19 @@ struct GSUBGPOS
{
TRACE_SANITIZE (this);
typedef OffsetListOf<TLookup> TLookupList;
return_trace (version.sanitize (c) &&
likely (version.major == 1) &&
scriptList.sanitize (c, this) &&
featureList.sanitize (c, this) &&
CastR<OffsetTo<TLookupList>> (lookupList).sanitize (c, this) &&
(version.to_int () < 0x00010001u || featureVars.sanitize (c, this)));
if (unlikely (!(version.sanitize (c) &&
likely (version.major == 1) &&
scriptList.sanitize (c, this) &&
featureList.sanitize (c, this) &&
CastR<OffsetTo<TLookupList>> (lookupList).sanitize (c, this))))
return_trace (false);
#ifndef HB_NO_VAR
if (unlikely (!(version.to_int () < 0x00010001u || featureVars.sanitize (c, this))))
return_trace (false);
#endif
return_trace (true);
}
template <typename T>

View File

@ -62,6 +62,7 @@
* kern
*/
#ifndef HB_NO_OT_KERN
/**
* hb_ot_layout_has_kerning:
* @face: The #hb_face_t to work on
@ -78,7 +79,6 @@ hb_ot_layout_has_kerning (hb_face_t *face)
return face->table.kern->has_data ();
}
/**
* hb_ot_layout_has_machine_kerning:
* @face: The #hb_face_t to work on
@ -95,7 +95,6 @@ hb_ot_layout_has_machine_kerning (hb_face_t *face)
return face->table.kern->has_state_machine ();
}
/**
* hb_ot_layout_has_cross_kerning:
* @face: The #hb_face_t to work on
@ -128,6 +127,7 @@ hb_ot_layout_kern (const hb_ot_shape_plan_t *plan,
kern.apply (&c);
}
#endif
/*
@ -311,6 +311,7 @@ hb_ot_layout_get_glyphs_in_class (hb_face_t *face,
}
#ifndef HB_NO_LAYOUT_UNUSED
/**
* hb_ot_layout_get_attach_points:
* @face: The #hb_face_t to work on
@ -333,19 +334,11 @@ hb_ot_layout_get_attach_points (hb_face_t *face,
unsigned int *point_count /* IN/OUT */,
unsigned int *point_array /* OUT */)
{
#ifdef HB_NO_LAYOUT_UNUSED
if (point_count)
*point_count = 0;
return 0;
#endif
return face->table.GDEF->table->get_attach_points (glyph,
start_offset,
point_count,
point_array);
}
/**
* hb_ot_layout_get_ligature_carets:
* @font: The #hb_font_t to work on
@ -368,22 +361,19 @@ hb_ot_layout_get_ligature_carets (hb_font_t *font,
unsigned int *caret_count /* IN/OUT */,
hb_position_t *caret_array /* OUT */)
{
#ifdef HB_NO_LAYOUT_UNUSED
if (caret_count)
*caret_count = 0;
return 0;
#endif
unsigned int result_caret_count = 0;
unsigned int result = font->face->table.GDEF->table->get_lig_carets (font, direction, glyph, start_offset, &result_caret_count, caret_array);
if (result)
{
if (caret_count) *caret_count = result_caret_count;
}
#ifndef HB_NO_AAT
else
result = font->face->table.lcar->get_lig_carets (font, direction, glyph, start_offset, caret_count, caret_array);
#endif
return result;
}
#endif
/*
@ -397,6 +387,8 @@ OT::GSUB::is_blacklisted (hb_blob_t *blob HB_UNUSED,
#ifdef HB_NO_OT_LAYOUT_BLACKLIST
return false;
#endif
#ifndef HB_NO_SHAPE_AAT
/* Mac OS X prefers morx over GSUB. It also ships with various Indic fonts,
* all by 'MUTF' foundry (Tamil MN, Tamil Sangam MN, etc.), that have broken
* GSUB/GPOS tables. Some have GSUB with zero scripts, those are ignored by
@ -414,6 +406,7 @@ OT::GSUB::is_blacklisted (hb_blob_t *blob HB_UNUSED,
if (unlikely (face->table.OS2->achVendID == HB_TAG ('M','U','T','F') &&
face->table.morx->has_data ()))
return true;
#endif
return false;
}
@ -1210,6 +1203,7 @@ hb_ot_layout_collect_lookups (hb_face_t *face,
}
#ifndef HB_NO_LAYOUT_COLLECT_GLYPHS
/**
* hb_ot_layout_lookup_collect_glyphs:
* @face: #hb_face_t to work upon
@ -1256,6 +1250,7 @@ hb_ot_layout_lookup_collect_glyphs (hb_face_t *face,
}
}
}
#endif
/* Variations support */
@ -1564,6 +1559,7 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
}
#ifndef HB_NO_LAYOUT_FEATURE_PARAMS
/**
* hb_ot_layout_get_size_params:
* @face: #hb_face_t to work upon
@ -1626,8 +1622,6 @@ hb_ot_layout_get_size_params (hb_face_t *face,
return false;
}
/**
* hb_ot_layout_feature_get_name_ids:
* @face: #hb_face_t to work upon
@ -1702,8 +1696,6 @@ hb_ot_layout_feature_get_name_ids (hb_face_t *face,
if (first_param_id) *first_param_id = HB_OT_NAME_ID_INVALID;
return false;
}
/**
* hb_ot_layout_feature_get_characters:
* @face: #hb_face_t to work upon
@ -1757,6 +1749,7 @@ hb_ot_layout_feature_get_characters (hb_face_t *face,
if (char_count) *char_count = len;
return cv_params.characters.len;
}
#endif
/*
@ -1941,11 +1934,6 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
}
#if 0
static const OT::BASE& _get_base (hb_face_t *face)
{
return *face->table.BASE;
}
hb_bool_t
hb_ot_layout_get_baseline (hb_font_t *font,
hb_ot_layout_baseline_t baseline,
@ -1954,9 +1942,8 @@ hb_ot_layout_get_baseline (hb_font_t *font,
hb_tag_t language_tag,
hb_position_t *coord /* OUT. May be NULL. */)
{
const OT::BASE &base = _get_base (font->face);
bool result = base.get_baseline (font, baseline, direction, script_tag,
language_tag, coord);
bool result = font->face->table.BASE->get_baseline (font, baseline, direction, script_tag,
language_tag, coord);
/* TODO: Simulate https://docs.microsoft.com/en-us/typography/opentype/spec/baselinetags#ideographic-em-box */
if (!result && coord) *coord = 0;

View File

@ -24,9 +24,10 @@
* Igalia Author(s): Frédéric Wang
*/
#include "hb-open-type.hh"
#include "hb.hh"
#ifndef HB_NO_MATH
#include "hb-ot-face.hh"
#include "hb-ot-math-table.hh"
@ -62,10 +63,6 @@
hb_bool_t
hb_ot_math_has_data (hb_face_t *face)
{
#ifdef HB_NO_MATH
return false;
#endif
return face->table.MATH->has_data ();
}
@ -90,10 +87,6 @@ hb_position_t
hb_ot_math_get_constant (hb_font_t *font,
hb_ot_math_constant_t constant)
{
#ifdef HB_NO_MATH
return 0;
#endif
return font->face->table.MATH->get_constant(constant, font);
}
@ -113,10 +106,6 @@ hb_position_t
hb_ot_math_get_glyph_italics_correction (hb_font_t *font,
hb_codepoint_t glyph)
{
#ifdef HB_NO_MATH
return 0;
#endif
return font->face->table.MATH->get_glyph_info().get_italics_correction (glyph, font);
}
@ -143,10 +132,6 @@ hb_position_t
hb_ot_math_get_glyph_top_accent_attachment (hb_font_t *font,
hb_codepoint_t glyph)
{
#ifdef HB_NO_MATH
return 0;
#endif
return font->face->table.MATH->get_glyph_info().get_top_accent_attachment (glyph, font);
}
@ -165,10 +150,6 @@ hb_bool_t
hb_ot_math_is_glyph_extended_shape (hb_face_t *face,
hb_codepoint_t glyph)
{
#ifdef HB_NO_MATH
return false;
#endif
return face->table.MATH->get_glyph_info().is_extended_shape (glyph);
}
@ -197,10 +178,6 @@ hb_ot_math_get_glyph_kerning (hb_font_t *font,
hb_ot_math_kern_t kern,
hb_position_t correction_height)
{
#ifdef HB_NO_MATH
return 0;
#endif
return font->face->table.MATH->get_glyph_info().get_kerning (glyph,
kern,
correction_height,
@ -238,12 +215,6 @@ hb_ot_math_get_glyph_variants (hb_font_t *font,
unsigned int *variants_count, /* IN/OUT */
hb_ot_math_glyph_variant_t *variants /* OUT */)
{
#ifdef HB_NO_MATH
if (variants_count)
*variants_count = 0;
return 0;
#endif
return font->face->table.MATH->get_variants().get_glyph_variants (glyph, direction, font,
start_offset,
variants_count,
@ -272,10 +243,6 @@ hb_position_t
hb_ot_math_get_min_connector_overlap (hb_font_t *font,
hb_direction_t direction)
{
#ifdef HB_NO_MATH
return 0;
#endif
return font->face->table.MATH->get_variants().get_min_connector_overlap (direction, font);
}
@ -313,12 +280,6 @@ hb_ot_math_get_glyph_assembly (hb_font_t *font,
hb_ot_math_glyph_part_t *parts, /* OUT */
hb_position_t *italics_correction /* OUT */)
{
#ifdef HB_NO_MATH
if (parts_count)
*parts_count = 0;
return 0;
#endif
return font->face->table.MATH->get_variants().get_glyph_parts (glyph,
direction,
font,
@ -327,3 +288,6 @@ hb_ot_math_get_glyph_assembly (hb_font_t *font,
parts,
italics_correction);
}
#endif

View File

@ -94,39 +94,35 @@ struct maxp
return_trace (likely (version.major == 0 && version.minor == 0x5000u));
}
bool subset (hb_subset_plan_t *plan) const
bool subset (hb_subset_context_t *c) const
{
hb_blob_t *maxp_blob = hb_sanitize_context_t().reference_table<maxp> (plan->source);
hb_blob_t *maxp_prime_blob = hb_blob_copy_writable_or_fail (maxp_blob);
hb_blob_destroy (maxp_blob);
TRACE_SUBSET (this);
maxp *maxp_prime = c->serializer->embed (this);
if (unlikely (!maxp_prime)) return_trace (false);
if (unlikely (!maxp_prime_blob)) {
return false;
}
maxp *maxp_prime = (maxp *) hb_blob_get_data (maxp_prime_blob, nullptr);
maxp_prime->set_num_glyphs (plan->num_output_glyphs ());
if (plan->drop_hints)
drop_hint_fields (plan, maxp_prime);
bool result = plan->add_table (HB_OT_TAG_maxp, maxp_prime_blob);
hb_blob_destroy (maxp_prime_blob);
return result;
}
static void drop_hint_fields (hb_subset_plan_t *plan HB_UNUSED, maxp *maxp_prime)
{
maxp_prime->numGlyphs = c->plan->num_output_glyphs ();
if (maxp_prime->version.major == 1)
{
maxpV1Tail &v1 = StructAfter<maxpV1Tail> (*maxp_prime);
v1.maxZones = 1;
v1.maxTwilightPoints = 0;
v1.maxStorage = 0;
v1.maxFunctionDefs = 0;
v1.maxInstructionDefs = 0;
v1.maxStackElements = 0;
v1.maxSizeOfInstructions = 0;
const maxpV1Tail *src_v1 = &StructAfter<maxpV1Tail> (*this);
maxpV1Tail *dest_v1 = c->serializer->embed<maxpV1Tail> (src_v1);
if (unlikely (!dest_v1)) return_trace (false);
if (c->plan->drop_hints)
drop_hint_fields (dest_v1);
}
return_trace (true);
}
static void drop_hint_fields (maxpV1Tail* dest_v1)
{
dest_v1->maxZones = 1;
dest_v1->maxTwilightPoints = 0;
dest_v1->maxStorage = 0;
dest_v1->maxFunctionDefs = 0;
dest_v1->maxInstructionDefs = 0;
dest_v1->maxStackElements = 0;
dest_v1->maxSizeOfInstructions = 0;
}
protected:

View File

@ -63,7 +63,7 @@ struct NameRecord
#ifndef HB_NO_OT_NAME_LANGUAGE_AAT
if (p == 0)
return _hb_aat_language_get (face, l);
return face->table.ltag->get_language (l);
#endif
#endif

View File

@ -26,9 +26,10 @@
#include "hb.hh"
#ifndef HB_NO_NAME
#include "hb-ot-name-table.hh"
#include "hb-ot-face.hh"
#include "hb-utf.hh"
@ -58,11 +59,6 @@ const hb_ot_name_entry_t *
hb_ot_name_list_names (hb_face_t *face,
unsigned int *num_entries /* OUT */)
{
#ifdef HB_NO_NAME
if (num_entries)
*num_entries = 0;
return 0;
#endif
const OT::name_accelerator_t &name = *face->table.name;
if (num_entries) *num_entries = name.names.length;
return (const hb_ot_name_entry_t *) name.names;
@ -172,11 +168,6 @@ hb_ot_name_get_utf8 (hb_face_t *face,
unsigned int *text_size /* IN/OUT */,
char *text /* OUT */)
{
#ifdef HB_NO_NAME
if (text_size)
*text_size = 0;
return 0;
#endif
return hb_ot_name_get_utf<hb_utf8_t> (face, name_id, language, text_size,
(hb_utf8_t::codepoint_t *) text);
}
@ -204,11 +195,6 @@ hb_ot_name_get_utf16 (hb_face_t *face,
unsigned int *text_size /* IN/OUT */,
uint16_t *text /* OUT */)
{
#ifdef HB_NO_NAME
if (text_size)
*text_size = 0;
return 0;
#endif
return hb_ot_name_get_utf<hb_utf16_t> (face, name_id, language, text_size, text);
}
@ -235,10 +221,8 @@ hb_ot_name_get_utf32 (hb_face_t *face,
unsigned int *text_size /* IN/OUT */,
uint32_t *text /* OUT */)
{
#ifdef HB_NO_NAME
if (text_size)
*text_size = 0;
return 0;
#endif
return hb_ot_name_get_utf<hb_utf32_t> (face, name_id, language, text_size, text);
}
#endif

View File

@ -145,36 +145,28 @@ struct OS2
}
}
bool subset (hb_subset_plan_t *plan) const
bool subset (hb_subset_context_t *c) const
{
hb_blob_t *os2_blob = hb_sanitize_context_t ().reference_table<OS2> (plan->source);
hb_blob_t *os2_prime_blob = hb_blob_create_sub_blob (os2_blob, 0, -1);
// TODO(grieger): move to hb_blob_copy_writable_or_fail
hb_blob_destroy (os2_blob);
OS2 *os2_prime = (OS2 *) hb_blob_get_data_writable (os2_prime_blob, nullptr);
if (unlikely (!os2_prime)) {
hb_blob_destroy (os2_prime_blob);
return false;
}
TRACE_SUBSET (this);
OS2 *os2_prime = c->serializer->embed (this);
if (unlikely (!os2_prime)) return_trace (false);
uint16_t min_cp, max_cp;
find_min_and_max_codepoint (plan->unicodes, &min_cp, &max_cp);
find_min_and_max_codepoint (c->plan->unicodes, &min_cp, &max_cp);
os2_prime->usFirstCharIndex = min_cp;
os2_prime->usLastCharIndex = max_cp;
_update_unicode_ranges (plan->unicodes, os2_prime->ulUnicodeRange);
bool result = plan->add_table (HB_OT_TAG_OS2, os2_prime_blob);
_update_unicode_ranges (c->plan->unicodes, os2_prime->ulUnicodeRange);
hb_blob_destroy (os2_prime_blob);
return result;
return_trace (true);
}
void _update_unicode_ranges (const hb_set_t *codepoints,
HBUINT32 ulUnicodeRange[4]) const
{
HBUINT32 newBits[4];
for (unsigned int i = 0; i < 4; i++)
ulUnicodeRange[i] = 0;
newBits[i] = 0;
hb_codepoint_t cp = HB_SET_VALUE_INVALID;
while (codepoints->next (&cp)) {
@ -184,16 +176,19 @@ struct OS2
unsigned int block = bit / 32;
unsigned int bit_in_block = bit % 32;
unsigned int mask = 1 << bit_in_block;
ulUnicodeRange[block] = ulUnicodeRange[block] | mask;
newBits[block] = newBits[block] | mask;
}
if (cp >= 0x10000 && cp <= 0x110000)
{
/* the spec says that bit 57 ("Non Plane 0") implies that there's
at least one codepoint beyond the BMP; so I also include all
the non-BMP codepoints here */
ulUnicodeRange[1] = ulUnicodeRange[1] | (1 << 25);
newBits[1] = newBits[1] | (1 << 25);
}
}
for (unsigned int i = 0; i < 4; i++)
ulUnicodeRange[i] = ulUnicodeRange[i] & newBits[i]; // set bits only if set in the original
}
static void find_min_and_max_codepoint (const hb_set_t *codepoints,
@ -218,6 +213,15 @@ struct OS2
font_page_t get_font_page () const
{ return (font_page_t) (version == 0 ? fsSelection & 0xFF00 : 0); }
unsigned get_size () const
{
unsigned result = min_size;
if (version >= 1) result += v1X.get_size ();
if (version >= 2) result += v2X.get_size ();
if (version >= 5) result += v5X.get_size ();
return result;
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);

View File

@ -73,26 +73,25 @@ struct post
{
static constexpr hb_tag_t tableTag = HB_OT_TAG_post;
bool subset (hb_subset_plan_t *plan) const
void serialize (hb_serialize_context_t *c) const
{
unsigned int post_prime_length;
hb_blob_t *post_blob = hb_sanitize_context_t ().reference_table<post>(plan->source);
hb_blob_t *post_prime_blob = hb_blob_create_sub_blob (post_blob, 0, post::min_size);
post *post_prime = (post *) hb_blob_get_data_writable (post_prime_blob, &post_prime_length);
hb_blob_destroy (post_blob);
if (unlikely (!post_prime || post_prime_length != post::min_size))
{
hb_blob_destroy (post_prime_blob);
DEBUG_MSG(SUBSET, nullptr, "Invalid source post table with length %d.", post_prime_length);
return false;
}
post *post_prime = c->allocate_min<post> ();
if (unlikely (!post_prime)) return;
memcpy (post_prime, this, post::min_size);
post_prime->version.major = 3; // Version 3 does not have any glyph names.
bool result = plan->add_table (HB_OT_TAG_post, post_prime_blob);
hb_blob_destroy (post_prime_blob);
}
return result;
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this);
post *post_prime = c->serializer->start_embed<post> ();
if (unlikely (!post_prime)) return_trace (false);
serialize (c->serializer);
if (c->serializer->in_error () || c->serializer->ran_out_of_room) return_trace (false);
return_trace (true);
}
struct accelerator_t
@ -158,7 +157,7 @@ struct post
for (unsigned int i = 0; i < count; i++)
gids[i] = i;
hb_sort_r (gids, count, sizeof (gids[0]), cmp_gids, (void *) this);
hb_qsort (gids, count, sizeof (gids[0]), cmp_gids, (void *) this);
if (unlikely (!gids_sorted_by_name.cmpexch (nullptr, gids)))
{
@ -168,8 +167,8 @@ struct post
}
hb_bytes_t st (name, len);
const uint16_t *gid = (const uint16_t *) hb_bsearch_r (hb_addressof (st), gids, count,
sizeof (gids[0]), cmp_key, (void *) this);
const uint16_t *gid = (const uint16_t *) hb_bsearch (hb_addressof (st), gids, count,
sizeof (gids[0]), cmp_key, (void *) this);
if (gid)
{
*glyph = *gid;

View File

@ -359,7 +359,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 == 0x11301u || u == 0x11303u)) cat = OT_SM;
else if (unlikely (u == 0x1133cu)) cat = OT_N;
else if (unlikely (u == 0x1133Bu || u == 0x1133Cu)) cat = OT_N;
else if (unlikely (u == 0x0AFBu)) cat = OT_N; /* https://github.com/harfbuzz/harfbuzz/issues/552 */

View File

@ -36,31 +36,31 @@
static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
1u, 32u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u,
3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 5u, 29u,
5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u,
3u, 29u, 1u, 16u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 1u, 32u,
1u, 32u, 8u, 8u, 0
3u, 29u, 3u, 29u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u,
3u, 29u, 3u, 29u, 1u, 16u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
3u, 29u, 3u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 30u,
3u, 29u, 1u, 32u, 1u, 32u, 8u, 8u, 0
};
static const char _myanmar_syllable_machine_key_spans[] = {
32, 28, 25, 4, 25, 23, 21, 21,
27, 27, 27, 27, 16, 27, 27, 27,
27, 27, 28, 27, 27, 27, 27, 25,
4, 25, 23, 21, 21, 27, 27, 27,
27, 16, 28, 27, 27, 27, 27, 27,
28, 27, 27, 27, 27, 28, 27, 32,
32, 1
27, 27, 28, 27, 27, 27, 27, 27,
25, 4, 25, 23, 21, 21, 27, 27,
27, 27, 16, 28, 27, 27, 27, 27,
27, 28, 27, 27, 27, 27, 27, 28,
27, 32, 32, 1
};
static const short _myanmar_syllable_machine_index_offsets[] = {
0, 33, 62, 88, 93, 119, 143, 165,
187, 215, 243, 271, 299, 316, 344, 372,
400, 428, 456, 485, 513, 541, 569, 597,
623, 628, 654, 678, 700, 722, 750, 778,
806, 834, 851, 880, 908, 936, 964, 992,
1020, 1049, 1077, 1105, 1133, 1161, 1190, 1218,
1251, 1284
625, 651, 656, 682, 706, 728, 750, 778,
806, 834, 862, 879, 908, 936, 964, 992,
1020, 1048, 1077, 1105, 1133, 1161, 1189, 1217,
1246, 1274, 1307, 1340
};
static const char _myanmar_syllable_machine_indicies[] = {
@ -126,116 +126,123 @@ static const char _myanmar_syllable_machine_indicies[] = {
21, 21, 21, 21, 21, 21, 32, 33,
34, 35, 36, 43, 21, 22, 21, 24,
24, 21, 25, 21, 26, 21, 21, 21,
21, 21, 21, 21, 43, 21, 21, 28,
21, 21, 21, 21, 21, 21, 21, 28,
21, 30, 21, 32, 33, 34, 35, 36,
21, 22, 21, 24, 24, 21, 25, 21,
26, 21, 21, 21, 21, 21, 21, 21,
43, 21, 21, 28, 21, 21, 21, 32,
33, 34, 35, 36, 21, 22, 21, 24,
24, 21, 25, 21, 26, 21, 21, 21,
21, 21, 21, 21, 43, 21, 21, 28,
21, 21, 21, 21, 44, 21, 21, 28,
29, 30, 21, 32, 33, 34, 35, 36,
21, 22, 23, 24, 24, 21, 25, 21,
21, 22, 21, 24, 24, 21, 25, 21,
26, 21, 21, 21, 21, 21, 21, 21,
27, 21, 21, 28, 29, 30, 31, 32,
33, 34, 35, 36, 21, 45, 45, 44,
5, 44, 44, 44, 44, 44, 44, 44,
44, 44, 46, 44, 44, 44, 44, 44,
44, 14, 44, 44, 44, 18, 44, 45,
45, 44, 5, 44, 45, 45, 44, 5,
44, 44, 44, 44, 44, 44, 44, 44,
44, 44, 44, 44, 44, 44, 44, 44,
14, 44, 44, 44, 18, 44, 47, 44,
45, 45, 44, 5, 44, 14, 44, 44,
44, 44, 44, 44, 44, 48, 44, 44,
44, 44, 44, 44, 14, 44, 45, 45,
44, 5, 44, 44, 44, 44, 44, 44,
44, 44, 44, 48, 44, 44, 44, 44,
44, 44, 14, 44, 45, 45, 44, 5,
44, 44, 44, 44, 44, 44, 44, 44,
44, 44, 44, 44, 44, 44, 44, 44,
14, 44, 2, 44, 45, 45, 44, 5,
44, 6, 44, 44, 44, 44, 44, 44,
44, 49, 44, 44, 49, 44, 44, 44,
14, 50, 44, 44, 18, 44, 2, 44,
45, 45, 44, 5, 44, 6, 44, 44,
44, 44, 44, 44, 44, 44, 44, 44,
44, 44, 44, 44, 14, 44, 44, 44,
18, 44, 2, 44, 45, 45, 44, 5,
44, 6, 44, 44, 44, 44, 44, 44,
44, 49, 44, 44, 44, 44, 44, 44,
14, 50, 44, 44, 18, 44, 2, 44,
45, 45, 44, 5, 44, 6, 44, 44,
44, 44, 44, 44, 44, 44, 44, 44,
44, 44, 44, 44, 14, 50, 44, 44,
18, 44, 51, 51, 44, 44, 44, 44,
44, 44, 44, 44, 44, 44, 44, 44,
44, 51, 44, 2, 3, 45, 45, 44,
5, 44, 6, 44, 44, 44, 44, 44,
44, 44, 8, 44, 44, 10, 11, 12,
13, 14, 15, 16, 17, 18, 19, 44,
2, 44, 45, 45, 44, 5, 44, 6,
44, 44, 44, 44, 44, 44, 44, 8,
44, 44, 10, 11, 12, 13, 14, 15,
16, 17, 18, 44, 2, 44, 45, 45,
44, 5, 44, 6, 44, 44, 44, 44,
44, 44, 44, 52, 44, 44, 44, 44,
44, 44, 14, 15, 16, 17, 18, 44,
2, 44, 45, 45, 44, 5, 44, 6,
44, 44, 44, 44, 44, 44, 44, 44,
44, 44, 44, 44, 44, 44, 14, 15,
16, 17, 18, 44, 2, 44, 45, 45,
44, 5, 44, 6, 44, 44, 44, 44,
44, 44, 44, 44, 44, 44, 44, 44,
44, 44, 14, 15, 16, 44, 18, 44,
2, 44, 45, 45, 44, 5, 44, 6,
44, 44, 44, 44, 44, 44, 44, 44,
44, 44, 44, 44, 44, 44, 14, 44,
16, 44, 18, 44, 2, 44, 45, 45,
44, 5, 44, 6, 44, 44, 44, 44,
44, 44, 44, 44, 44, 44, 44, 44,
44, 44, 14, 15, 16, 17, 18, 52,
44, 2, 44, 45, 45, 44, 5, 44,
6, 44, 44, 44, 44, 44, 44, 44,
52, 44, 44, 10, 44, 12, 44, 14,
15, 16, 17, 18, 44, 2, 44, 45,
45, 44, 5, 44, 6, 44, 44, 44,
44, 44, 44, 44, 52, 44, 44, 10,
44, 44, 44, 14, 15, 16, 17, 18,
44, 2, 44, 45, 45, 44, 5, 44,
6, 44, 44, 44, 44, 44, 44, 44,
52, 44, 44, 10, 11, 12, 44, 14,
15, 16, 17, 18, 44, 2, 3, 45,
45, 44, 5, 44, 6, 44, 44, 44,
44, 44, 44, 44, 8, 44, 44, 10,
21, 21, 21, 28, 29, 30, 21, 32,
33, 34, 35, 36, 21, 22, 23, 24,
24, 21, 25, 21, 26, 21, 21, 21,
21, 21, 21, 21, 27, 21, 21, 28,
29, 30, 31, 32, 33, 34, 35, 36,
21, 46, 46, 45, 5, 45, 45, 45,
45, 45, 45, 45, 45, 45, 47, 45,
45, 45, 45, 45, 45, 14, 45, 45,
45, 18, 45, 46, 46, 45, 5, 45,
46, 46, 45, 5, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 14, 45, 45, 45,
18, 45, 48, 45, 46, 46, 45, 5,
45, 14, 45, 45, 45, 45, 45, 45,
45, 49, 45, 45, 45, 45, 45, 45,
14, 45, 46, 46, 45, 5, 45, 45,
45, 45, 45, 45, 45, 45, 45, 49,
45, 45, 45, 45, 45, 45, 14, 45,
46, 46, 45, 5, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 14, 45, 2, 45,
46, 46, 45, 5, 45, 6, 45, 45,
45, 45, 45, 45, 45, 50, 45, 45,
50, 45, 45, 45, 14, 51, 45, 45,
18, 45, 2, 45, 46, 46, 45, 5,
45, 6, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45,
14, 45, 45, 45, 18, 45, 2, 45,
46, 46, 45, 5, 45, 6, 45, 45,
45, 45, 45, 45, 45, 50, 45, 45,
45, 45, 45, 45, 14, 51, 45, 45,
18, 45, 2, 45, 46, 46, 45, 5,
45, 6, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45,
14, 51, 45, 45, 18, 45, 52, 52,
45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 52, 45, 2,
3, 46, 46, 45, 5, 45, 6, 45,
45, 45, 45, 45, 45, 45, 8, 45,
45, 10, 11, 12, 13, 14, 15, 16,
17, 18, 19, 45, 2, 45, 46, 46,
45, 5, 45, 6, 45, 45, 45, 45,
45, 45, 45, 8, 45, 45, 10, 11,
12, 13, 14, 15, 16, 17, 18, 45,
2, 45, 46, 46, 45, 5, 45, 6,
45, 45, 45, 45, 45, 45, 45, 53,
45, 45, 45, 45, 45, 45, 14, 15,
16, 17, 18, 45, 2, 45, 46, 46,
45, 5, 45, 6, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 14, 15, 16, 17, 18, 45,
2, 45, 46, 46, 45, 5, 45, 6,
45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 14, 15,
16, 45, 18, 45, 2, 45, 46, 46,
45, 5, 45, 6, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 14, 45, 16, 45, 18, 45,
2, 45, 46, 46, 45, 5, 45, 6,
45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 14, 15,
16, 17, 18, 53, 45, 2, 45, 46,
46, 45, 5, 45, 6, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 10,
45, 12, 45, 14, 15, 16, 17, 18,
45, 2, 45, 46, 46, 45, 5, 45,
6, 45, 45, 45, 45, 45, 45, 45,
53, 45, 45, 10, 45, 45, 45, 14,
15, 16, 17, 18, 45, 2, 45, 46,
46, 45, 5, 45, 6, 45, 45, 45,
45, 45, 45, 45, 54, 45, 45, 10,
11, 12, 45, 14, 15, 16, 17, 18,
45, 2, 45, 46, 46, 45, 5, 45,
6, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 10, 11, 12, 45, 14,
15, 16, 17, 18, 45, 2, 3, 46,
46, 45, 5, 45, 6, 45, 45, 45,
45, 45, 45, 45, 8, 45, 45, 10,
11, 12, 13, 14, 15, 16, 17, 18,
44, 22, 23, 24, 24, 21, 25, 21,
45, 22, 23, 24, 24, 21, 25, 21,
26, 21, 21, 21, 21, 21, 21, 21,
53, 21, 21, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 21, 22, 54,
55, 21, 21, 28, 29, 30, 31, 32,
33, 34, 35, 36, 37, 21, 22, 56,
24, 24, 21, 25, 21, 26, 21, 21,
21, 21, 21, 21, 21, 27, 21, 21,
28, 29, 30, 31, 32, 33, 34, 35,
36, 21, 1, 1, 2, 3, 45, 45,
44, 5, 44, 6, 1, 44, 44, 44,
44, 1, 44, 8, 44, 44, 10, 11,
36, 21, 1, 1, 2, 3, 46, 46,
45, 5, 45, 6, 1, 45, 45, 45,
45, 1, 45, 8, 45, 45, 10, 11,
12, 13, 14, 15, 16, 17, 18, 19,
44, 1, 44, 1, 1, 55, 55, 55,
55, 55, 55, 55, 55, 1, 55, 55,
55, 55, 1, 55, 55, 55, 55, 55,
55, 55, 55, 55, 55, 55, 55, 55,
55, 55, 1, 55, 56, 55, 0
45, 1, 45, 1, 1, 57, 57, 57,
57, 57, 57, 57, 57, 1, 57, 57,
57, 57, 1, 57, 57, 57, 57, 57,
57, 57, 57, 57, 57, 57, 57, 57,
57, 57, 1, 57, 58, 57, 0
};
static const char _myanmar_syllable_machine_trans_targs[] = {
0, 1, 23, 33, 0, 24, 30, 45,
35, 48, 36, 41, 42, 43, 26, 38,
39, 40, 29, 44, 49, 0, 2, 12,
0, 1, 24, 34, 0, 25, 31, 47,
36, 50, 37, 42, 43, 44, 27, 39,
40, 41, 30, 46, 51, 0, 2, 12,
0, 3, 9, 13, 14, 19, 20, 21,
5, 16, 17, 18, 8, 22, 4, 6,
7, 10, 11, 15, 0, 0, 25, 27,
28, 31, 32, 34, 37, 46, 47, 0,
0
5, 16, 17, 18, 8, 23, 4, 6,
7, 10, 11, 15, 22, 0, 0, 26,
28, 29, 32, 33, 35, 38, 45, 48,
49, 0, 0
};
static const char _myanmar_syllable_machine_trans_actions[] = {
@ -244,9 +251,9 @@ static const char _myanmar_syllable_machine_trans_actions[] = {
0, 0, 0, 0, 0, 5, 0, 0,
6, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 7, 8, 0, 0,
0, 0, 0, 0, 0, 0, 0, 9,
10
0, 0, 0, 0, 0, 7, 8, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 9, 10
};
static const char _myanmar_syllable_machine_to_state_actions[] = {
@ -256,7 +263,7 @@ static const char _myanmar_syllable_machine_to_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0
0, 0, 0, 0
};
static const char _myanmar_syllable_machine_from_state_actions[] = {
@ -266,17 +273,17 @@ static const char _myanmar_syllable_machine_from_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0
0, 0, 0, 0
};
static const short _myanmar_syllable_machine_eof_trans[] = {
0, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 22,
22, 22, 22, 22, 22, 22, 22, 45,
45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 45, 45, 45,
45, 45, 45, 45, 45, 22, 22, 45,
56, 56
22, 22, 22, 22, 22, 22, 22, 22,
46, 46, 46, 46, 46, 46, 46, 46,
46, 46, 46, 46, 46, 46, 46, 46,
46, 46, 46, 46, 46, 46, 46, 22,
22, 46, 58, 58
};
static const int myanmar_syllable_machine_start = 0;
@ -309,7 +316,7 @@ find_syllables (hb_buffer_t *buffer)
int cs;
hb_glyph_info_t *info = buffer->info;
#line 313 "hb-ot-shape-complex-myanmar-machine.hh"
#line 320 "hb-ot-shape-complex-myanmar-machine.hh"
{
cs = myanmar_syllable_machine_start;
ts = 0;
@ -325,7 +332,7 @@ find_syllables (hb_buffer_t *buffer)
unsigned int syllable_serial = 1;
#line 329 "hb-ot-shape-complex-myanmar-machine.hh"
#line 336 "hb-ot-shape-complex-myanmar-machine.hh"
{
int _slen;
int _trans;
@ -339,7 +346,7 @@ _resume:
#line 1 "NONE"
{ts = p;}
break;
#line 343 "hb-ot-shape-complex-myanmar-machine.hh"
#line 350 "hb-ot-shape-complex-myanmar-machine.hh"
}
_keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
@ -389,7 +396,7 @@ _eof_trans:
#line 90 "hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (non_myanmar_cluster); }}
break;
#line 393 "hb-ot-shape-complex-myanmar-machine.hh"
#line 400 "hb-ot-shape-complex-myanmar-machine.hh"
}
_again:
@ -398,7 +405,7 @@ _again:
#line 1 "NONE"
{ts = 0;}
break;
#line 402 "hb-ot-shape-complex-myanmar-machine.hh"
#line 409 "hb-ot-shape-complex-myanmar-machine.hh"
}
if ( ++p != pe )

View File

@ -69,7 +69,7 @@ k = (Ra As H); # Kinzi
c = C|Ra; # is_consonant
medial_group = MY? MR? MW? MH? As?;
medial_group = MY? As? MR? ((MW MH? | MH) As?)?;
main_vowel_group = (VPre.VS?)* VAbv* VBlw* A* (DB As?)?;
post_vowel_group = VPst MH? As* VAbv* A* (DB As?)?;
pwo_tone_group = PT A* DB? As?;

View File

@ -98,21 +98,30 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
plan.props = props;
plan.shaper = shaper;
map.compile (plan.map, key);
#ifndef HB_NO_SHAPE_AAT
if (apply_morx)
aat_map.compile (plan.aat_map);
#endif
#ifndef HB_NO_OT_SHAPE_FRACTIONS
plan.frac_mask = plan.map.get_1_mask (HB_TAG ('f','r','a','c'));
plan.numr_mask = plan.map.get_1_mask (HB_TAG ('n','u','m','r'));
plan.dnom_mask = plan.map.get_1_mask (HB_TAG ('d','n','o','m'));
plan.has_frac = plan.frac_mask || (plan.numr_mask && plan.dnom_mask);
#endif
plan.rtlm_mask = plan.map.get_1_mask (HB_TAG ('r','t','l','m'));
hb_tag_t kern_tag = HB_DIRECTION_IS_HORIZONTAL (props.direction) ?
HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n');
#ifndef HB_NO_OT_KERN
plan.kern_mask = plan.map.get_mask (kern_tag);
plan.trak_mask = plan.map.get_mask (HB_TAG ('t','r','a','k'));
plan.requested_kerning = !!plan.kern_mask;
#endif
#ifndef HB_NO_SHAPE_AAT
plan.trak_mask = plan.map.get_mask (HB_TAG ('t','r','a','k'));
plan.requested_tracking = !!plan.trak_mask;
#endif
bool has_gpos_kern = plan.map.get_feature_index (1, kern_tag) != HB_OT_LAYOUT_NO_FEATURE_INDEX;
bool disable_gpos = plan.shaper->gpos_tag &&
plan.shaper->gpos_tag != plan.map.chosen_script[1];
@ -152,24 +161,33 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
if (!plan.apply_kerx && !has_gpos_kern)
{
/* Apparently Apple applies kerx if GPOS kern was not applied. */
if (0)
;
#ifndef HB_NO_SHAPE_AAT
else if (hb_aat_layout_has_positioning (face))
if (hb_aat_layout_has_positioning (face))
plan.apply_kerx = true;
else
#endif
else if (hb_ot_layout_has_kerning (face))
#ifndef HB_NO_OT_KERN
if (hb_ot_layout_has_kerning (face))
plan.apply_kern = true;
#endif
}
plan.zero_marks = script_zero_marks &&
!plan.apply_kerx &&
(!plan.apply_kern || !hb_ot_layout_has_machine_kerning (face));
(!plan.apply_kern
#ifndef HB_NO_OT_KERN
|| !hb_ot_layout_has_machine_kerning (face)
#endif
);
plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k'));
plan.adjust_mark_positioning_when_zeroing = !plan.apply_gpos &&
!plan.apply_kerx &&
(!plan.apply_kern || !hb_ot_layout_has_cross_kerning (face));
(!plan.apply_kern
#ifndef HB_NO_OT_KERN
|| !hb_ot_layout_has_cross_kerning (face)
#endif
);
plan.fallback_mark_positioning = plan.adjust_mark_positioning_when_zeroing &&
script_fallback_mark_positioning;
@ -185,7 +203,9 @@ hb_ot_shape_plan_t::init0 (hb_face_t *face,
const hb_shape_plan_key_t *key)
{
map.init ();
#ifndef HB_NO_SHAPE_AAT
aat_map.init ();
#endif
hb_ot_shape_planner_t planner (face,
&key->props);
@ -213,16 +233,20 @@ hb_ot_shape_plan_t::fini ()
shaper->data_destroy (const_cast<void *> (data));
map.fini ();
#ifndef HB_NO_SHAPE_AAT
aat_map.fini ();
#endif
}
void
hb_ot_shape_plan_t::substitute (hb_font_t *font,
hb_buffer_t *buffer) const
{
#ifndef HB_NO_SHAPE_AAT
if (unlikely (apply_morx))
hb_aat_layout_substitute (this, font, buffer);
else
#endif
map.substitute (this, font, buffer);
}
@ -232,15 +256,21 @@ hb_ot_shape_plan_t::position (hb_font_t *font,
{
if (this->apply_gpos)
map.position (this, font, buffer);
#ifndef HB_NO_SHAPE_AAT
else if (this->apply_kerx)
hb_aat_layout_position (this, font, buffer);
#endif
#ifndef HB_NO_OT_KERN
else if (this->apply_kern)
hb_ot_layout_kern (this, font, buffer);
#endif
else
_hb_ot_shape_fallback_kern (this, font, buffer);
#ifndef HB_NO_SHAPE_AAT
if (this->apply_trak)
hb_aat_layout_track (this, font, buffer);
#endif
}
@ -292,18 +322,22 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
break;
}
#ifndef HB_NO_OT_SHAPE_FRACTIONS
/* Automatic fractions. */
map->add_feature (HB_TAG ('f','r','a','c'));
map->add_feature (HB_TAG ('n','u','m','r'));
map->add_feature (HB_TAG ('d','n','o','m'));
#endif
/* Random! */
map->enable_feature (HB_TAG ('r','a','n','d'), F_RANDOM, HB_OT_MAP_MAX_VALUE);
#ifndef HB_NO_SHAPE_AAT
/* Tracking. We enable dummy feature here just to allow disabling
* AAT 'trak' table using features.
* https://github.com/harfbuzz/harfbuzz/issues/1303 */
map->enable_feature (HB_TAG ('t','r','a','k'), F_HAS_FALLBACK);
#endif
map->enable_feature (HB_TAG ('H','A','R','F'));
@ -336,6 +370,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
feature->value);
}
#ifndef HB_NO_SHAPE_AAT
if (planner->apply_morx)
{
hb_aat_map_builder_t *aat_map = &planner->aat_map;
@ -345,6 +380,7 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
aat_map->add_feature (feature->tag, feature->value);
}
}
#endif
if (planner->shaper->override_features)
planner->shaper->override_features (planner);
@ -569,6 +605,10 @@ hb_ot_mirror_chars (const hb_ot_shape_context_t *c)
static inline void
hb_ot_shape_setup_masks_fraction (const hb_ot_shape_context_t *c)
{
#ifdef HB_NO_OT_SHAPE_FRACTIONS
return;
#endif
if (!(c->buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_NON_ASCII) ||
!c->plan->has_frac)
return;
@ -779,8 +819,10 @@ static inline void
hb_ot_substitute_post (const hb_ot_shape_context_t *c)
{
hb_ot_hide_default_ignorables (c->buffer, c->font);
#ifndef HB_NO_SHAPE_AAT
if (c->plan->apply_morx)
hb_aat_layout_remove_deleted_glyphs (c->buffer);
#endif
if (c->plan->shaper->postprocess_glyphs)
c->plan->shaper->postprocess_glyphs (c->plan, c->buffer, c->font);
@ -914,8 +956,10 @@ hb_ot_position_complex (const hb_ot_shape_context_t *c)
/* Finish off. Has to follow a certain order. */
hb_ot_layout_position_finish_advances (c->font, c->buffer);
hb_ot_zero_width_default_ignorables (c->buffer);
#ifndef HB_NO_SHAPE_AAT
if (c->plan->apply_morx)
hb_aat_layout_zero_width_deleted_glyphs (c->buffer);
#endif
hb_ot_layout_position_finish_offsets (c->font, c->buffer);
/* The nil glyph_h_origin() func returns 0, so no need to apply it. */

View File

@ -65,14 +65,40 @@ struct hb_ot_shape_plan_t
hb_ot_map_t map;
hb_aat_map_t aat_map;
const void *data;
#ifndef HB_NO_OT_SHAPE_FRACTIONS
hb_mask_t frac_mask, numr_mask, dnom_mask;
#else
static constexpr hb_mask_t frac_mask = 0;
static constexpr hb_mask_t numr_mask = 0;
static constexpr hb_mask_t dnom_mask = 0;
#endif
hb_mask_t rtlm_mask;
#ifndef HB_NO_OT_KERN
hb_mask_t kern_mask;
#else
static constexpr hb_mask_t kern_mask = 0;
#endif
#ifndef HB_NO_SHAPE_AAT
hb_mask_t trak_mask;
#else
static constexpr hb_mask_t trak_mask = 0;
#endif
#ifndef HB_NO_OT_KERN
bool requested_kerning : 1;
#else
static constexpr bool requested_kerning = false;
#endif
#ifndef HB_NO_SHAPE_AAT
bool requested_tracking : 1;
#else
static constexpr bool requested_tracking = false;
#endif
#ifndef HB_NO_OT_SHAPE_FRACTIONS
bool has_frac : 1;
#else
static constexpr bool has_frac = false;
#endif
bool has_gpos_mark : 1;
bool zero_marks : 1;
bool fallback_glyph_classes : 1;
@ -80,7 +106,11 @@ struct hb_ot_shape_plan_t
bool adjust_mark_positioning_when_zeroing : 1;
bool apply_gpos : 1;
#ifndef HB_NO_OT_KERN
bool apply_kern : 1;
#else
static constexpr bool apply_kern = false;
#endif
#ifndef HB_NO_SHAPE_AAT
bool apply_kerx : 1;
bool apply_morx : 1;

View File

@ -59,14 +59,14 @@ enum
struct AxisValueFormat1
{
hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (likely (c->check_struct (this)));
}
hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
protected:
HBUINT16 format; /* Format identifier — set to 1. */
HBUINT16 axisIndex; /* Zero-base index into the axis record array
@ -84,14 +84,14 @@ struct AxisValueFormat1
struct AxisValueFormat2
{
hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (likely (c->check_struct (this)));
}
hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
protected:
HBUINT16 format; /* Format identifier — set to 2. */
HBUINT16 axisIndex; /* Zero-base index into the axis record array
@ -113,14 +113,14 @@ struct AxisValueFormat2
struct AxisValueFormat3
{
hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (likely (c->check_struct (this)));
}
hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
protected:
HBUINT16 format; /* Format identifier — set to 3. */
HBUINT16 axisIndex; /* Zero-base index into the axis record array
@ -157,14 +157,14 @@ struct AxisValueRecord
struct AxisValueFormat4
{
hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (likely (c->check_struct (this)));
}
hb_ot_name_id_t get_value_name_id () const { return valueNameID; }
protected:
HBUINT16 format; /* Format identifier — set to 4. */
HBUINT16 axisCount; /* The total number of axes contributing to
@ -183,6 +183,18 @@ struct AxisValueFormat4
struct AxisValue
{
hb_ot_name_id_t get_value_name_id () const
{
switch (u.format)
{
case 1: return u.format1.get_value_name_id ();
case 2: return u.format2.get_value_name_id ();
case 3: return u.format3.get_value_name_id ();
case 4: return u.format4.get_value_name_id ();
default:return HB_OT_NAME_ID_INVALID;
}
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@ -191,23 +203,11 @@ struct AxisValue
switch (u.format)
{
case 1: return_trace (likely (u.format1.sanitize (c)));
case 2: return_trace (likely (u.format2.sanitize (c)));
case 3: return_trace (likely (u.format3.sanitize (c)));
case 4: return_trace (likely (u.format4.sanitize (c)));
default: return_trace (true);
}
}
hb_ot_name_id_t get_value_name_id () const
{
switch (u.format)
{
case 1: return u.format1.get_value_name_id ();
case 2: return u.format2.get_value_name_id ();
case 3: return u.format3.get_value_name_id ();
case 4: return u.format4.get_value_name_id ();
default: return HB_OT_NAME_ID_INVALID;
case 1: return_trace (u.format1.sanitize (c));
case 2: return_trace (u.format2.sanitize (c));
case 3: return_trace (u.format3.sanitize (c));
case 4: return_trace (u.format4.sanitize (c));
default:return_trace (true);
}
}
@ -226,14 +226,14 @@ struct AxisValue
struct StatAxisRecord
{
hb_ot_name_id_t get_name_id () const { return nameID; }
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (likely (c->check_struct (this)));
}
hb_ot_name_id_t get_name_id () const { return nameID; }
protected:
Tag tag; /* A tag identifying the axis of design variation. */
NameID nameID; /* The name ID for entries in the 'name' table that
@ -249,16 +249,6 @@ struct STAT
{
static constexpr hb_tag_t tableTag = HB_OT_TAG_STAT;
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (likely (c->check_struct (this) &&
version.major == 1 &&
version.minor > 0 &&
designAxesOffset.sanitize (c, this, designAxisCount) &&
offsetToAxisValueOffsets.sanitize (c, this, axisValueCount, &(this+offsetToAxisValueOffsets))));
}
bool has_data () const { return version.to_int (); }
unsigned get_design_axis_count () const { return designAxisCount; }
@ -295,6 +285,16 @@ struct STAT
;
}
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (likely (c->check_struct (this) &&
version.major == 1 &&
version.minor > 0 &&
designAxesOffset.sanitize (c, this, designAxisCount) &&
offsetToAxisValueOffsets.sanitize (c, this, axisValueCount, &(this+offsetToAxisValueOffsets))));
}
protected:
hb_array_t<const StatAxisRecord> const get_design_axes () const
{ return (this+designAxesOffset).as_array (designAxisCount); }

View File

@ -145,7 +145,9 @@ hb_ot_all_tags_from_script (hb_script_t script,
hb_tag_t new_tag = hb_ot_new_tag_from_script (script);
if (unlikely (new_tag != HB_OT_TAG_DEFAULT_SCRIPT))
{
tags[i++] = new_tag | '3';
/* HB_SCRIPT_MYANMAR maps to 'mym2', but there is no 'mym3'. */
if (new_tag != HB_TAG('m','y','m','2'))
tags[i++] = new_tag | '3';
if (*count > i)
tags[i++] = new_tag;
}
@ -303,28 +305,28 @@ parse_private_use_subtag (const char *private_use_subtag,
const char *prefix,
unsigned char (*normalize) (unsigned char))
{
if (private_use_subtag && count && tags && *count)
{
const char *s = strstr (private_use_subtag, prefix);
if (s)
{
char tag[4];
int i;
s += strlen (prefix);
for (i = 0; i < 4 && ISALNUM (s[i]); i++)
tag[i] = normalize (s[i]);
if (i)
{
for (; i < 4; i++)
tag[i] = ' ';
tags[0] = HB_TAG (tag[0], tag[1], tag[2], tag[3]);
if ((tags[0] & 0xDFDFDFDF) == HB_OT_TAG_DEFAULT_SCRIPT)
tags[0] ^= ~0xDFDFDFDF;
*count = 1;
return false;
}
}
}
#ifdef HB_NO_LANGUAGE_PRIVATE_SUBTAG
return false;
#endif
if (!(private_use_subtag && count && tags && *count)) return false;
const char *s = strstr (private_use_subtag, prefix);
if (!s) return false;
char tag[4];
int i;
s += strlen (prefix);
for (i = 0; i < 4 && ISALNUM (s[i]); i++)
tag[i] = normalize (s[i]);
if (!i) return false;
for (; i < 4; i++)
tag[i] = ' ';
tags[0] = HB_TAG (tag[0], tag[1], tag[2], tag[3]);
if ((tags[0] & 0xDFDFDFDF) == HB_OT_TAG_DEFAULT_SCRIPT)
tags[0] ^= ~0xDFDFDFDF;
*count = 1;
return true;
}
@ -392,8 +394,8 @@ hb_ot_tags_from_script_and_language (hb_script_t script,
limit = s;
}
needs_script = parse_private_use_subtag (private_use_subtag, script_count, script_tags, "-hbsc", TOLOWER);
needs_language = parse_private_use_subtag (private_use_subtag, language_count, language_tags, "-hbot", TOUPPER);
needs_script = !parse_private_use_subtag (private_use_subtag, script_count, script_tags, "-hbsc", TOLOWER);
needs_language = !parse_private_use_subtag (private_use_subtag, language_count, language_tags, "-hbot", TOUPPER);
if (needs_language && language_count && language_tags && *language_count)
hb_ot_tags_from_language (lang_str, limit, language_count, language_tags);

View File

@ -77,9 +77,9 @@ struct MVAR
const int *coords, unsigned int coord_count) const
{
const VariationValueRecord *record;
record = (VariationValueRecord *) bsearch (&tag, valuesZ.arrayZ,
valueRecordCount, valueRecordSize,
tag_compare);
record = (VariationValueRecord *) hb_bsearch (&tag, valuesZ.arrayZ,
valueRecordCount, valueRecordSize,
tag_compare);
if (!record)
return 0.;

View File

@ -24,13 +24,15 @@
* Google Author(s): Behdad Esfahbod
*/
#include "hb-open-type.hh"
#include "hb.hh"
#ifndef HB_NO_VAR
#include "hb-ot-var.h"
#include "hb-ot-face.hh"
#include "hb-ot-var-avar-table.hh"
#include "hb-ot-var-fvar-table.hh"
#include "hb-ot-var-mvar-table.hh"
#include "hb-ot-var.h"
/**
@ -213,3 +215,6 @@ hb_ot_var_normalize_coords (hb_face_t *face,
face->table.avar->map_coords (normalized_coords, coords_length);
}
#endif

View File

@ -69,102 +69,50 @@ struct VORG
return vertYOrigins[i].vertOriginY;
}
bool _subset (const hb_subset_plan_t *plan HB_UNUSED,
const VORG *vorg_table,
const hb_vector_t<VertOriginMetric> &subset_metrics,
unsigned int dest_sz,
void *dest) const
template <typename Iterator,
hb_requires (hb_is_iterator (Iterator))>
void serialize (hb_serialize_context_t *c,
Iterator it,
FWORD defaultVertOriginY)
{
hb_serialize_context_t c (dest, dest_sz);
VORG *subset_table = c.start_serialize<VORG> ();
if (unlikely (!c.extend_min (*subset_table)))
return false;
if (unlikely (!c->extend_min ((*this)))) return;
subset_table->version.major = 1;
subset_table->version.minor = 0;
this->version.major = 1;
this->version.minor = 0;
subset_table->defaultVertOriginY = vorg_table->defaultVertOriginY;
subset_table->vertYOrigins.len = subset_metrics.length;
this->defaultVertOriginY = defaultVertOriginY;
this->vertYOrigins.len = it.len ();
bool success = true;
if (subset_metrics.length > 0)
{
unsigned int size = VertOriginMetric::static_size * subset_metrics.length;
VertOriginMetric *metrics = c.allocate_size<VertOriginMetric> (size);
if (likely (metrics != nullptr))
memcpy (metrics, &subset_metrics[0], size);
else
success = false;
}
c.end_serialize ();
return success;
+ it
| hb_apply ([c] (const VertOriginMetric& _) { c->copy (_);})
;
}
bool subset (hb_subset_plan_t *plan) const
bool subset (hb_subset_context_t *c) const
{
hb_blob_t *vorg_blob = hb_sanitize_context_t().reference_table<VORG> (plan->source);
const VORG *vorg_table = vorg_blob->as<VORG> ();
TRACE_SUBSET (this);
VORG *vorg_prime = c->serializer->start_embed<VORG> ();
if (unlikely (!c->serializer->check_success (vorg_prime))) return_trace (false);
/* count the number of glyphs to be included in the subset table */
hb_vector_t<VertOriginMetric> subset_metrics;
subset_metrics.init ();
auto it =
+ vertYOrigins.as_array ()
| hb_filter (c->plan->glyphset (), &VertOriginMetric::glyph)
| hb_map ([&] (const VertOriginMetric& _)
{
hb_codepoint_t new_glyph = HB_SET_VALUE_INVALID;
c->plan->new_gid_for_old_gid (_.glyph, &new_glyph);
hb_codepoint_t old_glyph = HB_SET_VALUE_INVALID;
unsigned int i = 0;
while (i < vertYOrigins.len
&& plan->glyphset ()->next (&old_glyph))
{
while (old_glyph > vertYOrigins[i].glyph)
{
i++;
if (i >= vertYOrigins.len)
break;
}
if (old_glyph == vertYOrigins[i].glyph)
{
hb_codepoint_t new_glyph;
if (plan->new_gid_for_old_gid (old_glyph, &new_glyph))
{
VertOriginMetric *metrics = subset_metrics.push ();
metrics->glyph = new_glyph;
metrics->vertOriginY = vertYOrigins[i].vertOriginY;
}
}
}
/* alloc the new table */
unsigned int dest_sz = VORG::min_size + VertOriginMetric::static_size * subset_metrics.length;
void *dest = (void *) malloc (dest_sz);
if (unlikely (!dest))
{
subset_metrics.fini ();
hb_blob_destroy (vorg_blob);
return false;
}
VertOriginMetric metric;
metric.glyph = new_glyph;
metric.vertOriginY = _.vertOriginY;
return metric;
})
;
/* serialize the new table */
if (!_subset (plan, vorg_table, subset_metrics, dest_sz, dest))
{
subset_metrics.fini ();
free (dest);
hb_blob_destroy (vorg_blob);
return false;
}
hb_blob_t *result = hb_blob_create ((const char *)dest,
dest_sz,
HB_MEMORY_MODE_READONLY,
dest,
free);
bool success = plan->add_table (HB_OT_TAG_VORG, result);
hb_blob_destroy (result);
subset_metrics.fini ();
hb_blob_destroy (vorg_blob);
return success;
vorg_prime->serialize (c->serializer, it, defaultVertOriginY);
return_trace (true);
}
bool sanitize (hb_sanitize_context_t *c) const

View File

@ -375,7 +375,7 @@ struct hb_serialize_context_t
(Type *, src.copy (this, hb_forward<Ts> (ds)...))
template <typename Type> auto
_copy (const Type &src, hb_priority<0>) -> decltype (&(src = src))
_copy (const Type &src, hb_priority<0>) -> decltype (&(hb_declval<Type> () = src))
{
Type *ret = this->allocate_size<Type> (sizeof (Type));
if (unlikely (!ret)) return nullptr;

View File

@ -47,6 +47,6 @@ HB_SHAPER_IMPLEMENT (directwrite)
HB_SHAPER_IMPLEMENT (coretext)
#endif
#ifdef HAVE_FALLBACK
#ifndef HB_NO_FALLBACK_SHAPE
HB_SHAPER_IMPLEMENT (fallback) /* <--- This should be last. */
#endif

View File

@ -39,8 +39,8 @@
#ifndef HB_NO_VISIBILITY
#include "hb-ot-name-language-static.hh"
hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)] = {};
/*thread_local*/ hb_vector_size_impl_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)] = {};
uint64_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)] = {};
/*thread_local*/ uint64_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (uint64_t) - 1) / sizeof (uint64_t)] = {};
DEFINE_NULL_NAMESPACE_BYTES (OT, Index) = {0xFF,0xFF};
DEFINE_NULL_NAMESPACE_BYTES (OT, LangSys) = {0x00,0x00, 0xFF,0xFF, 0x00,0x00};

View File

@ -24,6 +24,10 @@
* Adobe Author(s): Michiharu Ariza
*/
#include "hb.hh"
#ifndef HB_NO_SUBSET_CFF
#include "hb-ot-cff-common.hh"
#include "hb-ot-cff2-table.hh"
#include "hb-subset-cff-common.hh"
@ -44,18 +48,18 @@ using namespace CFF;
bool
hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan,
unsigned int fdCount,
const FDSelect &src, /* IN */
unsigned int &subset_fd_count /* OUT */,
unsigned int &subset_fdselect_size /* OUT */,
unsigned int &subset_fdselect_format /* OUT */,
hb_vector_t<code_pair_t> &fdselect_ranges /* OUT */,
remap_t &fdmap /* OUT */)
unsigned int fdCount,
const FDSelect &src, /* IN */
unsigned int &subset_fd_count /* OUT */,
unsigned int &subset_fdselect_size /* OUT */,
unsigned int &subset_fdselect_format /* OUT */,
hb_vector_t<code_pair_t> &fdselect_ranges /* OUT */,
hb_inc_bimap_t &fdmap /* OUT */)
{
subset_fd_count = 0;
subset_fdselect_size = 0;
subset_fdselect_format = 0;
unsigned int num_ranges = 0;
unsigned int num_ranges = 0;
unsigned int subset_num_glyphs = plan->num_output_glyphs ();
if (subset_num_glyphs == 0)
@ -63,14 +67,14 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan,
{
/* use hb_set to determine the subset of font dicts */
hb_set_t *set = hb_set_create ();
hb_set_t *set = hb_set_create ();
if (set == &Null (hb_set_t))
return false;
hb_codepoint_t prev_fd = CFF_UNDEF_CODE;
hb_codepoint_t prev_fd = CFF_UNDEF_CODE;
for (hb_codepoint_t i = 0; i < subset_num_glyphs; i++)
{
hb_codepoint_t glyph;
hb_codepoint_t fd;
hb_codepoint_t glyph;
hb_codepoint_t fd;
if (!plan->old_gid_for_new_gid (i, &glyph))
{
/* fonttools retains FDSelect & font dicts for missing glyphs. do the same */
@ -98,17 +102,13 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan,
else
{
/* create a fdmap */
if (!fdmap.reset (fdCount))
{
hb_set_destroy (set);
return false;
}
fdmap.reset ();
hb_codepoint_t fd = CFF_UNDEF_CODE;
hb_codepoint_t fd = CFF_UNDEF_CODE;
while (set->next (&fd))
fdmap.add (fd);
hb_set_destroy (set);
if (unlikely (fdmap.get_count () != subset_fd_count))
if (unlikely (fdmap.get_population () != subset_fd_count))
return false;
}
@ -152,10 +152,10 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan,
template <typename FDSELECT3_4>
static inline bool
serialize_fdselect_3_4 (hb_serialize_context_t *c,
const unsigned int num_glyphs,
const FDSelect &src,
unsigned int size,
const hb_vector_t<code_pair_t> &fdselect_ranges)
const unsigned int num_glyphs,
const FDSelect &src,
unsigned int size,
const hb_vector_t<code_pair_t> &fdselect_ranges)
{
TRACE_SERIALIZE (this);
FDSELECT3_4 *p = c->allocate_size<FDSELECT3_4> (size);
@ -166,7 +166,7 @@ serialize_fdselect_3_4 (hb_serialize_context_t *c,
p->ranges[i].first = fdselect_ranges[i].glyph;
p->ranges[i].fd = fdselect_ranges[i].code;
}
p->sentinel() = num_glyphs;
p->sentinel () = num_glyphs;
return_trace (true);
}
@ -176,15 +176,15 @@ serialize_fdselect_3_4 (hb_serialize_context_t *c,
**/
bool
hb_serialize_cff_fdselect (hb_serialize_context_t *c,
const unsigned int num_glyphs,
const FDSelect &src,
unsigned int fd_count,
unsigned int fdselect_format,
unsigned int size,
const hb_vector_t<code_pair_t> &fdselect_ranges)
const unsigned int num_glyphs,
const FDSelect &src,
unsigned int fd_count,
unsigned int fdselect_format,
unsigned int size,
const hb_vector_t<code_pair_t> &fdselect_ranges)
{
TRACE_SERIALIZE (this);
FDSelect *p = c->allocate_min<FDSelect> ();
FDSelect *p = c->allocate_min<FDSelect> ();
if (unlikely (p == nullptr)) return_trace (false);
p->format = fdselect_format;
size -= FDSelect::min_size;
@ -192,42 +192,37 @@ hb_serialize_cff_fdselect (hb_serialize_context_t *c,
switch (fdselect_format)
{
#if CFF_SERIALIZE_FDSELECT_0
case 0:
case 0:
{
FDSelect0 *p = c->allocate_size<FDSelect0> (size);
if (unlikely (p == nullptr)) return_trace (false);
unsigned int range_index = 0;
unsigned int fd = fdselect_ranges[range_index++].code;
for (unsigned int i = 0; i < num_glyphs; i++)
{
FDSelect0 *p = c->allocate_size<FDSelect0> (size);
if (unlikely (p == nullptr)) return_trace (false);
unsigned int range_index = 0;
unsigned int fd = fdselect_ranges[range_index++].code;
for (unsigned int i = 0; i < num_glyphs; i++)
if ((range_index < fdselect_ranges.len) &&
(i >= fdselect_ranges[range_index].glyph))
{
if ((range_index < fdselect_ranges.len) &&
(i >= fdselect_ranges[range_index].glyph))
{
fd = fdselect_ranges[range_index++].code;
}
p->fds[i] = fd;
fd = fdselect_ranges[range_index++].code;
}
break;
p->fds[i] = fd;
}
return_trace (true);
}
#endif /* CFF_SERIALIZE_FDSELECT_0 */
case 3:
return serialize_fdselect_3_4<FDSelect3> (c,
num_glyphs,
src,
size,
fdselect_ranges);
case 3:
return serialize_fdselect_3_4<FDSelect3> (c, num_glyphs, src,
size, fdselect_ranges);
case 4:
return serialize_fdselect_3_4<FDSelect4> (c,
num_glyphs,
src,
size,
fdselect_ranges);
case 4:
return serialize_fdselect_3_4<FDSelect4> (c, num_glyphs, src,
size, fdselect_ranges);
default:
assert(false);
default:
return_trace (false);
}
return_trace (true);
}
#endif

View File

@ -541,39 +541,29 @@ struct subr_subset_param_t
bool drop_hints;
};
struct subr_remap_t : remap_t
struct subr_remap_t : hb_inc_bimap_t
{
void create (hb_set_t *closure)
{
/* create a remapping of subroutine numbers from old to new.
* no optimization based on usage counts. fonttools doesn't appear doing that either.
*/
reset (closure->get_max () + 1);
for (hb_codepoint_t old_num = 0; old_num < length; old_num++)
{
if (hb_set_has (closure, old_num))
add (old_num);
}
hb_codepoint_t old_num = HB_SET_VALUE_INVALID;
while (hb_set_next (closure, &old_num))
add (old_num);
if (get_count () < 1240)
if (get_population () < 1240)
bias = 107;
else if (get_count () < 33900)
else if (get_population () < 33900)
bias = 1131;
else
bias = 32768;
}
hb_codepoint_t operator[] (unsigned int old_num) const
{
if (old_num >= length)
return CFF_UNDEF_CODE;
else
return remap_t::operator[] (old_num);
}
int biased_num (unsigned int old_num) const
{
hb_codepoint_t new_num = (*this)[old_num];
hb_codepoint_t new_num = get (old_num);
return (int)new_num - bias;
}
@ -581,15 +571,15 @@ struct subr_remap_t : remap_t
int bias;
};
struct subr_remap_ts
struct subr_remaps_t
{
subr_remap_ts ()
subr_remaps_t ()
{
global_remap.init ();
local_remaps.init ();
}
~subr_remap_ts () { fini (); }
~subr_remaps_t () { fini (); }
void init (unsigned int fdCount)
{
@ -765,7 +755,7 @@ struct subr_subsetter_t
bool encode_subrs (const parsed_cs_str_vec_t &subrs, const subr_remap_t& remap, unsigned int fd, str_buff_vec_t &buffArray) const
{
unsigned int count = remap.get_count ();
unsigned int count = remap.get_population ();
if (unlikely (!buffArray.resize (count)))
return false;
@ -1005,7 +995,7 @@ struct subr_subsetter_t
parsed_cs_str_vec_t parsed_global_subrs;
hb_vector_t<parsed_cs_str_vec_t> parsed_local_subrs;
subr_remap_ts remaps;
subr_remaps_t remaps;
private:
typedef typename SUBRS::count_type subr_count_type;
@ -1021,7 +1011,7 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan,
unsigned int &subset_fdselect_size /* OUT */,
unsigned int &subset_fdselect_format /* OUT */,
hb_vector_t<CFF::code_pair_t> &fdselect_ranges /* OUT */,
CFF::remap_t &fdmap /* OUT */);
hb_inc_bimap_t &fdmap /* OUT */);
HB_INTERNAL bool
hb_serialize_cff_fdselect (hb_serialize_context_t *c,

View File

@ -24,24 +24,27 @@
* Adobe Author(s): Michiharu Ariza
*/
#include "hb.hh"
#ifndef HB_NO_SUBSET_CFF
#include "hb-open-type.hh"
#include "hb-ot-cff1-table.hh"
#include "hb-set.h"
#include "hb-bimap.hh"
#include "hb-subset-cff1.hh"
#include "hb-subset-plan.hh"
#include "hb-subset-cff-common.hh"
#include "hb-cff1-interp-cs.hh"
#ifndef HB_NO_SUBSET_CFF
using namespace CFF;
struct remap_sid_t : remap_t
struct remap_sid_t : hb_inc_bimap_t
{
unsigned int add (unsigned int sid)
{
if ((sid != CFF_UNDEF_SID) && !is_std_std (sid))
return offset_sid (remap_t::add (unoffset_sid (sid)));
return offset_sid (hb_inc_bimap_t::add (unoffset_sid (sid)));
else
return sid;
}
@ -51,7 +54,7 @@ struct remap_sid_t : remap_t
if (is_std_std (sid) || (sid == CFF_UNDEF_SID))
return sid;
else
return offset_sid (remap_t::operator [] (unoffset_sid (sid)));
return offset_sid (get (unoffset_sid (sid)));
}
static const unsigned int num_std_strings = 391;
@ -579,8 +582,7 @@ struct cff_subset_plan {
bool collect_sids_in_dicts (const OT::cff1::accelerator_subset_t &acc)
{
if (unlikely (!sidmap.reset (acc.stringIndex->count)))
return false;
sidmap.reset ();
for (unsigned int i = 0; i < name_dict_values_t::ValCount; i++)
{
@ -594,7 +596,7 @@ struct cff_subset_plan {
if (acc.fdArray != &Null(CFF1FDArray))
for (unsigned int i = 0; i < orig_fdcount; i++)
if (fdmap.includes (i))
if (fdmap.has (i))
(void)sidmap.add (acc.fontDicts[i].fontName);
return true;
@ -680,7 +682,7 @@ struct cff_subset_plan {
/* SIDs for name strings in dicts are added before glyph names so they fit in 16-bit int range */
if (unlikely (!collect_sids_in_dicts (acc)))
return false;
if (unlikely (sidmap.get_count () > 0x8000)) /* assumption: a dict won't reference that many strings */
if (unlikely (sidmap.get_population () > 0x8000)) /* assumption: a dict won't reference that many strings */
return false;
if (subset_charset)
offsets.charsetInfo.size = plan_subset_charset (acc, plan);
@ -737,7 +739,7 @@ struct cff_subset_plan {
{
subset_localsubrs[fd].init ();
offsets.localSubrsInfos[fd].init ();
if (fdmap.includes (fd))
if (fdmap.has (fd))
{
if (!subr_subsetter.encode_localsubrs (fd, subset_localsubrs[fd]))
return false;
@ -788,7 +790,7 @@ struct cff_subset_plan {
cff1_font_dict_op_serializer_t fontSzr;
unsigned int dictsSize = 0;
for (unsigned int i = 0; i < acc.fontDicts.length; i++)
if (fdmap.includes (i))
if (fdmap.has (i))
dictsSize += FontDict::calculate_serialized_size (acc.fontDicts[i], fontSzr);
offsets.FDArrayInfo.offSize = calcOffSize (dictsSize);
@ -811,7 +813,7 @@ struct cff_subset_plan {
offsets.privateDictInfo.offset = final_size;
for (unsigned int i = 0; i < orig_fdcount; i++)
{
if (fdmap.includes (i))
if (fdmap.has (i))
{
bool has_localsubrs = offsets.localSubrsInfos[i].size > 0;
cff_private_dict_op_serializer_t privSzr (desubroutinize, plan->drop_hints);
@ -855,7 +857,7 @@ struct cff_subset_plan {
/* font dict index remap table from fullset FDArray to subset FDArray.
* set to CFF_UNDEF_CODE if excluded from subset */
remap_t fdmap;
hb_inc_bimap_t fdmap;
str_buff_vec_t subset_charstrings;
str_buff_vec_t subset_globalsubrs;
@ -1032,7 +1034,7 @@ static inline bool _write_cff1 (const cff_subset_plan &plan,
assert (plan.offsets.privateDictInfo.offset == (unsigned) (c.head - c.start));
for (unsigned int i = 0; i < acc.privateDicts.length; i++)
{
if (plan.fdmap.includes (i))
if (plan.fdmap.has (i))
{
PrivateDict *pd = c.start_embed<PrivateDict> ();
if (unlikely (pd == nullptr)) return false;
@ -1040,7 +1042,7 @@ static inline bool _write_cff1 (const cff_subset_plan &plan,
bool result;
cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints);
/* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
unsigned int subroffset = (plan.offsets.localSubrsInfos[i].size > 0)? priv_size: 0;
unsigned int subroffset = (plan.offsets.localSubrsInfos[i].size > 0) ? priv_size : 0;
result = pd->serialize (&c, acc.privateDicts[i], privSzr, subroffset);
if (unlikely (!result))
{
@ -1121,4 +1123,5 @@ hb_subset_cff1 (hb_subset_plan_t *plan,
return result;
}
#endif

View File

@ -24,6 +24,10 @@
* Adobe Author(s): Michiharu Ariza
*/
#include "hb.hh"
#ifndef HB_NO_SUBSET_CFF
#include "hb-open-type.hh"
#include "hb-ot-cff2-table.hh"
#include "hb-set.h"
@ -32,8 +36,6 @@
#include "hb-subset-cff-common.hh"
#include "hb-cff2-interp-cs.hh"
#ifndef HB_NO_SUBSET_CFF
using namespace CFF;
struct cff2_sub_table_offsets_t : cff_sub_table_offsets_t
@ -328,18 +330,15 @@ struct cff2_subset_plan {
{
subset_localsubrs[fd].init ();
offsets.localSubrsInfos[fd].init ();
if (fdmap.includes (fd))
{
if (!subr_subsetter.encode_localsubrs (fd, subset_localsubrs[fd]))
return false;
if (!subr_subsetter.encode_localsubrs (fd, subset_localsubrs[fd]))
return false;
unsigned int dataSize = subset_localsubrs[fd].total_size ();
if (dataSize > 0)
{
offsets.localSubrsInfos[fd].offset = final_size;
offsets.localSubrsInfos[fd].offSize = calcOffSize (dataSize);
offsets.localSubrsInfos[fd].size = CFF2Subrs::calculate_serialized_size (offsets.localSubrsInfos[fd].offSize, subset_localsubrs[fd].length, dataSize);
}
unsigned int dataSize = subset_localsubrs[fd].total_size ();
if (dataSize > 0)
{
offsets.localSubrsInfos[fd].offset = final_size;
offsets.localSubrsInfos[fd].offSize = calcOffSize (dataSize);
offsets.localSubrsInfos[fd].size = CFF2Subrs::calculate_serialized_size (offsets.localSubrsInfos[fd].offSize, subset_localsubrs[fd].length, dataSize);
}
}
}
@ -380,7 +379,7 @@ struct cff2_subset_plan {
cff_font_dict_op_serializer_t fontSzr;
unsigned int dictsSize = 0;
for (unsigned int i = 0; i < acc.fontDicts.length; i++)
if (fdmap.includes (i))
if (fdmap.has (i))
dictsSize += FontDict::calculate_serialized_size (acc.fontDicts[i], fontSzr);
offsets.FDArrayInfo.offSize = calcOffSize (dictsSize);
@ -399,7 +398,7 @@ struct cff2_subset_plan {
offsets.privateDictsOffset = final_size;
for (unsigned int i = 0; i < orig_fdcount; i++)
{
if (fdmap.includes (i))
if (fdmap.has (i))
{
bool has_localsubrs = offsets.localSubrsInfos[i].size > 0;
cff_private_dict_op_serializer_t privSzr (desubroutinize, drop_hints);
@ -429,7 +428,7 @@ struct cff2_subset_plan {
unsigned int subset_fdselect_format;
hb_vector_t<code_pair_t> subset_fdselect_ranges;
remap_t fdmap;
hb_inc_bimap_t fdmap;
str_buff_vec_t subset_charstrings;
str_buff_vec_t subset_globalsubrs;
@ -539,7 +538,7 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan,
assert (plan.offsets.privateDictsOffset == (unsigned) (c.head - c.start));
for (unsigned int i = 0; i < acc.privateDicts.length; i++)
{
if (plan.fdmap.includes (i))
if (plan.fdmap.has (i))
{
PrivateDict *pd = c.start_embed<PrivateDict> ();
if (unlikely (pd == nullptr)) return false;
@ -547,7 +546,7 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan,
bool result;
cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints);
/* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
unsigned int subroffset = (plan.offsets.localSubrsInfos[i].size > 0)? priv_size: 0;
unsigned int subroffset = (plan.offsets.localSubrsInfos[i].size > 0) ? priv_size : 0;
result = pd->serialize (&c, acc.privateDicts[i], privSzr, subroffset);
if (unlikely (!result))
{
@ -629,4 +628,5 @@ hb_subset_cff2 (hb_subset_plan_t *plan,
return result;
}
#endif

View File

@ -194,23 +194,12 @@ static void
_nameid_closure (hb_face_t *face,
hb_set_t *nameids)
{
hb_tag_t table_tags[32];
unsigned count = ARRAY_LENGTH (table_tags);
hb_face_get_table_tags (face, 0, &count, table_tags);
for (unsigned int i = 0; i < count; i++)
{
hb_tag_t tag = table_tags[i];
switch (tag) {
case HB_OT_TAG_STAT:
face->table.STAT->collect_name_ids (nameids);
break;
case HB_OT_TAG_fvar:
face->table.fvar->collect_name_ids (nameids);
break;
default:
break;
}
}
#ifndef HB_NO_STAT
face->table.STAT->collect_name_ids (nameids);
#endif
#ifndef HB_NO_VAR
face->table.fvar->collect_name_ids (nameids);
#endif
}
/**

View File

@ -67,7 +67,7 @@ template<typename TableType>
static bool
_subset2 (hb_subset_plan_t *plan)
{
bool result = true;
bool result = false;
hb_blob_t *source_blob = hb_sanitize_context_t ().reference_table<TableType> (plan->source);
const TableType *table = source_blob->as<TableType> ();
@ -172,16 +172,16 @@ _subset_table (hb_subset_plan_t *plan,
DEBUG_MSG(SUBSET, nullptr, "skip hhea handled by hmtx");
return true;
case HB_OT_TAG_hmtx:
result = _subset<const OT::hmtx> (plan);
result = _subset2<const OT::hmtx> (plan);
break;
case HB_OT_TAG_vhea:
DEBUG_MSG(SUBSET, nullptr, "skip vhea handled by vmtx");
return true;
case HB_OT_TAG_vmtx:
result = _subset<const OT::vmtx> (plan);
result = _subset2<const OT::vmtx> (plan);
break;
case HB_OT_TAG_maxp:
result = _subset<const OT::maxp> (plan);
result = _subset2<const OT::maxp> (plan);
break;
case HB_OT_TAG_loca:
DEBUG_MSG(SUBSET, nullptr, "skip loca handled by glyf");
@ -190,10 +190,10 @@ _subset_table (hb_subset_plan_t *plan,
result = _subset<const OT::cmap> (plan);
break;
case HB_OT_TAG_OS2:
result = _subset<const OT::OS2> (plan);
result = _subset2<const OT::OS2> (plan);
break;
case HB_OT_TAG_post:
result = _subset<const OT::post> (plan);
result = _subset2<const OT::post> (plan);
break;
#ifndef HB_NO_SUBSET_CFF
@ -204,7 +204,7 @@ _subset_table (hb_subset_plan_t *plan,
result = _subset<const OT::cff2> (plan);
break;
case HB_OT_TAG_VORG:
result = _subset<const OT::VORG> (plan);
result = _subset2<const OT::VORG> (plan);
break;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -114,6 +114,14 @@ _cmp_pair (const void *_key, const void *_item)
return a < b ? -1 : a > b ? +1 : 0;
}
static int
_cmp_pair_11_7_14 (const void *_key, const void *_item)
{
uint32_t& a = * (uint32_t*) _key;
uint32_t b = (* (uint32_t*) _item) & HB_CODEPOINT_ENCODE3_11_7_14(0x1FFFFFu, 0x1FFFFFu, 0);
return a < b ? -1 : a > b ? +1 : 0;
}
static hb_bool_t
hb_ucd_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
@ -122,16 +130,30 @@ hb_ucd_compose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
{
if (_hb_ucd_compose_hangul (a, b, ab)) return true;
uint64_t k = HB_CODEPOINT_ENCODE3 (a, b, 0);
uint64_t *v = (uint64_t*) hb_bsearch (&k, _hb_ucd_dm2_map,
ARRAY_LENGTH (_hb_ucd_dm2_map),
sizeof (*_hb_ucd_dm2_map),
_cmp_pair);
if (likely (!v)) return false;
hb_codepoint_t u = 0;
if ((a & 0xFFFFF800u) == 0x0000u && (b & 0xFFFFFF80) == 0x0300u)
{
uint32_t k = HB_CODEPOINT_ENCODE3_11_7_14 (a, b, 0);
uint32_t *v = (uint32_t*) hb_bsearch (&k, _hb_ucd_dm2_u32_map,
ARRAY_LENGTH (_hb_ucd_dm2_u32_map),
sizeof (*_hb_ucd_dm2_u32_map),
_cmp_pair_11_7_14);
if (likely (!v)) return false;
u = HB_CODEPOINT_DECODE3_11_7_14_3 (*v);
}
else
{
uint64_t k = HB_CODEPOINT_ENCODE3 (a, b, 0);
uint64_t *v = (uint64_t*) hb_bsearch (&k, _hb_ucd_dm2_u64_map,
ARRAY_LENGTH (_hb_ucd_dm2_u64_map),
sizeof (*_hb_ucd_dm2_u64_map),
_cmp_pair);
if (likely (!v)) return false;
u = HB_CODEPOINT_DECODE3_3 (*v);
}
hb_codepoint_t u = HB_CODEPOINT_DECODE3_3 (*v);
if (unlikely (!u)) return false;
*ab = u;
return true;
}
@ -148,15 +170,30 @@ hb_ucd_decompose (hb_unicode_funcs_t *ufuncs HB_UNUSED,
if (likely (!i)) return false;
i--;
if (i < ARRAY_LENGTH (_hb_ucd_dm1_map))
if (i < ARRAY_LENGTH (_hb_ucd_dm1_p0_map) + ARRAY_LENGTH (_hb_ucd_dm1_p2_map))
{
*a = _hb_ucd_dm1_map[i];
if (i < ARRAY_LENGTH (_hb_ucd_dm1_p0_map))
*a = _hb_ucd_dm1_p0_map[i];
else
{
i -= ARRAY_LENGTH (_hb_ucd_dm1_p0_map);
*a = 0x20000 | _hb_ucd_dm1_p2_map[i];
}
*b = 0;
return true;
}
i -= ARRAY_LENGTH (_hb_ucd_dm1_map);
i -= ARRAY_LENGTH (_hb_ucd_dm1_p0_map) + ARRAY_LENGTH (_hb_ucd_dm1_p2_map);
uint64_t v = _hb_ucd_dm2_map[i];
if (i < ARRAY_LENGTH (_hb_ucd_dm2_u32_map))
{
uint32_t v = _hb_ucd_dm2_u32_map[i];
*a = HB_CODEPOINT_DECODE3_11_7_14_1 (v);
*b = HB_CODEPOINT_DECODE3_11_7_14_2 (v);
return true;
}
i -= ARRAY_LENGTH (_hb_ucd_dm2_u32_map);
uint64_t v = _hb_ucd_dm2_u64_map[i];
*a = HB_CODEPOINT_DECODE3_1 (v);
*b = HB_CODEPOINT_DECODE3_2 (v);
return true;

View File

@ -326,11 +326,11 @@ DECLARE_NULL_INSTANCE (hb_unicode_funcs_t);
*
* Modify Telugu length marks (ccc=84, ccc=91).
* These are the only matras in the main Indic scripts range that have
* a non-zero ccc. That makes them reorder with the Halant that is
* ccc=9. Just zero them, we don't need them in our Indic shaper.
* a non-zero ccc. That makes them reorder with the Halant (ccc=9).
* Assign 5 and 6, which are otherwise unassigned.
*/
#define HB_MODIFIED_COMBINING_CLASS_CCC84 0 /* length mark */
#define HB_MODIFIED_COMBINING_CLASS_CCC91 0 /* ai length mark */
#define HB_MODIFIED_COMBINING_CLASS_CCC84 5 /* length mark */
#define HB_MODIFIED_COMBINING_CLASS_CCC91 6 /* ai length mark */
/* Thai
*

View File

@ -25,12 +25,19 @@
*/
#include "hb.hh"
#ifdef HAVE_UNISCRIBE
#include "hb-shaper-impl.hh"
#include <windows.h>
#include <usp10.h>
#include <rpc.h>
#ifndef E_NOT_SUFFICIENT_BUFFER
#define E_NOT_SUFFICIENT_BUFFER HRESULT_FROM_WIN32 (ERROR_INSUFFICIENT_BUFFER)
#endif
#include "hb-uniscribe.h"
#include "hb-open-file.hh"
@ -717,7 +724,7 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan,
HB_STMT_START { \
DEBUG_MSG (UNISCRIBE, nullptr, __VA_ARGS__); \
return false; \
} HB_STMT_END;
} HB_STMT_END
HRESULT hr;
@ -1019,3 +1026,4 @@ retry:
}
#endif

View File

@ -38,9 +38,9 @@ HB_BEGIN_DECLS
#define HB_VERSION_MAJOR 2
#define HB_VERSION_MINOR 5
#define HB_VERSION_MICRO 1
#define HB_VERSION_MICRO 3
#define HB_VERSION_STRING "2.5.1"
#define HB_VERSION_STRING "2.5.3"
#define HB_VERSION_ATLEAST(major,minor,micro) \
((major)*10000+(minor)*100+(micro) <= \

View File

@ -66,7 +66,7 @@
#pragma GCC diagnostic error "-Wcast-align"
#pragma GCC diagnostic error "-Wcast-function-type"
#pragma GCC diagnostic error "-Wdelete-non-virtual-dtor"
#pragma GCC diagnostic error "-Wdouble-promotion"
#pragma GCC diagnostic error "-Wembedded-directive"
#pragma GCC diagnostic error "-Wextra-semi-stmt"
#pragma GCC diagnostic error "-Wformat-security"
#pragma GCC diagnostic error "-Wimplicit-function-declaration"
@ -99,6 +99,7 @@
#pragma GCC diagnostic warning "-Wbuiltin-macro-redefined"
#pragma GCC diagnostic warning "-Wdeprecated"
#pragma GCC diagnostic warning "-Wdisabled-optimization"
#pragma GCC diagnostic warning "-Wdouble-promotion"
#pragma GCC diagnostic warning "-Wformat=2"
#pragma GCC diagnostic warning "-Wignored-pragma-optimize"
#pragma GCC diagnostic warning "-Wlogical-op"
@ -183,8 +184,15 @@
#include <stdarg.h>
#if (defined(_MSC_VER) && _MSC_VER >= 1500) || defined(__MINGW32__)
#ifdef __MINGW32_VERSION
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN 1
#endif
#include <windows.h>
#else
#include <intrin.h>
#endif
#endif
#define HB_PASTE1(a,b) a##b
#define HB_PASTE(a,b) HB_PASTE1(a,b)
@ -204,14 +212,6 @@ extern "C" void hb_free_impl(void *ptr);
#define calloc hb_calloc_impl
#define realloc hb_realloc_impl
#define free hb_free_impl
#ifdef hb_memalign_impl
extern "C" int hb_memalign_impl(void **memptr, size_t alignment, size_t size);
#define posix_memalign hb_memalign_impl
#else
#undef HAVE_POSIX_MEMALIGN
#endif
#endif
@ -352,7 +352,7 @@ extern "C" int hb_memalign_impl(void **memptr, size_t alignment, size_t size);
# define HB_NO_GETENV
# endif
# if _WIN32_WCE < 0x800
# define setlocale(Category, Locale) "C"
# define HB_NO_SETLOCALE
static int errno = 0; /* Use something better? */
# endif
# elif defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_PC_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP)
@ -436,38 +436,6 @@ static_assert ((sizeof (hb_var_int_t) == 4), "");
void operator=(const TypeName&) = delete
/*
* Compiler-assisted vectorization parameters.
*/
/*
* Disable vectorization for now. To correctly use them, we should
* use posix_memalign() to allocate in hb_vector_t. Otherwise, can
* cause misaligned access.
*
* https://bugs.chromium.org/p/chromium/issues/detail?id=860184
*/
#ifndef HB_VECTOR_SIZE
# define HB_VECTOR_SIZE 0
#endif
/* The `vector_size' attribute was introduced in gcc 3.1. */
#ifndef HB_VECTOR_SIZE
# if defined( __GNUC__ ) && ( __GNUC__ >= 4 )
# define HB_VECTOR_SIZE 128
# else
# define HB_VECTOR_SIZE 0
# endif
#endif
static_assert (0 == (HB_VECTOR_SIZE & (HB_VECTOR_SIZE - 1)), "HB_VECTOR_SIZE is not power of 2.");
static_assert (0 == (HB_VECTOR_SIZE % 64), "HB_VECTOR_SIZE is not multiple of 64.");
#if HB_VECTOR_SIZE
typedef uint64_t hb_vector_size_impl_t __attribute__((vector_size (HB_VECTOR_SIZE / 8)));
#else
typedef uint64_t hb_vector_size_impl_t;
#endif
/* Flags */
/* Enable bitwise ops on enums marked as flags_t */
@ -508,46 +476,6 @@ typedef uint64_t hb_vector_size_impl_t;
#define VAR 1
/* fallback for round() */
static inline double
_hb_round (double x)
{
if (x >= 0)
return floor (x + 0.5);
else
return ceil (x - 0.5);
}
#if !defined (HAVE_ROUND) && !defined (HAVE_DECL_ROUND)
#define round(x) _hb_round(x)
#endif
/* fallback for posix_memalign() */
static inline int
_hb_memalign(void **memptr, size_t alignment, size_t size)
{
if (unlikely (0 != (alignment & (alignment - 1)) ||
!alignment ||
0 != (alignment & (sizeof (void *) - 1))))
return EINVAL;
char *p = (char *) malloc (size + alignment - 1);
if (unlikely (!p))
return ENOMEM;
size_t off = (size_t) p & (alignment - 1);
if (off)
p += alignment - off;
*memptr = (void *) p;
return 0;
}
#if !defined(posix_memalign) && !defined(HAVE_POSIX_MEMALIGN)
#define posix_memalign _hb_memalign
#endif
/*
* Big-endian integers. Here because fundamental.
*/

View File

@ -38,6 +38,10 @@
using namespace OT;
#ifdef HB_NO_OPEN
#define hb_blob_create_from_file(x) hb_blob_get_empty ()
#endif
int
main (int argc, char **argv)
{

View File

@ -101,6 +101,7 @@ DEFINES['PACKAGE_VERSION'] = '"moz"'
DEFINES['PACKAGE_BUGREPORT'] = '"http://bugzilla.mozilla.org/"'
DEFINES['HAVE_OT'] = 1
DEFINES['HAVE_ROUND'] = 1
DEFINES['HB_NO_FALLBACK_SHAPE'] = True
DEFINES['HB_NO_MT'] = True
DEFINES['HB_NO_UCD'] = True
DEFINES['HB_NO_UNICODE_FUNCS'] = True

View File

@ -34,9 +34,17 @@
#include <stdio.h>
#ifdef HB_NO_OPEN
#define hb_blob_create_from_file(x) hb_blob_get_empty ()
#endif
int
main (int argc, char **argv)
{
bool ret = true;
#ifndef HB_NO_BUFFER_SERIALIZE
if (argc != 2) {
fprintf (stderr, "usage: %s font-file\n", argv[0]);
exit (1);
@ -59,7 +67,6 @@ main (int argc, char **argv)
hb_buffer_t *buf;
buf = hb_buffer_create ();
bool ret = true;
char line[BUFSIZ], out[BUFSIZ];
while (fgets (line, sizeof(line), stdin) != nullptr)
{
@ -85,5 +92,7 @@ main (int argc, char **argv)
hb_font_destroy (font);
#endif
return !ret;
}

View File

@ -31,6 +31,10 @@
#include <stdio.h>
#ifdef HB_NO_OPEN
#define hb_blob_create_from_file(x) hb_blob_get_empty ()
#endif
int
main (int argc, char **argv)
{
@ -45,10 +49,15 @@ main (int argc, char **argv)
hb_blob_destroy (blob);
blob = nullptr;
unsigned int p[5];
bool ret = hb_ot_layout_get_size_params (face, p, p+1, (p+2), p+3, p+4);
bool ret = true;
#ifndef HB_NO_LAYOUT_FEATURE_PARAMS
unsigned int p[5];
ret = hb_ot_layout_get_size_params (face, p, p+1, (p+2), p+3, p+4);
printf ("%g %u %u %g %g\n", p[0]/10., p[1], p[2], p[3]/10., p[4]/10.);
#endif
hb_face_destroy (face);
return !ret;
}

View File

@ -35,6 +35,10 @@
#include "hb-ft.h"
#endif
#ifdef HB_NO_OPEN
#define hb_blob_create_from_file(x) hb_blob_get_empty ()
#endif
int
main (int argc, char **argv)
{

View File

@ -23,7 +23,16 @@
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
#include "hb.h"
#include "hb.hh"
#include <cairo.h>
#ifdef HB_NO_OPEN
#define hb_blob_create_from_file(x) hb_blob_get_empty ()
#endif
#if !defined(HB_NO_COLOR) && defined(CAIRO_HAS_SVG_SURFACE)
#include "hb-ot.h"
#include "hb-ft.h"
@ -32,7 +41,6 @@
#include FT_FREETYPE_H
#include FT_GLYPH_H
#include <cairo.h>
#include <cairo-ft.h>
#include <cairo-svg.h>
@ -133,7 +141,7 @@ layered_glyph_dump (hb_face_t *face, cairo_font_face_t *cairo_face, unsigned int
unsigned glyph_count = hb_face_get_glyph_count (face);
for (hb_codepoint_t gid = 0; gid < glyph_count; ++gid)
{
unsigned int num_layers = hb_ot_color_glyph_get_layers (face, gid, 0, NULL, NULL);
unsigned int num_layers = hb_ot_color_glyph_get_layers (face, gid, 0, nullptr, nullptr);
if (!num_layers)
continue;
@ -169,7 +177,7 @@ layered_glyph_dump (hb_face_t *face, cairo_font_face_t *cairo_face, unsigned int
unsigned int palette_count = hb_ot_color_palette_get_count (face);
for (unsigned int palette = 0; palette < palette_count; palette++)
{
unsigned int num_colors = hb_ot_color_palette_get_colors (face, palette, 0, NULL, NULL);
unsigned int num_colors = hb_ot_color_palette_get_colors (face, palette, 0, nullptr, nullptr);
if (!num_colors)
continue;
@ -271,14 +279,14 @@ main (int argc, char **argv)
FILE *font_name_file = fopen ("out/.dumped_font_name", "r");
if (font_name_file != NULL)
if (font_name_file != nullptr)
{
fprintf (stderr, "Purge or move ./out folder in order to run a new dump\n");
exit (1);
}
font_name_file = fopen ("out/.dumped_font_name", "w");
if (font_name_file == NULL)
if (font_name_file == nullptr)
{
fprintf (stderr, "./out is not accessible as a folder, create it please\n");
exit (1);
@ -334,3 +342,7 @@ main (int argc, char **argv)
return 0;
}
#else
int main (int argc, char **argv) { return 0; }
#endif

View File

@ -30,6 +30,10 @@
#include <stdlib.h>
#include <stdio.h>
#ifdef HB_NO_OPEN
#define hb_blob_create_from_file(x) hb_blob_get_empty ()
#endif
int
main (int argc, char **argv)
{
@ -43,7 +47,9 @@ main (int argc, char **argv)
hb_blob_destroy (blob);
blob = nullptr;
unsigned int count;
unsigned int count = 0;
#ifndef HB_NO_NAME
const hb_ot_name_entry_t *entries = hb_ot_name_list_names (face, &count);
for (unsigned int i = 0; i < count; i++)
@ -62,6 +68,7 @@ main (int argc, char **argv)
printf ("%s\n", buf);
}
#endif
hb_face_destroy (face);

View File

@ -34,6 +34,10 @@
#include "hb-ft.h"
#endif
#ifdef HB_NO_OPEN
#define hb_blob_create_from_file(x) hb_blob_get_empty ()
#endif
int
main (int argc, char **argv)
{

View File

@ -5,7 +5,7 @@
MY_TEMP_DIR=`mktemp -d -t harfbuzz_update.XXXXXX` || exit 1
VERSION=2.5.1
VERSION=2.5.3
git clone https://github.com/harfbuzz/harfbuzz ${MY_TEMP_DIR}/harfbuzz
git -C ${MY_TEMP_DIR}/harfbuzz checkout ${VERSION}