Merge branch 'master' into cff-subset
This commit is contained in:
commit
45e564a519
19
NEWS
19
NEWS
|
@ -1,3 +1,22 @@
|
|||
Overview of changes leading to 1.9.0
|
||||
Monday, September 10, 2018
|
||||
====================================
|
||||
- Added 'cmap' API to hb_face_t.
|
||||
- Face-builder API.
|
||||
- hb-ot-font re-creation should be much leaner now, as the
|
||||
font tables it uses are cached on hb_face_t now.
|
||||
- Internal source header file name changes:
|
||||
hb-*-private.hh is renamed to hb-*.hh.
|
||||
|
||||
New API:
|
||||
+HB_UNICODE_MAX
|
||||
+hb_face_collect_unicodes()
|
||||
+hb_face_collect_variation_selectors()
|
||||
+hb_face_collect_variation_unicodes()
|
||||
+hb_face_builder_create()
|
||||
+hb_face_builder_add_table()
|
||||
|
||||
|
||||
Overview of changes leading to 1.8.8
|
||||
Tuesday, August 14, 2018
|
||||
====================================
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
AC_PREREQ([2.64])
|
||||
AC_INIT([HarfBuzz],
|
||||
[1.8.8],
|
||||
[1.9.0],
|
||||
[https://github.com/harfbuzz/harfbuzz/issues/new],
|
||||
[harfbuzz],
|
||||
[http://harfbuzz.org/])
|
||||
|
|
|
@ -582,6 +582,8 @@ hb_set_union
|
|||
|
||||
<SECTION>
|
||||
<FILE>hb-shape</FILE>
|
||||
HB_FEATURE_GLOBAL_END
|
||||
HB_FEATURE_GLOBAL_START
|
||||
hb_feature_t
|
||||
hb_feature_from_string
|
||||
hb_feature_to_string
|
||||
|
|
|
@ -7,6 +7,7 @@ HB_BASE_sources = \
|
|||
hb-buffer.hh \
|
||||
hb-buffer-serialize.cc \
|
||||
hb-buffer.cc \
|
||||
hb-cache.hh \
|
||||
hb-common.cc \
|
||||
hb-debug.hh \
|
||||
hb-dsalgs.hh \
|
||||
|
|
|
@ -67,11 +67,11 @@ struct BinSearchArrayOf
|
|||
inline const Type& operator [] (unsigned int i) const
|
||||
{
|
||||
if (unlikely (i >= header.nUnits)) return Null(Type);
|
||||
return StructAtOffset<Type> (bytesZ, i * header.unitSize);
|
||||
return StructAtOffset<Type> (&bytesZ, i * header.unitSize);
|
||||
}
|
||||
inline Type& operator [] (unsigned int i)
|
||||
{
|
||||
return StructAtOffset<Type> (bytesZ, i * header.unitSize);
|
||||
return StructAtOffset<Type> (&bytesZ, i * header.unitSize);
|
||||
}
|
||||
inline unsigned int get_size (void) const
|
||||
{ return header.static_size + header.nUnits * header.unitSize; }
|
||||
|
@ -88,7 +88,7 @@ struct BinSearchArrayOf
|
|||
* pointed to do have a simple sanitize(), ie. they do not
|
||||
* reference other structs via offsets.
|
||||
*/
|
||||
(void) (false && StructAtOffset<Type> (bytesZ, 0).sanitize (c));
|
||||
(void) (false && StructAtOffset<Type> (&bytesZ, 0).sanitize (c));
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ struct BinSearchArrayOf
|
|||
while (min <= max)
|
||||
{
|
||||
int mid = (min + max) / 2;
|
||||
const Type *p = (const Type *) (((const char *) bytesZ) + (mid * size));
|
||||
const Type *p = (const Type *) (((const char *) &bytesZ) + (mid * size));
|
||||
int c = p->cmp (key);
|
||||
if (c < 0)
|
||||
max = mid - 1;
|
||||
|
@ -129,12 +129,12 @@ struct BinSearchArrayOf
|
|||
TRACE_SANITIZE (this);
|
||||
return_trace (header.sanitize (c) &&
|
||||
Type::static_size >= header.unitSize &&
|
||||
c->check_array (bytesZ, header.unitSize, header.nUnits));
|
||||
c->check_array (bytesZ.arrayZ, header.nUnits, header.unitSize));
|
||||
}
|
||||
|
||||
protected:
|
||||
BinSearchHeader header;
|
||||
HBUINT8 bytesZ[VAR];
|
||||
UnsizedArrayOf<HBUINT8> bytesZ;
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (10, bytesZ);
|
||||
};
|
||||
|
@ -480,8 +480,8 @@ struct StateTable
|
|||
while (state < num_states)
|
||||
{
|
||||
if (unlikely (!c->check_array (states,
|
||||
states[0].static_size * nClasses,
|
||||
num_states)))
|
||||
num_states,
|
||||
states[0].static_size * nClasses)))
|
||||
return_trace (false);
|
||||
{ /* Sweep new states. */
|
||||
const HBUINT16 *stop = &states[num_states * nClasses];
|
||||
|
@ -490,9 +490,7 @@ struct StateTable
|
|||
state = num_states;
|
||||
}
|
||||
|
||||
if (unlikely (!c->check_array (entries,
|
||||
entries[0].static_size,
|
||||
num_entries)))
|
||||
if (unlikely (!c->check_array (entries, num_entries)))
|
||||
return_trace (false);
|
||||
{ /* Sweep new entries. */
|
||||
const Entry<Extra> *stop = &entries[num_entries];
|
||||
|
|
|
@ -619,7 +619,7 @@ struct Chain
|
|||
{
|
||||
inline void apply (hb_aat_apply_context_t *c) const
|
||||
{
|
||||
const ChainSubtable *subtable = &StructAtOffset<ChainSubtable> (featureZ, featureZ[0].static_size * featureCount);
|
||||
const ChainSubtable *subtable = &StructAtOffset<ChainSubtable> (&featureZ, featureZ[0].static_size * featureCount);
|
||||
unsigned int count = subtableCount;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
|
@ -648,10 +648,10 @@ struct Chain
|
|||
!c->check_range (this, length))
|
||||
return_trace (false);
|
||||
|
||||
if (!c->check_array (featureZ, featureZ[0].static_size, featureCount))
|
||||
if (!c->check_array (featureZ.arrayZ, featureCount))
|
||||
return_trace (false);
|
||||
|
||||
const ChainSubtable *subtable = &StructAtOffset<ChainSubtable> (featureZ, featureZ[0].static_size * featureCount);
|
||||
const ChainSubtable *subtable = &StructAtOffset<ChainSubtable> (&featureZ, featureZ[0].static_size * featureCount);
|
||||
unsigned int count = subtableCount;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
|
@ -669,8 +669,8 @@ struct Chain
|
|||
HBUINT32 featureCount; /* Number of feature subtable entries. */
|
||||
HBUINT32 subtableCount; /* The number of subtables in the chain. */
|
||||
|
||||
Feature featureZ[VAR]; /* Features. */
|
||||
/*ChainSubtable subtableX[VAR];*//* Subtables. */
|
||||
UnsizedArrayOf<Feature> featureZ; /* Features. */
|
||||
/*ChainSubtable firstSubtable;*//* Subtables. */
|
||||
/*subtableGlyphCoverageArray*/ /* Only if major == 3. */
|
||||
|
||||
public:
|
||||
|
@ -689,7 +689,7 @@ struct morx
|
|||
inline void apply (hb_aat_apply_context_t *c) const
|
||||
{
|
||||
c->set_lookup_index (0);
|
||||
const Chain *chain = chainsZ;
|
||||
const Chain *chain = &firstChain;
|
||||
unsigned int count = chainCount;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
|
@ -706,7 +706,7 @@ struct morx
|
|||
!chainCount.sanitize (c))
|
||||
return_trace (false);
|
||||
|
||||
const Chain *chain = chainsZ;
|
||||
const Chain *chain = &firstChain;
|
||||
unsigned int count = chainCount;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
|
@ -723,7 +723,7 @@ struct morx
|
|||
* 1 for mort, 2 or 3 for morx. */
|
||||
HBUINT32 chainCount; /* Number of metamorphosis chains contained in this
|
||||
* table. */
|
||||
Chain chainsZ[VAR]; /* Chains. */
|
||||
Chain firstChain; /* Chains. */
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_MIN (8);
|
||||
|
|
|
@ -98,7 +98,7 @@ static inline void _hb_memory_barrier (void)
|
|||
{
|
||||
#if !defined(MemoryBarrier)
|
||||
/* MinGW has a convoluted history of supporting MemoryBarrier. */
|
||||
long dummy = 0;
|
||||
LONG dummy = 0;
|
||||
InterlockedExchange (&dummy, 1);
|
||||
#else
|
||||
MemoryBarrier ();
|
||||
|
@ -106,7 +106,8 @@ static inline void _hb_memory_barrier (void)
|
|||
}
|
||||
#define _hb_memory_barrier() _hb_memory_barrier ()
|
||||
|
||||
#define hb_atomic_int_impl_add(AI, V) InterlockedExchangeAdd ((unsigned *) (AI), (V))
|
||||
#define hb_atomic_int_impl_add(AI, V) InterlockedExchangeAdd ((LONG *) (AI), (V))
|
||||
static_assert ((sizeof (LONG) == sizeof (int)), "");
|
||||
|
||||
#define hb_atomic_ptr_impl_cmpexch(P,O,N) (InterlockedCompareExchangePointer ((void **) (P), (void *) (N), (void *) (O)) == (void *) (O))
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ struct hb_buffer_t
|
|||
/* Text before / after the main buffer contents.
|
||||
* Always in Unicode, and ordered outward.
|
||||
* Index 0 is for "pre-context", 1 for "post-context". */
|
||||
static const unsigned int CONTEXT_LENGTH = 5;
|
||||
enum { CONTEXT_LENGTH = 5 };
|
||||
hb_codepoint_t context[2][CONTEXT_LENGTH];
|
||||
unsigned int context_len[2];
|
||||
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright © 2012 Google, Inc.
|
||||
*
|
||||
* This is part of HarfBuzz, a text shaping library.
|
||||
*
|
||||
* Permission is hereby granted, without written agreement and without
|
||||
* license or royalty fees, to use, copy, modify, and distribute this
|
||||
* software and its documentation for any purpose, provided that the
|
||||
* above copyright notice and the following two paragraphs appear in
|
||||
* all copies of this software.
|
||||
*
|
||||
* IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
|
||||
* DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
|
||||
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
|
||||
* IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
|
||||
* DAMAGE.
|
||||
*
|
||||
* THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
|
||||
* BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
|
||||
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
|
||||
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
|
||||
*
|
||||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#ifndef HB_CACHE_HH
|
||||
#define HB_CACHE_HH
|
||||
|
||||
#include "hb.hh"
|
||||
|
||||
|
||||
/* Implements a lock-free cache for int->int functions. */
|
||||
|
||||
template <unsigned int key_bits, unsigned int value_bits, unsigned int cache_bits>
|
||||
struct hb_cache_t
|
||||
{
|
||||
static_assert ((key_bits >= cache_bits), "");
|
||||
static_assert ((key_bits + value_bits - cache_bits <= 8 * sizeof (unsigned int)), "");
|
||||
|
||||
inline void init (void) { clear (); }
|
||||
inline void fini (void) {}
|
||||
|
||||
inline void clear (void)
|
||||
{ memset (values, 255, sizeof (values)); }
|
||||
|
||||
inline bool get (unsigned int key, unsigned int *value) const
|
||||
{
|
||||
unsigned int k = key & ((1u<<cache_bits)-1);
|
||||
unsigned int v = values[k].get_relaxed ();
|
||||
if ((v >> value_bits) != (key >> cache_bits))
|
||||
return false;
|
||||
*value = v & ((1u<<value_bits)-1);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool set (unsigned int key, unsigned int value)
|
||||
{
|
||||
if (unlikely ((key >> key_bits) || (value >> value_bits)))
|
||||
return false; /* Overflows */
|
||||
unsigned int k = key & ((1u<<cache_bits)-1);
|
||||
unsigned int v = ((key>>cache_bits)<<value_bits) | value;
|
||||
values[k].set_relaxed (v);
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
hb_atomic_int_t values[1u<<cache_bits];
|
||||
};
|
||||
|
||||
typedef hb_cache_t<21, 16, 8> hb_cmap_cache_t;
|
||||
typedef hb_cache_t<16, 24, 8> hb_advance_cache_t;
|
||||
|
||||
|
||||
#endif /* HB_CACHE_HH */
|
|
@ -877,8 +877,8 @@ parse_feature_indices (const char **pp, const char *end, hb_feature_t *feature)
|
|||
|
||||
bool has_start;
|
||||
|
||||
feature->start = 0;
|
||||
feature->end = (unsigned int) -1;
|
||||
feature->start = HB_FEATURE_GLOBAL_START;
|
||||
feature->end = HB_FEATURE_GLOBAL_END;
|
||||
|
||||
if (!parse_char (pp, end, '['))
|
||||
return true;
|
||||
|
|
|
@ -379,6 +379,19 @@ typedef void (*hb_destroy_func_t) (void *user_data);
|
|||
|
||||
/* Font features and variations. */
|
||||
|
||||
/**
|
||||
* HB_FEATURE_GLOBAL_START
|
||||
*
|
||||
* Since: REPLACEME
|
||||
*/
|
||||
#define HB_FEATURE_GLOBAL_START 0
|
||||
/**
|
||||
* HB_FEATURE_GLOBAL_END
|
||||
*
|
||||
* Since: REPLACEME
|
||||
*/
|
||||
#define HB_FEATURE_GLOBAL_END ((unsigned int) -1)
|
||||
|
||||
typedef struct hb_feature_t {
|
||||
hb_tag_t tag;
|
||||
uint32_t value;
|
||||
|
|
|
@ -67,7 +67,10 @@ hb_options (void)
|
|||
u.i = _hb_options.get_relaxed ();
|
||||
|
||||
if (unlikely (!u.i))
|
||||
{
|
||||
_hb_options_init ();
|
||||
u.i = _hb_options.get_relaxed ();
|
||||
}
|
||||
|
||||
return u.opts;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
|
||||
#include "hb.hh"
|
||||
|
||||
#include "hb-null.hh"
|
||||
|
||||
|
||||
/* Void! For when we need a expression-type of void. */
|
||||
typedef const struct _hb_void_t *hb_void_t;
|
||||
|
@ -507,6 +509,24 @@ struct hb_auto_t : Type
|
|||
void fini (void) {}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct hb_array_t
|
||||
{
|
||||
inline hb_array_t (void) : arrayZ (nullptr), len (0) {}
|
||||
inline hb_array_t (const T *array_, unsigned int len_) : arrayZ (array_), len (len_) {}
|
||||
|
||||
inline const T& operator [] (unsigned int i) const
|
||||
{
|
||||
if (unlikely (i >= len)) return Null(T);
|
||||
return arrayZ[i];
|
||||
}
|
||||
|
||||
inline void free (void) { ::free ((void *) arrayZ); arrayZ = nullptr; len = 0; }
|
||||
|
||||
const T *arrayZ;
|
||||
unsigned int len;
|
||||
};
|
||||
|
||||
struct hb_bytes_t
|
||||
{
|
||||
inline hb_bytes_t (void) : bytes (nullptr), len (0) {}
|
||||
|
|
|
@ -163,11 +163,12 @@ _hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void
|
|||
return hb_blob_reference (data->blob);
|
||||
|
||||
const OT::OpenTypeFontFile &ot_file = *data->blob->as<OT::OpenTypeFontFile> ();
|
||||
const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index);
|
||||
unsigned int base_offset;
|
||||
const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index, &base_offset);
|
||||
|
||||
const OT::OpenTypeTable &table = ot_face.get_table_by_tag (tag);
|
||||
|
||||
hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.length);
|
||||
hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, base_offset + table.offset, table.length);
|
||||
|
||||
return blob;
|
||||
}
|
||||
|
@ -526,7 +527,7 @@ hb_face_get_table_tags (const hb_face_t *face,
|
|||
* @face: font face.
|
||||
* @out: set to add Unicode characters covered by @face to.
|
||||
*
|
||||
* Since: REPLACEME
|
||||
* Since: 1.9.0
|
||||
*/
|
||||
void
|
||||
hb_face_collect_unicodes (hb_face_t *face,
|
||||
|
@ -543,7 +544,7 @@ hb_face_collect_unicodes (hb_face_t *face,
|
|||
*
|
||||
*
|
||||
*
|
||||
* Since: REPLACEME
|
||||
* Since: 1.9.0
|
||||
*/
|
||||
void
|
||||
hb_face_collect_variation_selectors (hb_face_t *face,
|
||||
|
@ -560,7 +561,7 @@ hb_face_collect_variation_selectors (hb_face_t *face,
|
|||
*
|
||||
*
|
||||
*
|
||||
* Since: REPLACEME
|
||||
* Since: 1.9.0
|
||||
*/
|
||||
void
|
||||
hb_face_collect_variation_unicodes (hb_face_t *face,
|
||||
|
@ -684,7 +685,7 @@ _hb_face_builder_reference_table (hb_face_t *face, hb_tag_t tag, void *user_data
|
|||
*
|
||||
* Return value: (transfer full) New face.
|
||||
*
|
||||
* Since: REPLACEME
|
||||
* Since: 1.9.0
|
||||
**/
|
||||
hb_face_t *
|
||||
hb_face_builder_create (void)
|
||||
|
@ -703,7 +704,7 @@ hb_face_builder_create (void)
|
|||
* Add table for @tag with data provided by @blob to the face. @face must
|
||||
* be created using hb_face_builder_create().
|
||||
*
|
||||
* Since: REPLACEME
|
||||
* Since: 1.9.0
|
||||
**/
|
||||
hb_bool_t
|
||||
hb_face_builder_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob)
|
||||
|
|
50
src/hb-ft.cc
50
src/hb-ft.cc
|
@ -33,6 +33,7 @@
|
|||
|
||||
#include "hb-font.hh"
|
||||
#include "hb-machinery.hh"
|
||||
#include "hb-cache.hh"
|
||||
|
||||
#include FT_ADVANCES_H
|
||||
#include FT_MULTIPLE_MASTERS_H
|
||||
|
@ -68,6 +69,9 @@ struct hb_ft_font_t
|
|||
int load_flags;
|
||||
bool symbol; /* Whether selected cmap is symbol cmap. */
|
||||
bool unref; /* Whether to destroy ft_face when done. */
|
||||
|
||||
mutable int cached_x_scale;
|
||||
mutable hb_advance_cache_t advance_cache;
|
||||
};
|
||||
|
||||
static hb_ft_font_t *
|
||||
|
@ -84,6 +88,9 @@ _hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref)
|
|||
|
||||
ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
|
||||
|
||||
ft_font->cached_x_scale = 0;
|
||||
ft_font->advance_cache.init ();
|
||||
|
||||
return ft_font;
|
||||
}
|
||||
|
||||
|
@ -98,6 +105,8 @@ _hb_ft_font_destroy (void *data)
|
|||
{
|
||||
hb_ft_font_t *ft_font = (hb_ft_font_t *) data;
|
||||
|
||||
ft_font->advance_cache.fini ();
|
||||
|
||||
if (ft_font->unref)
|
||||
_hb_ft_face_destroy (ft_font->ft_face);
|
||||
|
||||
|
@ -227,6 +236,46 @@ hb_ft_get_glyph_h_advance (hb_font_t *font,
|
|||
return (v + (1<<9)) >> 10;
|
||||
}
|
||||
|
||||
static void
|
||||
hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data,
|
||||
unsigned count,
|
||||
hb_codepoint_t *first_glyph,
|
||||
unsigned glyph_stride,
|
||||
hb_position_t *first_advance,
|
||||
unsigned advance_stride,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
||||
FT_Face ft_face = ft_font->ft_face;
|
||||
int load_flags = ft_font->load_flags;
|
||||
int mult = font->x_scale < 0 ? -1 : +1;
|
||||
|
||||
if (font->x_scale != ft_font->cached_x_scale)
|
||||
{
|
||||
ft_font->advance_cache.clear ();
|
||||
ft_font->cached_x_scale = font->x_scale;
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
FT_Fixed v = 0;
|
||||
hb_codepoint_t glyph = *first_glyph;
|
||||
|
||||
unsigned int cv;
|
||||
if (ft_font->advance_cache.get (glyph, &cv))
|
||||
v = cv;
|
||||
else
|
||||
{
|
||||
FT_Get_Advance (ft_face, glyph, load_flags, &v);
|
||||
ft_font->advance_cache.set (glyph, v);
|
||||
}
|
||||
|
||||
*first_advance = (v * mult + (1<<9)) >> 10;
|
||||
first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride);
|
||||
first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride);
|
||||
}
|
||||
}
|
||||
|
||||
static hb_position_t
|
||||
hb_ft_get_glyph_v_advance (hb_font_t *font,
|
||||
void *font_data,
|
||||
|
@ -432,6 +481,7 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft
|
|||
hb_font_funcs_set_nominal_glyph_func (funcs, hb_ft_get_nominal_glyph, nullptr, nullptr);
|
||||
hb_font_funcs_set_variation_glyph_func (funcs, hb_ft_get_variation_glyph, nullptr, nullptr);
|
||||
hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ft_get_glyph_h_advance, nullptr, nullptr);
|
||||
hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ft_get_glyph_h_advances, nullptr, nullptr);
|
||||
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);
|
||||
|
|
|
@ -99,8 +99,8 @@ static inline Type& StructAfter(TObject &X)
|
|||
|
||||
#define DEFINE_SIZE_STATIC(size) \
|
||||
DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)); \
|
||||
static const unsigned int static_size = (size); \
|
||||
static const unsigned int min_size = (size); \
|
||||
enum { static_size = (size) }; \
|
||||
enum { min_size = (size) }; \
|
||||
inline unsigned int get_size (void) const { return (size); }
|
||||
|
||||
#define DEFINE_SIZE_UNION(size, _member) \
|
||||
|
@ -114,7 +114,7 @@ static inline Type& StructAfter(TObject &X)
|
|||
#define DEFINE_SIZE_ARRAY(size, array) \
|
||||
DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + VAR * sizeof (array[0])); \
|
||||
DEFINE_COMPILES_ASSERTION ((void) array[0].static_size) \
|
||||
static const unsigned int min_size = (size); \
|
||||
enum { min_size = (size) }; \
|
||||
|
||||
#define DEFINE_SIZE_ARRAY_SIZED(size, array) \
|
||||
DEFINE_SIZE_ARRAY(size, array); \
|
||||
|
@ -133,7 +133,7 @@ static inline Type& StructAfter(TObject &X)
|
|||
template <typename Context, typename Return, unsigned int MaxDebugDepth>
|
||||
struct hb_dispatch_context_t
|
||||
{
|
||||
static const unsigned int max_debug_depth = MaxDebugDepth;
|
||||
enum { max_debug_depth = MaxDebugDepth };
|
||||
typedef Return return_t;
|
||||
template <typename T, typename F>
|
||||
inline bool may_dispatch (const T *obj, const F *format) { return true; }
|
||||
|
@ -296,7 +296,8 @@ struct hb_sanitize_context_t :
|
|||
return likely (ok);
|
||||
}
|
||||
|
||||
inline bool check_array (const void *base, unsigned int record_size, unsigned int len) const
|
||||
template <typename T>
|
||||
inline bool check_array (const T *base, unsigned int len, unsigned int record_size = T::static_size) const
|
||||
{
|
||||
const char *p = (const char *) base;
|
||||
bool overflows = hb_unsigned_mul_overflows (len, record_size);
|
||||
|
|
|
@ -115,7 +115,7 @@ typedef struct OffsetTable
|
|||
* table list. */
|
||||
int i = tables.len < 64 ? tables.lsearch (t) : tables.bsearch (t);
|
||||
if (table_index)
|
||||
*table_index = i == -1 ? Index::NOT_FOUND_INDEX : (unsigned int) i;
|
||||
*table_index = i == -1 ? (unsigned) Index::NOT_FOUND_INDEX : (unsigned) i;
|
||||
return i != -1;
|
||||
}
|
||||
inline const TableRecord& get_table_by_tag (hb_tag_t tag) const
|
||||
|
@ -300,7 +300,7 @@ struct ResourceRefItem
|
|||
|
||||
HBINT16 id; /* Resource ID, is really should be signed? */
|
||||
HBINT16 nameOffset; /* Offset from beginning of resource name list
|
||||
* to resource name, minus means there is no */
|
||||
* to resource name, minus means there is none. */
|
||||
HBUINT8 attr; /* Resource attributes */
|
||||
HBUINT24 dataOffset; /* Offset from beginning of resource data to
|
||||
* data for this resource */
|
||||
|
@ -318,15 +318,9 @@ struct ResourceTypeItem
|
|||
return_trace (likely (c->check_struct (this)));
|
||||
}
|
||||
|
||||
inline unsigned int get_resource_count () const
|
||||
{
|
||||
return numRes + 1;
|
||||
}
|
||||
inline unsigned int get_resource_count () const { return numRes + 1; }
|
||||
|
||||
inline bool is_sfnt () const
|
||||
{
|
||||
return type == HB_TAG ('s','f','n','t');
|
||||
}
|
||||
inline bool is_sfnt () const { return type == HB_TAG ('s','f','n','t'); }
|
||||
|
||||
inline const ResourceRefItem& get_ref_item (const void *base,
|
||||
unsigned int i) const
|
||||
|
@ -335,11 +329,11 @@ struct ResourceTypeItem
|
|||
}
|
||||
|
||||
protected:
|
||||
Tag type; /* Resource type */
|
||||
HBUINT16 numRes; /* Number of resource this type in map minus 1 */
|
||||
Tag type; /* Resource type. */
|
||||
HBUINT16 numRes; /* Number of resources minus 1. */
|
||||
OffsetTo<UnsizedArrayOf<ResourceRefItem> >
|
||||
refList; /* Offset from beginning of resource type list
|
||||
* to reference list for this type */
|
||||
* to reference item list for this type. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (8);
|
||||
};
|
||||
|
@ -428,14 +422,19 @@ struct ResourceForkHeader
|
|||
return StructAtOffset<LArrayOf<HBUINT8> > (this, offset);
|
||||
}
|
||||
|
||||
inline const OpenTypeFontFace& get_face (unsigned int idx) const
|
||||
inline const OpenTypeFontFace& get_face (unsigned int idx, unsigned int *base_offset = nullptr) const
|
||||
{
|
||||
const ResourceMap &resource_map = this+map;
|
||||
for (unsigned int i = 0; i < resource_map.get_types_count (); ++i)
|
||||
{
|
||||
const ResourceTypeItem& type = resource_map.get_type (i);
|
||||
if (type.is_sfnt () && idx < type.get_resource_count ())
|
||||
return (OpenTypeFontFace&) get_data (type, idx).arrayZ;
|
||||
{
|
||||
const OpenTypeFontFace &face = (OpenTypeFontFace&) get_data (type, idx).arrayZ;
|
||||
if (base_offset)
|
||||
*base_offset = (const char *) &face - (const char *) this;
|
||||
return face;
|
||||
}
|
||||
}
|
||||
return Null (OpenTypeFontFace);
|
||||
}
|
||||
|
@ -502,12 +501,14 @@ struct OpenTypeFontFile
|
|||
case Typ1Tag:
|
||||
case TrueTypeTag: return 1;
|
||||
case TTCTag: return u.ttcHeader.get_face_count ();
|
||||
// case DFontTag: return u.rfHeader.get_face_count ();
|
||||
case DFontTag: return u.rfHeader.get_face_count ();
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
inline const OpenTypeFontFace& get_face (unsigned int i) const
|
||||
inline const OpenTypeFontFace& get_face (unsigned int i, unsigned int *base_offset = nullptr) const
|
||||
{
|
||||
if (base_offset)
|
||||
*base_offset = 0;
|
||||
switch (u.tag) {
|
||||
/* Note: for non-collection SFNT data we ignore index. This is because
|
||||
* Apple dfont container is a container of SFNT's. So each SFNT is a
|
||||
|
@ -517,7 +518,7 @@ struct OpenTypeFontFile
|
|||
case Typ1Tag:
|
||||
case TrueTypeTag: return u.fontFace;
|
||||
case TTCTag: return u.ttcHeader.get_face (i);
|
||||
// case DFontTag: return u.rfHeader.get_face (i);
|
||||
case DFontTag: return u.rfHeader.get_face (i, base_offset);
|
||||
default: return Null(OpenTypeFontFace);
|
||||
}
|
||||
}
|
||||
|
@ -544,7 +545,7 @@ struct OpenTypeFontFile
|
|||
case Typ1Tag:
|
||||
case TrueTypeTag: return_trace (u.fontFace.sanitize (c));
|
||||
case TTCTag: return_trace (u.ttcHeader.sanitize (c));
|
||||
// case DFontTag: return_trace (u.rfHeader.sanitize (c));
|
||||
case DFontTag: return_trace (u.rfHeader.sanitize (c));
|
||||
default: return_trace (true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -150,7 +150,7 @@ typedef HBUINT16 NameID;
|
|||
|
||||
/* Script/language-system/feature index */
|
||||
struct Index : HBUINT16 {
|
||||
static const unsigned int NOT_FOUND_INDEX = 0xFFFFu;
|
||||
enum { NOT_FOUND_INDEX = 0xFFFFu };
|
||||
};
|
||||
DECLARE_NULL_NAMESPACE_BYTES (OT, Index);
|
||||
|
||||
|
@ -299,7 +299,6 @@ static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset)
|
|||
* Array Types
|
||||
*/
|
||||
|
||||
/* TODO Use it in ArrayOf, HeadlessArrayOf, and other places around the code base?? */
|
||||
template <typename Type>
|
||||
struct UnsizedArrayOf
|
||||
{
|
||||
|
@ -345,7 +344,7 @@ struct UnsizedArrayOf
|
|||
inline bool sanitize_shallow (hb_sanitize_context_t *c, unsigned int count) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_array (arrayZ, arrayZ[0].static_size, count));
|
||||
return_trace (c->check_array (arrayZ, count));
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -487,7 +486,7 @@ struct ArrayOf
|
|||
inline bool sanitize_shallow (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (len.sanitize (c) && c->check_array (arrayZ, Type::static_size, len));
|
||||
return_trace (len.sanitize (c) && c->check_array (arrayZ, len));
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -596,7 +595,7 @@ struct HeadlessArrayOf
|
|||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (len.sanitize (c) &&
|
||||
(!len || c->check_array (arrayZ, Type::static_size, len - 1)));
|
||||
(!len || c->check_array (arrayZ, len - 1)));
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
|
@ -231,7 +231,7 @@ struct CmapSubtableFormat4
|
|||
inline void init (const CmapSubtableFormat4 *subtable)
|
||||
{
|
||||
segCount = subtable->segCountX2 / 2;
|
||||
endCount = subtable->values;
|
||||
endCount = subtable->values.arrayZ;
|
||||
startCount = endCount + segCount + 1;
|
||||
idDelta = startCount + segCount;
|
||||
idRangeOffset = idDelta + segCount;
|
||||
|
@ -369,7 +369,8 @@ struct CmapSubtableFormat4
|
|||
HBUINT16 entrySelector; /* log2(searchRange/2) */
|
||||
HBUINT16 rangeShift; /* 2 x segCount - searchRange */
|
||||
|
||||
HBUINT16 values[VAR];
|
||||
UnsizedArrayOf<HBUINT16>
|
||||
values;
|
||||
#if 0
|
||||
HBUINT16 endCount[segCount]; /* End characterCode for each segment,
|
||||
* last=0xFFFFu. */
|
||||
|
@ -377,7 +378,8 @@ struct CmapSubtableFormat4
|
|||
HBUINT16 startCount[segCount]; /* Start character code for each segment. */
|
||||
HBINT16 idDelta[segCount]; /* Delta for all character codes in segment. */
|
||||
HBUINT16 idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */
|
||||
HBUINT16 glyphIdArray[VAR]; /* Glyph index array (arbitrary length) */
|
||||
UnsizedArrayOf<HBUINT16>
|
||||
glyphIdArray; /* Glyph index array (arbitrary length) */
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
|
|
@ -128,7 +128,7 @@ struct IndexSubtableFormat1Or3
|
|||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
c->check_array (offsetArrayZ, offsetArrayZ[0].static_size, glyph_count + 1));
|
||||
c->check_array (offsetArrayZ.arrayZ, glyph_count + 1));
|
||||
}
|
||||
|
||||
bool get_image_data (unsigned int idx,
|
||||
|
@ -144,7 +144,8 @@ struct IndexSubtableFormat1Or3
|
|||
}
|
||||
|
||||
IndexSubtableHeader header;
|
||||
Offset<OffsetType> offsetArrayZ[VAR];
|
||||
UnsizedArrayOf<Offset<OffsetType> >
|
||||
offsetArrayZ;
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY(8, offsetArrayZ);
|
||||
};
|
||||
|
@ -240,7 +241,7 @@ struct IndexSubtableArray
|
|||
inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!c->check_array (&indexSubtablesZ, indexSubtablesZ[0].static_size, count)))
|
||||
if (unlikely (!c->check_array (indexSubtablesZ.arrayZ, count)))
|
||||
return_trace (false);
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (unlikely (!indexSubtablesZ[i].sanitize (c, this)))
|
||||
|
@ -255,15 +256,14 @@ struct IndexSubtableArray
|
|||
{
|
||||
unsigned int firstGlyphIndex = indexSubtablesZ[i].firstGlyphIndex;
|
||||
unsigned int lastGlyphIndex = indexSubtablesZ[i].lastGlyphIndex;
|
||||
if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex) {
|
||||
if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex)
|
||||
return &indexSubtablesZ[i];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
protected:
|
||||
IndexSubtableRecord indexSubtablesZ[VAR];
|
||||
UnsizedArrayOf<IndexSubtableRecord> indexSubtablesZ;
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY(0, indexSubtablesZ);
|
||||
};
|
||||
|
@ -528,7 +528,7 @@ struct CBDT
|
|||
|
||||
protected:
|
||||
FixedVersion<> version;
|
||||
HBUINT8 dataZ[VAR];
|
||||
UnsizedArrayOf<HBUINT8> dataZ;
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY(4, dataZ);
|
||||
};
|
||||
|
|
|
@ -48,10 +48,9 @@ hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED,
|
|||
hb_codepoint_t unicode,
|
||||
hb_codepoint_t *glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
|
||||
{
|
||||
const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data;
|
||||
return ot_font->cmap.get_relaxed()->get_nominal_glyph (unicode, glyph);
|
||||
const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
|
||||
return ot_face->cmap.get_relaxed()->get_nominal_glyph (unicode, glyph);
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
|
@ -62,8 +61,8 @@ hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED,
|
|||
hb_codepoint_t *glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data;
|
||||
return ot_font->cmap.get_relaxed ()->get_variation_glyph (unicode, variation_selector, glyph);
|
||||
const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
|
||||
return ot_face->cmap.get_relaxed ()->get_variation_glyph (unicode, variation_selector, glyph);
|
||||
}
|
||||
|
||||
static hb_position_t
|
||||
|
@ -72,8 +71,28 @@ hb_ot_get_glyph_h_advance (hb_font_t *font,
|
|||
hb_codepoint_t glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data;
|
||||
return font->em_scale_x (ot_font->hmtx.get_relaxed ()->get_advance (glyph, font));
|
||||
const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
|
||||
return font->em_scale_x (ot_face->hmtx.get_relaxed ()->get_advance (glyph, font));
|
||||
}
|
||||
|
||||
static void
|
||||
hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data,
|
||||
unsigned count,
|
||||
hb_codepoint_t *first_glyph,
|
||||
unsigned glyph_stride,
|
||||
hb_position_t *first_advance,
|
||||
unsigned advance_stride,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
|
||||
const OT::hmtx_accelerator_t &hmtx = *ot_face->hmtx.get_relaxed ();
|
||||
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
*first_advance = font->em_scale_x (hmtx.get_advance (*first_glyph, font));
|
||||
first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride);
|
||||
first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride);
|
||||
}
|
||||
}
|
||||
|
||||
static hb_position_t
|
||||
|
@ -82,8 +101,28 @@ hb_ot_get_glyph_v_advance (hb_font_t *font,
|
|||
hb_codepoint_t glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data;
|
||||
return font->em_scale_y (-(int) ot_font->vmtx.get_relaxed ()->get_advance (glyph, font));
|
||||
const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
|
||||
return font->em_scale_y (-(int) ot_face->vmtx.get_relaxed ()->get_advance (glyph, font));
|
||||
}
|
||||
|
||||
static void
|
||||
hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data,
|
||||
unsigned count,
|
||||
hb_codepoint_t *first_glyph,
|
||||
unsigned glyph_stride,
|
||||
hb_position_t *first_advance,
|
||||
unsigned advance_stride,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
|
||||
const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx.get_relaxed ();
|
||||
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
*first_advance = font->em_scale_y (-(int) vmtx.get_advance (*first_glyph, font));
|
||||
first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride);
|
||||
first_advance = &StructAtOffset<hb_position_t> (first_advance, advance_stride);
|
||||
}
|
||||
}
|
||||
|
||||
static hb_position_t
|
||||
|
@ -93,8 +132,8 @@ hb_ot_get_glyph_h_kerning (hb_font_t *font,
|
|||
hb_codepoint_t right_glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data;
|
||||
return font->em_scale_x (ot_font->kern->get_h_kerning (left_glyph, right_glyph));
|
||||
const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
|
||||
return font->em_scale_x (ot_face->kern->get_h_kerning (left_glyph, right_glyph));
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
|
@ -104,10 +143,10 @@ hb_ot_get_glyph_extents (hb_font_t *font,
|
|||
hb_glyph_extents_t *extents,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data;
|
||||
bool ret = ot_font->glyf->get_extents (glyph, extents);
|
||||
const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
|
||||
bool ret = ot_face->glyf->get_extents (glyph, extents);
|
||||
if (!ret)
|
||||
ret = ot_font->CBDT->get_extents (glyph, extents);
|
||||
ret = ot_face->CBDT->get_extents (glyph, extents);
|
||||
// TODO Hook up side-bearings variations.
|
||||
extents->x_bearing = font->em_scale_x (extents->x_bearing);
|
||||
extents->y_bearing = font->em_scale_y (extents->y_bearing);
|
||||
|
@ -123,8 +162,8 @@ hb_ot_get_glyph_name (hb_font_t *font HB_UNUSED,
|
|||
char *name, unsigned int size,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data;
|
||||
return ot_font->post->get_glyph_name (glyph, name, size);
|
||||
const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
|
||||
return ot_face->post->get_glyph_name (glyph, name, size);
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
|
@ -134,8 +173,8 @@ hb_ot_get_glyph_from_name (hb_font_t *font HB_UNUSED,
|
|||
hb_codepoint_t *glyph,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data;
|
||||
return ot_font->post->get_glyph_from_name (name, len, glyph);
|
||||
const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
|
||||
return ot_face->post->get_glyph_from_name (name, len, glyph);
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
|
@ -144,12 +183,12 @@ hb_ot_get_font_h_extents (hb_font_t *font,
|
|||
hb_font_extents_t *metrics,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data;
|
||||
metrics->ascender = font->em_scale_y (ot_font->hmtx.get_relaxed ()->ascender);
|
||||
metrics->descender = font->em_scale_y (ot_font->hmtx.get_relaxed ()->descender);
|
||||
metrics->line_gap = font->em_scale_y (ot_font->hmtx.get_relaxed ()->line_gap);
|
||||
const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
|
||||
metrics->ascender = font->em_scale_y (ot_face->hmtx.get_relaxed ()->ascender);
|
||||
metrics->descender = font->em_scale_y (ot_face->hmtx.get_relaxed ()->descender);
|
||||
metrics->line_gap = font->em_scale_y (ot_face->hmtx.get_relaxed ()->line_gap);
|
||||
// TODO Hook up variations.
|
||||
return ot_font->hmtx.get_relaxed ()->has_font_extents;
|
||||
return ot_face->hmtx.get_relaxed ()->has_font_extents;
|
||||
}
|
||||
|
||||
static hb_bool_t
|
||||
|
@ -158,19 +197,19 @@ hb_ot_get_font_v_extents (hb_font_t *font,
|
|||
hb_font_extents_t *metrics,
|
||||
void *user_data HB_UNUSED)
|
||||
{
|
||||
const hb_ot_face_data_t *ot_font = (const hb_ot_face_data_t *) font_data;
|
||||
metrics->ascender = font->em_scale_x (ot_font->vmtx.get_relaxed ()->ascender);
|
||||
metrics->descender = font->em_scale_x (ot_font->vmtx.get_relaxed ()->descender);
|
||||
metrics->line_gap = font->em_scale_x (ot_font->vmtx.get_relaxed ()->line_gap);
|
||||
const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
|
||||
metrics->ascender = font->em_scale_x (ot_face->vmtx.get_relaxed ()->ascender);
|
||||
metrics->descender = font->em_scale_x (ot_face->vmtx.get_relaxed ()->descender);
|
||||
metrics->line_gap = font->em_scale_x (ot_face->vmtx.get_relaxed ()->line_gap);
|
||||
// TODO Hook up variations.
|
||||
return ot_font->vmtx.get_relaxed ()->has_font_extents;
|
||||
return ot_face->vmtx.get_relaxed ()->has_font_extents;
|
||||
}
|
||||
|
||||
#ifdef HB_USE_ATEXIT
|
||||
static void free_static_ot_funcs (void);
|
||||
#endif
|
||||
|
||||
static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot_font_funcs_lazy_loader_t>
|
||||
static struct hb_ot_face_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot_face_funcs_lazy_loader_t>
|
||||
{
|
||||
static inline hb_font_funcs_t *create (void)
|
||||
{
|
||||
|
@ -181,7 +220,9 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot
|
|||
hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, nullptr, nullptr);
|
||||
hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, nullptr, nullptr);
|
||||
hb_font_funcs_set_glyph_h_advance_func (funcs, hb_ot_get_glyph_h_advance, nullptr, nullptr);
|
||||
hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ot_get_glyph_h_advances, nullptr, nullptr);
|
||||
hb_font_funcs_set_glyph_v_advance_func (funcs, hb_ot_get_glyph_v_advance, nullptr, nullptr);
|
||||
hb_font_funcs_set_glyph_v_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr);
|
||||
//hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, nullptr, nullptr);
|
||||
//hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr);
|
||||
hb_font_funcs_set_glyph_h_kerning_func (funcs, hb_ot_get_glyph_h_kerning, nullptr, nullptr);
|
||||
|
@ -225,15 +266,15 @@ void
|
|||
hb_ot_font_set_funcs (hb_font_t *font)
|
||||
{
|
||||
if (unlikely (!hb_ot_shaper_face_data_ensure (font->face))) return;
|
||||
hb_ot_face_data_t *ot_font = hb_ot_face_data (font->face);
|
||||
hb_ot_face_data_t *ot_face = hb_ot_face_data (font->face);
|
||||
|
||||
/* Load them lazies. We access them with get_relaxed() for performance. */
|
||||
ot_font->cmap.get ();
|
||||
ot_font->hmtx.get ();
|
||||
ot_font->vmtx.get ();
|
||||
ot_face->cmap.get ();
|
||||
ot_face->hmtx.get ();
|
||||
ot_face->vmtx.get ();
|
||||
|
||||
hb_font_set_funcs (font,
|
||||
_hb_ot_get_font_funcs (),
|
||||
ot_font,
|
||||
ot_face,
|
||||
nullptr);
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ struct loca
|
|||
}
|
||||
|
||||
protected:
|
||||
HBUINT8 dataZ[VAR]; /* Location data. */
|
||||
UnsizedArrayOf<HBUINT8> dataZ; /* Location data. */
|
||||
DEFINE_SIZE_ARRAY (0, dataZ);
|
||||
};
|
||||
|
||||
|
@ -375,13 +375,13 @@ struct glyf
|
|||
|
||||
if (short_offset)
|
||||
{
|
||||
const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ;
|
||||
const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ.arrayZ;
|
||||
*start_offset = 2 * offsets[glyph];
|
||||
*end_offset = 2 * offsets[glyph + 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ;
|
||||
const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ.arrayZ;
|
||||
|
||||
*start_offset = offsets[glyph];
|
||||
*end_offset = offsets[glyph + 1];
|
||||
|
@ -418,7 +418,7 @@ struct glyf
|
|||
} while (composite_it.move_to_next());
|
||||
|
||||
if ( (uint16_t) last->flags & CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS)
|
||||
*instruction_start = ((char *) last - (char *) glyf_table->dataZ) + last->get_size();
|
||||
*instruction_start = ((char *) last - (char *) glyf_table->dataZ.arrayZ) + last->get_size();
|
||||
else
|
||||
*instruction_start = end_offset;
|
||||
*instruction_end = end_offset;
|
||||
|
@ -483,7 +483,7 @@ struct glyf
|
|||
};
|
||||
|
||||
protected:
|
||||
HBUINT8 dataZ[VAR]; /* Glyphs data. */
|
||||
UnsizedArrayOf<HBUINT8> dataZ; /* Glyphs data. */
|
||||
|
||||
DEFINE_SIZE_ARRAY (0, dataZ);
|
||||
};
|
||||
|
|
|
@ -66,7 +66,7 @@ struct DeviceRecord
|
|||
if (unlikely (i >= len())) return nullptr;
|
||||
hb_codepoint_t gid = this->subset_plan->glyphs [i];
|
||||
|
||||
const HBUINT8* width = &(this->source_device_record->widths[gid]);
|
||||
const HBUINT8* width = &(this->source_device_record->widthsZ[gid]);
|
||||
|
||||
if (width < ((const HBUINT8 *) this->source_device_record) + size_device_record)
|
||||
return width;
|
||||
|
@ -77,11 +77,7 @@ struct DeviceRecord
|
|||
|
||||
static inline unsigned int get_size (unsigned int count)
|
||||
{
|
||||
unsigned int raw_size = min_size + count * HBUINT8::static_size;
|
||||
if (raw_size % 4)
|
||||
/* Align to 32 bits */
|
||||
return raw_size + (4 - (raw_size % 4));
|
||||
return raw_size;
|
||||
return hb_ceil_to_4 (min_size + count * HBUINT8::static_size);
|
||||
}
|
||||
|
||||
inline bool serialize (hb_serialize_context_t *c, const SubsetView &subset_view)
|
||||
|
@ -107,7 +103,7 @@ struct DeviceRecord
|
|||
DEBUG_MSG(SUBSET, nullptr, "HDMX width for new gid %d is missing.", i);
|
||||
return_trace (false);
|
||||
}
|
||||
widths[i].set (*width);
|
||||
widthsZ[i].set (*width);
|
||||
}
|
||||
|
||||
return_trace (true);
|
||||
|
@ -122,9 +118,9 @@ struct DeviceRecord
|
|||
|
||||
HBUINT8 pixel_size; /* Pixel size for following widths (as ppem). */
|
||||
HBUINT8 max_width; /* Maximum width. */
|
||||
HBUINT8 widths[VAR]; /* Array of widths (numGlyphs is from the 'maxp' table). */
|
||||
UnsizedArrayOf<HBUINT8> widthsZ; /* Array of widths (numGlyphs is from the 'maxp' table). */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (2, widths);
|
||||
DEFINE_SIZE_ARRAY (2, widthsZ);
|
||||
};
|
||||
|
||||
|
||||
|
@ -140,7 +136,7 @@ struct hdmx
|
|||
inline const DeviceRecord& operator [] (unsigned int i) const
|
||||
{
|
||||
if (unlikely (i >= num_records)) return Null(DeviceRecord);
|
||||
return StructAtOffset<DeviceRecord> (this->data, i * size_device_record);
|
||||
return StructAtOffset<DeviceRecord> (&this->dataZ, i * size_device_record);
|
||||
}
|
||||
|
||||
inline bool serialize (hb_serialize_context_t *c, const hdmx *source_hdmx, hb_subset_plan_t *plan)
|
||||
|
@ -214,9 +210,9 @@ struct hdmx
|
|||
HBUINT16 version; /* Table version number (0) */
|
||||
HBUINT16 num_records; /* Number of device records. */
|
||||
HBUINT32 size_device_record; /* Size of a device record, 32-bit aligned. */
|
||||
HBUINT8 data[VAR]; /* Array of device records. */
|
||||
UnsizedArrayOf<HBUINT8> dataZ; /* Array of device records. */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (8, data);
|
||||
DEFINE_SIZE_ARRAY (8, dataZ);
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
|
|
@ -262,7 +262,7 @@ struct hmtxvmtx
|
|||
return default_advance;
|
||||
}
|
||||
|
||||
return table->longMetric[MIN (glyph, (uint32_t) num_advances - 1)].advance;
|
||||
return table->longMetricZ[MIN (glyph, (uint32_t) num_advances - 1)].advance;
|
||||
}
|
||||
|
||||
inline unsigned int get_advance (hb_codepoint_t glyph,
|
||||
|
@ -295,7 +295,7 @@ struct hmtxvmtx
|
|||
};
|
||||
|
||||
protected:
|
||||
LongMetric longMetric[VAR]; /* Paired advance width and leading
|
||||
UnsizedArrayOf<LongMetric>longMetricZ;/* Paired advance width and leading
|
||||
* bearing values for each glyph. The
|
||||
* value numOfHMetrics comes from
|
||||
* the 'hhea' table. If the font is
|
||||
|
@ -303,7 +303,7 @@ struct hmtxvmtx
|
|||
* be in the array, but that entry is
|
||||
* required. The last entry applies to
|
||||
* all subsequent glyphs. */
|
||||
/*FWORD leadingBearingX[VAR];*/ /* Here the advance is assumed
|
||||
/*UnsizedArrayOf<FWORD> leadingBearingX;*//* Here the advance is assumed
|
||||
* to be the same as the advance
|
||||
* for the last entry above. The
|
||||
* number of entries in this array is
|
||||
|
@ -317,7 +317,7 @@ struct hmtxvmtx
|
|||
* font to vary the side bearing
|
||||
* values for each glyph. */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (0, longMetric);
|
||||
DEFINE_SIZE_ARRAY (0, longMetricZ);
|
||||
};
|
||||
|
||||
struct hmtx : hmtxvmtx<hmtx, hhea> {
|
||||
|
|
|
@ -208,7 +208,7 @@ struct KernSubTableWrapper
|
|||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (thiz()) &&
|
||||
thiz()->length >= T::min_size &&
|
||||
c->check_array (thiz(), 1, thiz()->length) &&
|
||||
c->check_array (thiz(), thiz()->length, 1) &&
|
||||
thiz()->subtable.sanitize (c, thiz()->format));
|
||||
}
|
||||
};
|
||||
|
@ -222,7 +222,7 @@ struct KernTable
|
|||
inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const
|
||||
{
|
||||
int v = 0;
|
||||
const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (thiz()->data);
|
||||
const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ);
|
||||
unsigned int count = thiz()->nTables;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
|
@ -241,7 +241,7 @@ struct KernTable
|
|||
thiz()->version != T::VERSION))
|
||||
return_trace (false);
|
||||
|
||||
const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (thiz()->data);
|
||||
const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ);
|
||||
unsigned int count = thiz()->nTables;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
|
@ -289,9 +289,9 @@ struct KernOT : KernTable<KernOT>
|
|||
protected:
|
||||
HBUINT16 version; /* Version--0x0000u */
|
||||
HBUINT16 nTables; /* Number of subtables in the kerning table. */
|
||||
HBUINT8 data[VAR];
|
||||
UnsizedArrayOf<HBUINT8> dataZ;
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, data);
|
||||
DEFINE_SIZE_ARRAY (4, dataZ);
|
||||
};
|
||||
|
||||
struct KernAAT : KernTable<KernAAT>
|
||||
|
@ -329,9 +329,9 @@ struct KernAAT : KernTable<KernAAT>
|
|||
protected:
|
||||
HBUINT32 version; /* Version--0x00010000u */
|
||||
HBUINT32 nTables; /* Number of subtables in the kerning table. */
|
||||
HBUINT8 data[VAR];
|
||||
UnsizedArrayOf<HBUINT8> dataZ;
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (8, data);
|
||||
DEFINE_SIZE_ARRAY (8, dataZ);
|
||||
};
|
||||
|
||||
struct kern
|
||||
|
|
|
@ -1545,14 +1545,14 @@ struct VarData
|
|||
regionIndices.sanitize(c) &&
|
||||
shortCount <= regionIndices.len &&
|
||||
c->check_array (&StructAfter<HBUINT8> (regionIndices),
|
||||
get_row_size (), itemCount));
|
||||
itemCount, get_row_size ()));
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 itemCount;
|
||||
HBUINT16 shortCount;
|
||||
ArrayOf<HBUINT16> regionIndices;
|
||||
HBUINT8 bytesX[VAR];
|
||||
UnsizedArrayOf<HBUINT8>bytesX;
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY2 (6, regionIndices, bytesX);
|
||||
};
|
||||
|
@ -1749,7 +1749,7 @@ struct FeatureVariationRecord
|
|||
|
||||
struct FeatureVariations
|
||||
{
|
||||
static const unsigned int NOT_FOUND_INDEX = 0xFFFFFFFFu;
|
||||
enum { NOT_FOUND_INDEX = 0xFFFFFFFFu };
|
||||
|
||||
inline bool find_index (const int *coords, unsigned int coord_len,
|
||||
unsigned int *index) const
|
||||
|
@ -1850,7 +1850,7 @@ struct HintingDevice
|
|||
|
||||
unsigned int s = ppem_size - startSize;
|
||||
|
||||
unsigned int byte = deltaValue[s >> (4 - f)];
|
||||
unsigned int byte = deltaValueZ[s >> (4 - f)];
|
||||
unsigned int bits = (byte >> (16 - (((s & ((1 << (4 - f)) - 1)) + 1) << f)));
|
||||
unsigned int mask = (0xFFFFu >> (16 - (1 << f)));
|
||||
|
||||
|
@ -1870,9 +1870,10 @@ struct HintingDevice
|
|||
* 2 Signed 4-bit value, 4 values per uint16
|
||||
* 3 Signed 8-bit value, 2 values per uint16
|
||||
*/
|
||||
HBUINT16 deltaValue[VAR]; /* Array of compressed data */
|
||||
UnsizedArrayOf<HBUINT16>
|
||||
deltaValueZ; /* Array of compressed data */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (6, deltaValue);
|
||||
DEFINE_SIZE_ARRAY (6, deltaValueZ);
|
||||
};
|
||||
|
||||
struct VariationDevice
|
||||
|
|
|
@ -199,7 +199,7 @@ struct ValueFormat : HBUINT16
|
|||
TRACE_SANITIZE (this);
|
||||
unsigned int len = get_len ();
|
||||
|
||||
if (!c->check_array (values, get_size (), count)) return_trace (false);
|
||||
if (!c->check_array (values, count, get_size ())) return_trace (false);
|
||||
|
||||
if (!has_device ()) return_trace (true);
|
||||
|
||||
|
@ -376,7 +376,7 @@ struct AnchorMatrix
|
|||
if (!c->check_struct (this)) return_trace (false);
|
||||
if (unlikely (hb_unsigned_mul_overflows (rows, cols))) return_trace (false);
|
||||
unsigned int count = rows * cols;
|
||||
if (!c->check_array (matrixZ, matrixZ[0].static_size, count)) return_trace (false);
|
||||
if (!c->check_array (matrixZ.arrayZ, count)) return_trace (false);
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (!matrixZ[i].sanitize (c, this)) return_trace (false);
|
||||
return_trace (true);
|
||||
|
@ -384,8 +384,8 @@ struct AnchorMatrix
|
|||
|
||||
HBUINT16 rows; /* Number of rows */
|
||||
protected:
|
||||
OffsetTo<Anchor>
|
||||
matrixZ[VAR]; /* Matrix of offsets to Anchor tables--
|
||||
UnsizedArrayOf<OffsetTo<Anchor> >
|
||||
matrixZ; /* Matrix of offsets to Anchor tables--
|
||||
* from beginning of AnchorMatrix table */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (2, matrixZ);
|
||||
|
@ -621,7 +621,7 @@ struct PairSet
|
|||
unsigned int len2 = valueFormats[1].get_len ();
|
||||
unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
|
||||
|
||||
const PairValueRecord *record = CastP<PairValueRecord> (arrayZ);
|
||||
const PairValueRecord *record = &firstPairValueRecord;
|
||||
unsigned int count = len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
|
@ -640,7 +640,7 @@ struct PairSet
|
|||
unsigned int len2 = valueFormats[1].get_len ();
|
||||
unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
|
||||
|
||||
const PairValueRecord *record = CastP<PairValueRecord> (arrayZ);
|
||||
const PairValueRecord *record = &firstPairValueRecord;
|
||||
c->input->add_array (&record->secondGlyph, len, record_size);
|
||||
}
|
||||
|
||||
|
@ -654,7 +654,6 @@ struct PairSet
|
|||
unsigned int len2 = valueFormats[1].get_len ();
|
||||
unsigned int record_size = HBUINT16::static_size * (1 + len1 + len2);
|
||||
|
||||
const PairValueRecord *record_array = CastP<PairValueRecord> (arrayZ);
|
||||
unsigned int count = len;
|
||||
|
||||
/* Hand-coded bsearch. */
|
||||
|
@ -665,7 +664,7 @@ struct PairSet
|
|||
while (min <= max)
|
||||
{
|
||||
int mid = (min + max) / 2;
|
||||
const PairValueRecord *record = &StructAtOffset<PairValueRecord> (record_array, record_size * mid);
|
||||
const PairValueRecord *record = &StructAtOffset<PairValueRecord> (&firstPairValueRecord, record_size * mid);
|
||||
hb_codepoint_t mid_x = record->secondGlyph;
|
||||
if (x < mid_x)
|
||||
max = mid - 1;
|
||||
|
@ -698,20 +697,21 @@ struct PairSet
|
|||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (!(c->check_struct (this)
|
||||
&& c->check_array (arrayZ, HBUINT16::static_size * closure->stride, len))) return_trace (false);
|
||||
&& c->check_array (&firstPairValueRecord, len, HBUINT16::static_size * closure->stride))) return_trace (false);
|
||||
|
||||
unsigned int count = len;
|
||||
const PairValueRecord *record = CastP<PairValueRecord> (arrayZ);
|
||||
const PairValueRecord *record = &firstPairValueRecord;
|
||||
return_trace (closure->valueFormats[0].sanitize_values_stride_unsafe (c, closure->base, &record->values[0], count, closure->stride) &&
|
||||
closure->valueFormats[1].sanitize_values_stride_unsafe (c, closure->base, &record->values[closure->len1], count, closure->stride));
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 len; /* Number of PairValueRecords */
|
||||
HBUINT16 arrayZ[VAR]; /* Array of PairValueRecords--ordered
|
||||
PairValueRecord firstPairValueRecord;
|
||||
/* Array of PairValueRecords--ordered
|
||||
* by GlyphID of the second glyph */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (2, arrayZ);
|
||||
DEFINE_SIZE_MIN (2);
|
||||
};
|
||||
|
||||
struct PairPosFormat1
|
||||
|
@ -869,7 +869,7 @@ struct PairPosFormat2
|
|||
unsigned int stride = len1 + len2;
|
||||
unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size ();
|
||||
unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count;
|
||||
return_trace (c->check_array (values, record_size, count) &&
|
||||
return_trace (c->check_array (values, count, record_size) &&
|
||||
valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) &&
|
||||
valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride));
|
||||
}
|
||||
|
|
|
@ -541,6 +541,10 @@ struct AlternateSet
|
|||
unsigned int shift = hb_ctz (lookup_mask);
|
||||
unsigned int alt_index = ((lookup_mask & glyph_mask) >> shift);
|
||||
|
||||
/* If alt_index is MAX, randomize feature if it is the rand feature. */
|
||||
if (alt_index == HB_OT_MAP_MAX_VALUE && c->random)
|
||||
alt_index = c->random_number () % count + 1;
|
||||
|
||||
if (unlikely (alt_index > count || alt_index == 0)) return_trace (false);
|
||||
|
||||
c->replace_glyph (alternates[alt_index - 1]);
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "hb-buffer.hh"
|
||||
#include "hb-map.hh"
|
||||
#include "hb-set.hh"
|
||||
#include "hb-ot-map.hh"
|
||||
#include "hb-ot-layout-common.hh"
|
||||
#include "hb-ot-layout-gdef-table.hh"
|
||||
|
||||
|
@ -478,9 +479,12 @@ struct hb_ot_apply_context_t :
|
|||
unsigned int nesting_level_left;
|
||||
unsigned int debug_depth;
|
||||
|
||||
bool has_glyph_classes;
|
||||
bool auto_zwnj;
|
||||
bool auto_zwj;
|
||||
bool has_glyph_classes;
|
||||
bool random;
|
||||
|
||||
uint32_t random_state;
|
||||
|
||||
|
||||
hb_ot_apply_context_t (unsigned int table_index_,
|
||||
|
@ -498,13 +502,16 @@ struct hb_ot_apply_context_t :
|
|||
lookup_props (0),
|
||||
nesting_level_left (HB_MAX_NESTING_LEVEL),
|
||||
debug_depth (0),
|
||||
has_glyph_classes (gdef.has_glyph_classes ()),
|
||||
auto_zwnj (true),
|
||||
auto_zwj (true),
|
||||
has_glyph_classes (gdef.has_glyph_classes ()) {}
|
||||
random (false),
|
||||
random_state (1) {}
|
||||
|
||||
inline void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; }
|
||||
inline void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; }
|
||||
inline void set_auto_zwnj (bool auto_zwnj_) { auto_zwnj = auto_zwnj_; }
|
||||
inline void set_random (bool random_) { random = random_; }
|
||||
inline void set_recurse_func (recurse_func_t func) { recurse_func = func; }
|
||||
inline void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; }
|
||||
inline void set_lookup_props (unsigned int lookup_props_)
|
||||
|
@ -514,6 +521,13 @@ struct hb_ot_apply_context_t :
|
|||
iter_context.init (this, true);
|
||||
}
|
||||
|
||||
inline uint32_t random_number (void)
|
||||
{
|
||||
/* http://www.cplusplus.com/reference/random/minstd_rand/ */
|
||||
random_state = random_state * 48271 % 2147483647;
|
||||
return random_state;
|
||||
}
|
||||
|
||||
inline bool
|
||||
match_properties_mark (hb_codepoint_t glyph,
|
||||
unsigned int glyph_props,
|
||||
|
@ -1222,42 +1236,42 @@ struct Rule
|
|||
inline bool intersects (const hb_set_t *glyphs, ContextClosureLookupContext &lookup_context) const
|
||||
{
|
||||
return context_intersects (glyphs,
|
||||
inputCount, inputZ,
|
||||
inputCount, inputZ.arrayZ,
|
||||
lookup_context);
|
||||
}
|
||||
|
||||
inline void closure (hb_closure_context_t *c, ContextClosureLookupContext &lookup_context) const
|
||||
{
|
||||
TRACE_CLOSURE (this);
|
||||
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
|
||||
const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAtOffset<UnsizedArrayOf<LookupRecord> > (inputZ.arrayZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
|
||||
context_closure_lookup (c,
|
||||
inputCount, inputZ,
|
||||
lookupCount, lookupRecord,
|
||||
inputCount, inputZ.arrayZ,
|
||||
lookupCount, lookupRecord.arrayZ,
|
||||
lookup_context);
|
||||
}
|
||||
|
||||
inline void collect_glyphs (hb_collect_glyphs_context_t *c, ContextCollectGlyphsLookupContext &lookup_context) const
|
||||
{
|
||||
TRACE_COLLECT_GLYPHS (this);
|
||||
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
|
||||
const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAtOffset<UnsizedArrayOf<LookupRecord> > (inputZ.arrayZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
|
||||
context_collect_glyphs_lookup (c,
|
||||
inputCount, inputZ,
|
||||
lookupCount, lookupRecord,
|
||||
inputCount, inputZ.arrayZ,
|
||||
lookupCount, lookupRecord.arrayZ,
|
||||
lookup_context);
|
||||
}
|
||||
|
||||
inline bool would_apply (hb_would_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
|
||||
{
|
||||
TRACE_WOULD_APPLY (this);
|
||||
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
|
||||
return_trace (context_would_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context));
|
||||
const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAtOffset<UnsizedArrayOf<LookupRecord> > (inputZ.arrayZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
|
||||
return_trace (context_would_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, lookup_context));
|
||||
}
|
||||
|
||||
inline bool apply (hb_ot_apply_context_t *c, ContextApplyLookupContext &lookup_context) const
|
||||
{
|
||||
TRACE_APPLY (this);
|
||||
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (inputZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
|
||||
return_trace (context_apply_lookup (c, inputCount, inputZ, lookupCount, lookupRecord, lookup_context));
|
||||
const UnsizedArrayOf<LookupRecord> &lookupRecord = StructAtOffset<UnsizedArrayOf<LookupRecord> > (inputZ.arrayZ, inputZ[0].static_size * (inputCount ? inputCount - 1 : 0));
|
||||
return_trace (context_apply_lookup (c, inputCount, inputZ.arrayZ, lookupCount, lookupRecord.arrayZ, lookup_context));
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -1266,8 +1280,8 @@ struct Rule
|
|||
TRACE_SANITIZE (this);
|
||||
return_trace (inputCount.sanitize (c) &&
|
||||
lookupCount.sanitize (c) &&
|
||||
c->check_range (inputZ,
|
||||
inputZ[0].static_size * inputCount +
|
||||
c->check_range (inputZ.arrayZ,
|
||||
inputZ[0].static_size * (inputCount ? inputCount - 1 : 0) +
|
||||
LookupRecord::static_size * lookupCount));
|
||||
}
|
||||
|
||||
|
@ -1276,9 +1290,11 @@ struct Rule
|
|||
* glyph sequence--includes the first
|
||||
* glyph */
|
||||
HBUINT16 lookupCount; /* Number of LookupRecords */
|
||||
HBUINT16 inputZ[VAR]; /* Array of match inputs--start with
|
||||
UnsizedArrayOf<HBUINT16>
|
||||
inputZ; /* Array of match inputs--start with
|
||||
* second glyph */
|
||||
/*LookupRecord lookupRecordX[VAR];*/ /* Array of LookupRecords--in
|
||||
/*UnsizedArrayOf<LookupRecord>
|
||||
lookupRecordX;*/ /* Array of LookupRecords--in
|
||||
* design order */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, inputZ);
|
||||
|
@ -1595,7 +1611,7 @@ struct ContextFormat3
|
|||
this
|
||||
};
|
||||
return context_intersects (glyphs,
|
||||
glyphCount, (const HBUINT16 *) (coverageZ + 1),
|
||||
glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1),
|
||||
lookup_context);
|
||||
}
|
||||
|
||||
|
@ -1605,13 +1621,13 @@ struct ContextFormat3
|
|||
if (!(this+coverageZ[0]).intersects (c->glyphs))
|
||||
return;
|
||||
|
||||
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount);
|
||||
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ.arrayZ, coverageZ[0].static_size * glyphCount);
|
||||
struct ContextClosureLookupContext lookup_context = {
|
||||
{intersects_coverage},
|
||||
this
|
||||
};
|
||||
context_closure_lookup (c,
|
||||
glyphCount, (const HBUINT16 *) (coverageZ + 1),
|
||||
glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1),
|
||||
lookupCount, lookupRecord,
|
||||
lookup_context);
|
||||
}
|
||||
|
@ -1621,14 +1637,14 @@ struct ContextFormat3
|
|||
TRACE_COLLECT_GLYPHS (this);
|
||||
(this+coverageZ[0]).add_coverage (c->input);
|
||||
|
||||
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount);
|
||||
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ.arrayZ, coverageZ[0].static_size * glyphCount);
|
||||
struct ContextCollectGlyphsLookupContext lookup_context = {
|
||||
{collect_coverage},
|
||||
this
|
||||
};
|
||||
|
||||
context_collect_glyphs_lookup (c,
|
||||
glyphCount, (const HBUINT16 *) (coverageZ + 1),
|
||||
glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1),
|
||||
lookupCount, lookupRecord,
|
||||
lookup_context);
|
||||
}
|
||||
|
@ -1637,12 +1653,12 @@ struct ContextFormat3
|
|||
{
|
||||
TRACE_WOULD_APPLY (this);
|
||||
|
||||
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount);
|
||||
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ.arrayZ, coverageZ[0].static_size * glyphCount);
|
||||
struct ContextApplyLookupContext lookup_context = {
|
||||
{match_coverage},
|
||||
this
|
||||
};
|
||||
return_trace (context_would_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
|
||||
return_trace (context_would_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1), lookupCount, lookupRecord, lookup_context));
|
||||
}
|
||||
|
||||
inline const Coverage &get_coverage (void) const
|
||||
|
@ -1654,12 +1670,12 @@ struct ContextFormat3
|
|||
unsigned int index = (this+coverageZ[0]).get_coverage (c->buffer->cur().codepoint);
|
||||
if (likely (index == NOT_COVERED)) return_trace (false);
|
||||
|
||||
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * glyphCount);
|
||||
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ.arrayZ, coverageZ[0].static_size * glyphCount);
|
||||
struct ContextApplyLookupContext lookup_context = {
|
||||
{match_coverage},
|
||||
this
|
||||
};
|
||||
return_trace (context_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ + 1), lookupCount, lookupRecord, lookup_context));
|
||||
return_trace (context_apply_lookup (c, glyphCount, (const HBUINT16 *) (coverageZ.arrayZ + 1), lookupCount, lookupRecord, lookup_context));
|
||||
}
|
||||
|
||||
inline bool subset (hb_subset_context_t *c) const
|
||||
|
@ -1675,11 +1691,11 @@ struct ContextFormat3
|
|||
if (!c->check_struct (this)) return_trace (false);
|
||||
unsigned int count = glyphCount;
|
||||
if (!count) return_trace (false); /* We want to access coverageZ[0] freely. */
|
||||
if (!c->check_array (coverageZ, coverageZ[0].static_size, count)) return_trace (false);
|
||||
if (!c->check_array (coverageZ.arrayZ, count)) return_trace (false);
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (!coverageZ[i].sanitize (c, this)) return_trace (false);
|
||||
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ, coverageZ[0].static_size * count);
|
||||
return_trace (c->check_array (lookupRecord, lookupRecord[0].static_size, lookupCount));
|
||||
const LookupRecord *lookupRecord = &StructAtOffset<LookupRecord> (coverageZ.arrayZ, coverageZ[0].static_size * count);
|
||||
return_trace (c->check_array (lookupRecord, lookupCount));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
@ -1687,10 +1703,11 @@ struct ContextFormat3
|
|||
HBUINT16 glyphCount; /* Number of glyphs in the input glyph
|
||||
* sequence */
|
||||
HBUINT16 lookupCount; /* Number of LookupRecords */
|
||||
OffsetTo<Coverage>
|
||||
coverageZ[VAR]; /* Array of offsets to Coverage
|
||||
UnsizedArrayOf<OffsetTo<Coverage> >
|
||||
coverageZ; /* Array of offsets to Coverage
|
||||
* table in glyph sequence order */
|
||||
/*LookupRecord lookupRecordX[VAR];*/ /* Array of LookupRecords--in
|
||||
/*UnsizedArrayOf<LookupRecord>
|
||||
lookupRecordX;*/ /* Array of LookupRecords--in
|
||||
* design order */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (6, coverageZ);
|
||||
|
|
|
@ -1068,7 +1068,7 @@ hb_ot_layout_get_size_params (hb_face_t *face,
|
|||
|
||||
struct GSUBProxy
|
||||
{
|
||||
static const unsigned int table_index = 0;
|
||||
enum { table_index = 0 };
|
||||
static const bool inplace = false;
|
||||
typedef OT::SubstLookup Lookup;
|
||||
|
||||
|
@ -1082,7 +1082,7 @@ struct GSUBProxy
|
|||
|
||||
struct GPOSProxy
|
||||
{
|
||||
static const unsigned int table_index = 1;
|
||||
enum { table_index = 1 };
|
||||
static const bool inplace = true;
|
||||
typedef OT::PosLookup Lookup;
|
||||
|
||||
|
@ -1268,6 +1268,11 @@ inline void hb_ot_map_t::apply (const Proxy &proxy,
|
|||
c.set_lookup_mask (lookups[table_index][i].mask);
|
||||
c.set_auto_zwj (lookups[table_index][i].auto_zwj);
|
||||
c.set_auto_zwnj (lookups[table_index][i].auto_zwnj);
|
||||
if (lookups[table_index][i].random)
|
||||
{
|
||||
c.set_random (true);
|
||||
buffer->unsafe_to_break_all ();
|
||||
}
|
||||
apply_string<Proxy> (&c,
|
||||
proxy.table.get_lookup (lookup_index),
|
||||
proxy.accels[lookup_index]);
|
||||
|
|
|
@ -95,7 +95,8 @@ hb_ot_map_builder_t::add_lookups (hb_ot_map_t &m,
|
|||
unsigned int variations_index,
|
||||
hb_mask_t mask,
|
||||
bool auto_zwnj,
|
||||
bool auto_zwj)
|
||||
bool auto_zwj,
|
||||
bool random)
|
||||
{
|
||||
unsigned int lookup_indices[32];
|
||||
unsigned int offset, len;
|
||||
|
@ -122,6 +123,7 @@ hb_ot_map_builder_t::add_lookups (hb_ot_map_t &m,
|
|||
lookup->index = lookup_indices[i];
|
||||
lookup->auto_zwnj = auto_zwnj;
|
||||
lookup->auto_zwj = auto_zwj;
|
||||
lookup->random = random;
|
||||
}
|
||||
|
||||
offset += len;
|
||||
|
@ -208,8 +210,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
|
|||
/* Uses the global bit */
|
||||
bits_needed = 0;
|
||||
else
|
||||
/* Limit to 8 bits per feature. */
|
||||
bits_needed = MIN(8u, hb_bit_storage (info->max_value));
|
||||
/* Limit bits per feature. */
|
||||
bits_needed = MIN(HB_OT_MAP_MAX_BITS, hb_bit_storage (info->max_value));
|
||||
|
||||
if (!info->max_value || next_bit + bits_needed > 8 * sizeof (hb_mask_t))
|
||||
continue; /* Feature disabled, or not enough bits. */
|
||||
|
@ -252,6 +254,7 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
|
|||
map->stage[1] = info->stage[1];
|
||||
map->auto_zwnj = !(info->flags & F_MANUAL_ZWNJ);
|
||||
map->auto_zwj = !(info->flags & F_MANUAL_ZWJ);
|
||||
map->random = !!(info->flags & F_RANDOM);
|
||||
if ((info->flags & F_GLOBAL) && info->max_value == 1) {
|
||||
/* Uses the global bit */
|
||||
map->shift = global_bit_shift;
|
||||
|
@ -301,7 +304,8 @@ hb_ot_map_builder_t::compile (hb_ot_map_t &m,
|
|||
variations_index,
|
||||
m.features[i].mask,
|
||||
m.features[i].auto_zwnj,
|
||||
m.features[i].auto_zwj);
|
||||
m.features[i].auto_zwj,
|
||||
m.features[i].random);
|
||||
|
||||
/* Sort lookups and merge duplicates */
|
||||
if (last_num_lookups < m.lookups[table_index].len)
|
||||
|
|
|
@ -32,6 +32,9 @@
|
|||
#include "hb-buffer.hh"
|
||||
|
||||
|
||||
#define HB_OT_MAP_MAX_BITS 8u
|
||||
#define HB_OT_MAP_MAX_VALUE ((1u << HB_OT_MAP_MAX_BITS) - 1u)
|
||||
|
||||
struct hb_ot_shape_plan_t;
|
||||
|
||||
static const hb_tag_t table_tags[2] = {HB_OT_TAG_GSUB, HB_OT_TAG_GPOS};
|
||||
|
@ -52,6 +55,7 @@ struct hb_ot_map_t
|
|||
unsigned int needs_fallback : 1;
|
||||
unsigned int auto_zwnj : 1;
|
||||
unsigned int auto_zwj : 1;
|
||||
unsigned int random : 1;
|
||||
|
||||
inline int cmp (const hb_tag_t *tag_) const
|
||||
{ return *tag_ < tag ? -1 : *tag_ > tag ? 1 : 0; }
|
||||
|
@ -61,6 +65,7 @@ struct hb_ot_map_t
|
|||
unsigned short index;
|
||||
unsigned short auto_zwnj : 1;
|
||||
unsigned short auto_zwj : 1;
|
||||
unsigned short random : 1;
|
||||
hb_mask_t mask;
|
||||
|
||||
static int cmp (const void *pa, const void *pb)
|
||||
|
@ -167,7 +172,8 @@ enum hb_ot_map_feature_flags_t {
|
|||
F_HAS_FALLBACK = 0x0002u, /* Has fallback implementation, so include mask bit even if feature not found. */
|
||||
F_MANUAL_ZWNJ = 0x0004u, /* Don't skip over ZWNJ when matching **context**. */
|
||||
F_MANUAL_ZWJ = 0x0008u, /* Don't skip over ZWJ when matching **input**. */
|
||||
F_GLOBAL_SEARCH = 0x0010u /* If feature not found in LangSys, look for it in global feature list and pick one. */
|
||||
F_GLOBAL_SEARCH = 0x0010u, /* If feature not found in LangSys, look for it in global feature list and pick one. */
|
||||
F_RANDOM = 0x0020u /* Randomly select a glyph from an AlternateSubstFormat1 subtable. */
|
||||
};
|
||||
HB_MARK_AS_FLAG_T (hb_ot_map_feature_flags_t);
|
||||
/* Macro version for where const is desired. */
|
||||
|
@ -206,7 +212,8 @@ struct hb_ot_map_builder_t
|
|||
unsigned int variations_index,
|
||||
hb_mask_t mask,
|
||||
bool auto_zwnj = true,
|
||||
bool auto_zwj = true);
|
||||
bool auto_zwj = true,
|
||||
bool random = false);
|
||||
|
||||
struct feature_info_t {
|
||||
hb_tag_t tag;
|
||||
|
|
|
@ -234,7 +234,7 @@ struct MathKern
|
|||
TRACE_SANITIZE (this);
|
||||
unsigned int count = 2 * heightCount + 1;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (!mathValueRecords[i].sanitize (c, this)) return_trace (false);
|
||||
if (!mathValueRecordsZ.arrayZ[i].sanitize (c, this)) return_trace (false);
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
|
@ -242,16 +242,14 @@ struct MathKern
|
|||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
c->check_array (mathValueRecords,
|
||||
mathValueRecords[0].static_size,
|
||||
2 * heightCount + 1) &&
|
||||
c->check_array (mathValueRecordsZ.arrayZ, 2 * heightCount + 1) &&
|
||||
sanitize_math_value_records (c));
|
||||
}
|
||||
|
||||
inline hb_position_t get_value (hb_position_t correction_height, hb_font_t *font) const
|
||||
{
|
||||
const MathValueRecord* correctionHeight = mathValueRecords;
|
||||
const MathValueRecord* kernValue = mathValueRecords + heightCount;
|
||||
const MathValueRecord* correctionHeight = mathValueRecordsZ.arrayZ;
|
||||
const MathValueRecord* kernValue = mathValueRecordsZ.arrayZ + heightCount;
|
||||
int sign = font->y_scale < 0 ? -1 : +1;
|
||||
|
||||
/* The description of the MathKern table is a ambiguous, but interpreting
|
||||
|
@ -280,7 +278,8 @@ struct MathKern
|
|||
|
||||
protected:
|
||||
HBUINT16 heightCount;
|
||||
MathValueRecord mathValueRecords[VAR]; /* Array of correction heights at
|
||||
UnsizedArrayOf<MathValueRecord>
|
||||
mathValueRecordsZ; /* Array of correction heights at
|
||||
* which the kern value changes.
|
||||
* Sorted by the height value in
|
||||
* design units (heightCount entries),
|
||||
|
@ -290,7 +289,7 @@ struct MathKern
|
|||
*/
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (2, mathValueRecords);
|
||||
DEFINE_SIZE_ARRAY (2, mathValueRecordsZ);
|
||||
};
|
||||
|
||||
struct MathKernInfoRecord
|
||||
|
@ -588,7 +587,7 @@ struct MathVariants
|
|||
TRACE_SANITIZE (this);
|
||||
unsigned int count = vertGlyphCount + horizGlyphCount;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (!glyphConstruction[i].sanitize (c, this)) return_trace (false);
|
||||
if (!glyphConstruction.arrayZ[i].sanitize (c, this)) return_trace (false);
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
|
@ -598,9 +597,7 @@ struct MathVariants
|
|||
return_trace (c->check_struct (this) &&
|
||||
vertGlyphCoverage.sanitize (c, this) &&
|
||||
horizGlyphCoverage.sanitize (c, this) &&
|
||||
c->check_array (glyphConstruction,
|
||||
glyphConstruction[0].static_size,
|
||||
vertGlyphCount + horizGlyphCount) &&
|
||||
c->check_array (glyphConstruction.arrayZ, vertGlyphCount + horizGlyphCount) &&
|
||||
sanitize_offsets (c));
|
||||
}
|
||||
|
||||
|
@ -670,7 +667,8 @@ struct MathVariants
|
|||
/* Array of offsets to MathGlyphConstruction tables - from the beginning of
|
||||
the MathVariants table, for shapes growing in vertical/horizontal
|
||||
direction. */
|
||||
OffsetTo<MathGlyphConstruction> glyphConstruction[VAR];
|
||||
UnsizedArrayOf<OffsetTo<MathGlyphConstruction> >
|
||||
glyphConstruction;
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (10, glyphConstruction);
|
||||
|
|
|
@ -91,7 +91,7 @@ struct name
|
|||
key.encodingID.set (encoding_id);
|
||||
key.languageID.set (language_id);
|
||||
key.nameID.set (name_id);
|
||||
NameRecord *match = (NameRecord *) bsearch (&key, nameRecord, count, sizeof (nameRecord[0]), NameRecord::cmp);
|
||||
NameRecord *match = (NameRecord *) bsearch (&key, nameRecordZ.arrayZ, count, sizeof (nameRecordZ[0]), NameRecord::cmp);
|
||||
|
||||
if (!match)
|
||||
return 0;
|
||||
|
@ -102,14 +102,14 @@ struct name
|
|||
}
|
||||
|
||||
inline unsigned int get_size (void) const
|
||||
{ return min_size + count * nameRecord[0].min_size; }
|
||||
{ return min_size + count * nameRecordZ[0].min_size; }
|
||||
|
||||
inline bool sanitize_records (hb_sanitize_context_t *c) const {
|
||||
TRACE_SANITIZE (this);
|
||||
char *string_pool = (char *) this + stringOffset;
|
||||
unsigned int _count = count;
|
||||
for (unsigned int i = 0; i < _count; i++)
|
||||
if (!nameRecord[i].sanitize (c, string_pool)) return_trace (false);
|
||||
if (!nameRecordZ[i].sanitize (c, string_pool)) return_trace (false);
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,7 @@ struct name
|
|||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
likely (format == 0 || format == 1) &&
|
||||
c->check_array (nameRecord, nameRecord[0].static_size, count) &&
|
||||
c->check_array (nameRecordZ.arrayZ, count) &&
|
||||
sanitize_records (c));
|
||||
}
|
||||
|
||||
|
@ -126,9 +126,10 @@ struct name
|
|||
HBUINT16 format; /* Format selector (=0/1). */
|
||||
HBUINT16 count; /* Number of name records. */
|
||||
Offset16 stringOffset; /* Offset to start of string storage (from start of table). */
|
||||
NameRecord nameRecord[VAR]; /* The name records where count is the number of records. */
|
||||
UnsizedArrayOf<NameRecord>
|
||||
nameRecordZ; /* The name records where count is the number of records. */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (6, nameRecord);
|
||||
DEFINE_SIZE_ARRAY (6, nameRecordZ);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -55,10 +55,11 @@ struct postV2Tail
|
|||
return_trace (glyphNameIndex.sanitize (c));
|
||||
}
|
||||
|
||||
ArrayOf<HBUINT16>glyphNameIndex; /* This is not an offset, but is the
|
||||
ArrayOf<HBUINT16> glyphNameIndex; /* This is not an offset, but is the
|
||||
* ordinal number of the glyph in 'post'
|
||||
* string tables. */
|
||||
HBUINT8 namesX[VAR]; /* Glyph names with length bytes [variable]
|
||||
UnsizedArrayOf<HBUINT8>
|
||||
namesX; /* Glyph names with length bytes [variable]
|
||||
* (a Pascal string). */
|
||||
|
||||
DEFINE_SIZE_ARRAY2 (2, glyphNameIndex, namesX);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -69,7 +69,7 @@ syllable_tail = (z?.SM.SM?.ZWNJ?)? A{0,3}?;
|
|||
halant_group = (z?.H.(ZWJ.N?)?);
|
||||
final_halant_group = halant_group | H.ZWNJ;
|
||||
medial_group = CM?;
|
||||
halant_or_matra_group = (final_halant_group | (H.ZWJ)? matra_group{0,4});
|
||||
halant_or_matra_group = (final_halant_group | matra_group{0,4});
|
||||
|
||||
|
||||
consonant_syllable = (Repha|CS)? (cn.halant_group){0,4} cn medial_group halant_or_matra_group syllable_tail;
|
||||
|
|
|
@ -273,6 +273,7 @@ struct indic_shape_plan_t
|
|||
const indic_config_t *config;
|
||||
|
||||
bool is_old_spec;
|
||||
bool uniscribe_bug_compatible;
|
||||
mutable hb_atomic_int_t virama_glyph;
|
||||
|
||||
would_substitute_feature_t rphf;
|
||||
|
@ -298,6 +299,7 @@ data_create_indic (const hb_ot_shape_plan_t *plan)
|
|||
}
|
||||
|
||||
indic_plan->is_old_spec = indic_plan->config->has_old_spec && ((plan->map.chosen_script[0] & 0x000000FFu) != '2');
|
||||
indic_plan->uniscribe_bug_compatible = hb_options ().uniscribe_bug_compatible;
|
||||
indic_plan->virama_glyph.set_relaxed (-1);
|
||||
|
||||
/* Use zero-context would_substitute() matching for new-spec of the main
|
||||
|
@ -913,10 +915,12 @@ initial_reordering_standalone_cluster (const hb_ot_shape_plan_t *plan,
|
|||
hb_buffer_t *buffer,
|
||||
unsigned int start, unsigned int end)
|
||||
{
|
||||
const indic_shape_plan_t *indic_plan = (const indic_shape_plan_t *) plan->data;
|
||||
|
||||
/* We treat placeholder/dotted-circle as if they are consonants, so we
|
||||
* should just chain. Only if not in compatibility mode that is... */
|
||||
|
||||
if (hb_options ().uniscribe_bug_compatible)
|
||||
if (indic_plan->uniscribe_bug_compatible)
|
||||
{
|
||||
/* For dotted-circle, this is what Uniscribe does:
|
||||
* If dotted-circle is the last glyph, it just does nothing.
|
||||
|
@ -1356,7 +1360,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
|||
* Uniscribe doesn't do this.
|
||||
* TEST: U+0930,U+094D,U+0915,U+094B,U+094D
|
||||
*/
|
||||
if (!hb_options ().uniscribe_bug_compatible &&
|
||||
if (!indic_plan->uniscribe_bug_compatible &&
|
||||
unlikely (is_halant (info[new_reph_pos]))) {
|
||||
for (unsigned int i = base + 1; i < new_reph_pos; i++)
|
||||
if (info[i].indic_category() == OT_M) {
|
||||
|
@ -1462,7 +1466,7 @@ final_reordering_syllable (const hb_ot_shape_plan_t *plan,
|
|||
/*
|
||||
* Finish off the clusters and go home!
|
||||
*/
|
||||
if (hb_options ().uniscribe_bug_compatible)
|
||||
if (indic_plan->uniscribe_bug_compatible)
|
||||
{
|
||||
switch ((hb_tag_t) plan->props.script)
|
||||
{
|
||||
|
|
|
@ -90,10 +90,14 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
|
|||
break;
|
||||
}
|
||||
|
||||
/* Automatic fractions. */
|
||||
map->add_feature (HB_TAG ('f','r','a','c'), 1, F_NONE);
|
||||
map->add_feature (HB_TAG ('n','u','m','r'), 1, F_NONE);
|
||||
map->add_feature (HB_TAG ('d','n','o','m'), 1, F_NONE);
|
||||
|
||||
/* Random! */
|
||||
map->add_feature (HB_TAG ('r','a','n','d'), HB_OT_MAP_MAX_VALUE, F_GLOBAL | F_RANDOM);
|
||||
|
||||
if (planner->shaper->collect_features)
|
||||
planner->shaper->collect_features (planner);
|
||||
|
||||
|
@ -117,7 +121,8 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
|
|||
if (planner->shaper->override_features)
|
||||
planner->shaper->override_features (planner);
|
||||
|
||||
for (unsigned int i = 0; i < num_user_features; i++) {
|
||||
for (unsigned int i = 0; i < num_user_features; i++)
|
||||
{
|
||||
const hb_feature_t *feature = &user_features[i];
|
||||
map->add_feature (feature->tag, feature->value,
|
||||
(feature->start == 0 && feature->end == (unsigned int) -1) ?
|
||||
|
|
|
@ -93,6 +93,7 @@ struct SegmentMaps : ArrayOf<AxisValueMap>
|
|||
(value - arrayZ[i-1].fromCoord) + denom/2) / denom;
|
||||
}
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (2, arrayZ);
|
||||
};
|
||||
|
||||
|
@ -108,7 +109,7 @@ struct avar
|
|||
c->check_struct (this))))
|
||||
return_trace (false);
|
||||
|
||||
const SegmentMaps *map = axisSegmentMapsZ;
|
||||
const SegmentMaps *map = axisSegmentMapsZ.arrayZ;
|
||||
unsigned int count = axisCount;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
|
@ -124,7 +125,7 @@ struct avar
|
|||
{
|
||||
unsigned int count = MIN<unsigned int> (coords_length, axisCount);
|
||||
|
||||
const SegmentMaps *map = axisSegmentMapsZ;
|
||||
const SegmentMaps *map = axisSegmentMapsZ.arrayZ;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
{
|
||||
coords[i] = map->map (coords[i]);
|
||||
|
@ -139,7 +140,8 @@ struct avar
|
|||
HBUINT16 axisCount; /* The number of variation axes in the font. This
|
||||
* must be the same number as axisCount in the
|
||||
* 'fvar' table. */
|
||||
SegmentMaps axisSegmentMapsZ[VAR];
|
||||
UnsizedArrayOf<SegmentMaps>
|
||||
axisSegmentMapsZ;
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_MIN (8);
|
||||
|
|
|
@ -46,20 +46,21 @@ struct InstanceRecord
|
|||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
c->check_array (coordinates, coordinates[0].static_size, axis_count));
|
||||
c->check_array (coordinatesZ.arrayZ, axis_count));
|
||||
}
|
||||
|
||||
protected:
|
||||
NameID subfamilyNameID;/* The name ID for entries in the 'name' table
|
||||
* that provide subfamily names for this instance. */
|
||||
HBUINT16 reserved; /* Reserved for future use — set to 0. */
|
||||
Fixed coordinates[VAR];/* The coordinates array for this instance. */
|
||||
UnsizedArrayOf<Fixed>
|
||||
coordinatesZ; /* The coordinates array for this instance. */
|
||||
//NameID postScriptNameIDX;/*Optional. The name ID for entries in the 'name'
|
||||
// * table that provide PostScript names for this
|
||||
// * instance. */
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, coordinates);
|
||||
DEFINE_SIZE_ARRAY (4, coordinatesZ);
|
||||
};
|
||||
|
||||
struct AxisRecord
|
||||
|
|
|
@ -39,7 +39,7 @@ struct DeltaSetIndexMap
|
|||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
c->check_array (mapData, get_width (), mapCount));
|
||||
c->check_array (mapDataZ.arrayZ, mapCount, get_width ()));
|
||||
}
|
||||
|
||||
unsigned int map (unsigned int v) const /* Returns 16.16 outer.inner. */
|
||||
|
@ -55,7 +55,7 @@ struct DeltaSetIndexMap
|
|||
unsigned int u = 0;
|
||||
{ /* Fetch it. */
|
||||
unsigned int w = get_width ();
|
||||
const HBUINT8 *p = mapData + w * v;
|
||||
const HBUINT8 *p = mapDataZ.arrayZ + w * v;
|
||||
for (; w; w--)
|
||||
u = (u << 8) + *p++;
|
||||
}
|
||||
|
@ -81,10 +81,11 @@ struct DeltaSetIndexMap
|
|||
HBUINT16 format; /* A packed field that describes the compressed
|
||||
* representation of delta-set indices. */
|
||||
HBUINT16 mapCount; /* The number of mapping entries. */
|
||||
HBUINT8 mapData[VAR]; /* The delta-set index mapping data. */
|
||||
UnsizedArrayOf<HBUINT8>
|
||||
mapDataZ; /* The delta-set index mapping data. */
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (4, mapData);
|
||||
DEFINE_SIZE_ARRAY (4, mapDataZ);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -68,14 +68,14 @@ struct MVAR
|
|||
c->check_struct (this) &&
|
||||
valueRecordSize >= VariationValueRecord::static_size &&
|
||||
varStore.sanitize (c, this) &&
|
||||
c->check_array (values, valueRecordSize, valueRecordCount));
|
||||
c->check_array (valuesZ.arrayZ, valueRecordCount, valueRecordSize));
|
||||
}
|
||||
|
||||
inline float get_var (hb_tag_t tag,
|
||||
int *coords, unsigned int coord_count) const
|
||||
{
|
||||
const VariationValueRecord *record;
|
||||
record = (VariationValueRecord *) bsearch (&tag, values,
|
||||
record = (VariationValueRecord *) bsearch (&tag, valuesZ.arrayZ,
|
||||
valueRecordCount, valueRecordSize,
|
||||
tag_compare);
|
||||
if (!record)
|
||||
|
@ -101,11 +101,12 @@ protected:
|
|||
HBUINT16 valueRecordCount;/* The number of value records — may be zero. */
|
||||
OffsetTo<VariationStore>
|
||||
varStore; /* Offset to item variation store table. */
|
||||
HBUINT8 values[VAR]; /* Array of value records. The records must be
|
||||
UnsizedArrayOf<HBUINT8>
|
||||
valuesZ; /* Array of value records. The records must be
|
||||
* in binary order of their valueTag field. */
|
||||
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (12, values);
|
||||
DEFINE_SIZE_ARRAY (12, valuesZ);
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
|
|
@ -50,8 +50,8 @@ struct hb_set_digest_lowest_bits_t
|
|||
{
|
||||
ASSERT_POD ();
|
||||
|
||||
static const unsigned int mask_bytes = sizeof (mask_t);
|
||||
static const unsigned int mask_bits = sizeof (mask_t) * 8;
|
||||
enum { mask_bytes = sizeof (mask_t) };
|
||||
enum { mask_bits = sizeof (mask_t) * 8 };
|
||||
static const unsigned int num_bits = 0
|
||||
+ (mask_bytes >= 1 ? 3 : 0)
|
||||
+ (mask_bytes >= 2 ? 1 : 0)
|
||||
|
|
|
@ -157,7 +157,7 @@ struct hb_set_t
|
|||
}
|
||||
|
||||
typedef unsigned long long elt_t;
|
||||
static const unsigned int PAGE_BITS = 512;
|
||||
enum { PAGE_BITS = 512 };
|
||||
static_assert ((PAGE_BITS & ((PAGE_BITS) - 1)) == 0, "");
|
||||
|
||||
static inline unsigned int elt_get_min (const elt_t &elt) { return hb_ctz (elt); }
|
||||
|
@ -165,11 +165,11 @@ struct hb_set_t
|
|||
|
||||
typedef hb_vector_size_t<elt_t, PAGE_BITS / 8> vector_t;
|
||||
|
||||
static const unsigned int ELT_BITS = sizeof (elt_t) * 8;
|
||||
static const unsigned int ELT_MASK = ELT_BITS - 1;
|
||||
static const unsigned int BITS = sizeof (vector_t) * 8;
|
||||
static const unsigned int MASK = BITS - 1;
|
||||
static_assert (PAGE_BITS == BITS, "");
|
||||
enum { ELT_BITS = sizeof (elt_t) * 8 };
|
||||
enum { ELT_MASK = ELT_BITS - 1 };
|
||||
enum { BITS = sizeof (vector_t) * 8 };
|
||||
enum { MASK = BITS - 1 };
|
||||
static_assert ((unsigned) PAGE_BITS == (unsigned) BITS, "");
|
||||
|
||||
elt_t &elt (hb_codepoint_t g) { return v[(g & MASK) / ELT_BITS]; }
|
||||
elt_t const &elt (hb_codepoint_t g) const { return v[(g & MASK) / ELT_BITS]; }
|
||||
|
|
|
@ -40,6 +40,11 @@
|
|||
HB_BEGIN_DECLS
|
||||
|
||||
|
||||
/**
|
||||
* HB_UNICODE_MAX
|
||||
*
|
||||
* Since: 1.9.0
|
||||
*/
|
||||
#define HB_UNICODE_MAX 0x10FFFFu
|
||||
|
||||
|
||||
|
|
|
@ -392,7 +392,7 @@ _hb_rename_font (hb_blob_t *blob, wchar_t *new_name)
|
|||
name.stringOffset.set (name.get_size ());
|
||||
for (unsigned int i = 0; i < ARRAY_LENGTH (name_IDs); i++)
|
||||
{
|
||||
OT::NameRecord &record = name.nameRecord[i];
|
||||
OT::NameRecord &record = name.nameRecordZ[i];
|
||||
record.platformID.set (3);
|
||||
record.encodingID.set (1);
|
||||
record.languageID.set (0x0409u); /* English */
|
||||
|
|
|
@ -37,10 +37,10 @@ HB_BEGIN_DECLS
|
|||
|
||||
|
||||
#define HB_VERSION_MAJOR 1
|
||||
#define HB_VERSION_MINOR 8
|
||||
#define HB_VERSION_MICRO 8
|
||||
#define HB_VERSION_MINOR 9
|
||||
#define HB_VERSION_MICRO 0
|
||||
|
||||
#define HB_VERSION_STRING "1.8.8"
|
||||
#define HB_VERSION_STRING "1.9.0"
|
||||
|
||||
#define HB_VERSION_ATLEAST(major,minor,micro) \
|
||||
((major)*10000+(minor)*100+(micro) <= \
|
||||
|
|
|
@ -6,6 +6,7 @@ TESTS = \
|
|||
tests/arabic-stch.tests \
|
||||
tests/automatic-fractions.tests \
|
||||
tests/cluster.tests \
|
||||
tests/collections.tests \
|
||||
tests/color-fonts.tests \
|
||||
tests/context-matching.tests \
|
||||
tests/cursive-positioning.tests \
|
||||
|
@ -32,6 +33,7 @@ TESTS = \
|
|||
tests/mongolian-variation-selector.tests \
|
||||
tests/myanmar-syllable.tests \
|
||||
tests/none-directional.tests \
|
||||
tests/rand.tests \
|
||||
tests/spaces.tests \
|
||||
tests/simple.tests \
|
||||
tests/sinhala.tests \
|
||||
|
|
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 3.4 KiB |
Binary file not shown.
|
@ -0,0 +1,6 @@
|
|||
../fonts/TestDFONT.dfont:--face-index=0 --font-funcs=ot:U+2026,U+0020,U+002E:[ellipsis=0+723|space=1+250|period=2+241]
|
||||
../fonts/TestDFONT.dfont:--face-index=1 --font-funcs=ot:U+2026,U+0020,U+002E:[gid0=0+1000|gid0=1+1000|gid0=2+1000]
|
||||
../fonts/TestDFONT.dfont:--face-index=2 --font-funcs=ot:U+2026,U+0020,U+002E:[gid0=0+1000|gid0=1+1000|gid0=2+1000]
|
||||
../fonts/TestTTC.ttc:--face-index=0 --font-funcs=ot:U+2026,U+0020,U+002E:[ellipsis=0+723|space=1+250|period=2+241]
|
||||
../fonts/TestTTC.ttc:--face-index=1 --font-funcs=ot:U+2026,U+0020,U+002E:[ellipsis=0+723|space=1+250|period=2+241]
|
||||
../fonts/TestTTC.ttc:--face-index=2 --font-funcs=ot:U+2026,U+0020,U+002E:[gid0=0+1000|gid0=1+1000|gid0=2+1000]
|
|
@ -0,0 +1,3 @@
|
|||
../fonts/5bb74492f5e0ffa1fbb72e4c881be035120b6513.ttf:--no-glyph-names --features=-rand:U+0054,U+0055,U+0056:[1=0+560|2=1+602|3=2+602]
|
||||
../fonts/5bb74492f5e0ffa1fbb72e4c881be035120b6513.ttf:--no-glyph-names --features=rand=2:U+0054,U+0055,U+0056:[5=0+560|8=1+602|11=2+602]
|
||||
../fonts/5bb74492f5e0ffa1fbb72e4c881be035120b6513.ttf:--no-glyph-names:U+0054,U+0055,U+0056,U+0054,U+0055,U+0056,U+0054,U+0055,U+0056,U+0054,U+0055,U+0056:[5=0+560|7=1+602|10=2+602|4=3+560|7=4+602|10=5+602|6=6+560|9=7+602|10=8+602|5=9+560|8=10+602|12=11+602]
|
|
@ -125,7 +125,7 @@ helper_cairo_create_scaled_font (const font_options_t *font_opts)
|
|||
}
|
||||
#endif
|
||||
|
||||
cairo_face = cairo_ft_font_face_create_for_ft_face (ft_face, 0);
|
||||
cairo_face = cairo_ft_font_face_create_for_ft_face (ft_face, font_opts->ft_load_flags);
|
||||
}
|
||||
cairo_matrix_t ctm, font_matrix;
|
||||
cairo_font_options_t *font_options;
|
||||
|
|
|
@ -419,7 +419,7 @@ shape_options_t::add_options (option_parser_t *parser)
|
|||
{"cluster-level", 0, 0, G_OPTION_ARG_INT, &this->cluster_level, "Cluster merging level (default: 0)", "0/1/2"},
|
||||
{"normalize-glyphs",0, 0, G_OPTION_ARG_NONE, &this->normalize_glyphs, "Rearrange glyph clusters in nominal order", nullptr},
|
||||
{"verify", 0, 0, G_OPTION_ARG_NONE, &this->verify, "Perform sanity checks on shaping results", nullptr},
|
||||
{"num-iterations", 0, 0, G_OPTION_ARG_INT, &this->num_iterations, "Run shaper N times (default: 1)", "N"},
|
||||
{"num-iterations", 'n', 0, G_OPTION_ARG_INT, &this->num_iterations, "Run shaper N times (default: 1)", "N"},
|
||||
{nullptr}
|
||||
};
|
||||
parser->add_group (entries,
|
||||
|
@ -556,6 +556,7 @@ font_options_t::add_options (option_parser_t *parser)
|
|||
{"font-ppem", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_font_ppem, "Set x,y pixels per EM (default: 0; disabled)", "1/2 integers"},
|
||||
{"font-ptem", 0, 0, G_OPTION_ARG_DOUBLE, &this->ptem, "Set font point-size (default: 0; disabled)", "point-size"},
|
||||
{"font-funcs", 0, 0, G_OPTION_ARG_STRING, &this->font_funcs, text, "impl"},
|
||||
{"ft-load-flags", 0, 0, G_OPTION_ARG_INT, &this->ft_load_flags, "Set FreeType load-flags (default: 2)", "integer"},
|
||||
{nullptr}
|
||||
};
|
||||
parser->add_group (entries,
|
||||
|
@ -717,6 +718,9 @@ font_options_t::get_font (void) const
|
|||
}
|
||||
}
|
||||
set_font_funcs (font);
|
||||
#ifdef HAVE_FREETYPE
|
||||
hb_ft_font_set_load_flags (font, ft_load_flags);
|
||||
#endif
|
||||
|
||||
return font;
|
||||
}
|
||||
|
|
|
@ -454,6 +454,7 @@ struct font_options_t : option_group_t
|
|||
face_index = 0;
|
||||
font_size_x = font_size_y = default_font_size;
|
||||
font_funcs = nullptr;
|
||||
ft_load_flags = 2;
|
||||
|
||||
blob = nullptr;
|
||||
font = nullptr;
|
||||
|
@ -484,6 +485,7 @@ struct font_options_t : option_group_t
|
|||
mutable double font_size_x;
|
||||
mutable double font_size_y;
|
||||
char *font_funcs;
|
||||
int ft_load_flags;
|
||||
|
||||
private:
|
||||
mutable hb_font_t *font;
|
||||
|
|
Loading…
Reference in New Issue