Merge branch 'master' into cff-subset

This commit is contained in:
Michiharu Ariza 2018-10-09 22:00:10 -07:00
commit c06a5dff0b
19 changed files with 364 additions and 138 deletions

View File

@ -237,6 +237,7 @@ hb_font_funcs_set_glyph_v_advance_func
hb_font_funcs_set_glyph_v_advances_func
hb_font_funcs_set_glyph_v_origin_func
hb_font_funcs_set_nominal_glyph_func
hb_font_funcs_set_nominal_glyphs_func
hb_font_funcs_set_user_data
hb_font_funcs_set_variation_glyph_func
hb_font_funcs_t
@ -273,6 +274,8 @@ hb_font_get_glyph_v_origin
hb_font_get_glyph_v_origin_func_t
hb_font_get_nominal_glyph
hb_font_get_nominal_glyph_func_t
hb_font_get_nominal_glyphs
hb_font_get_nominal_glyphs_func_t
hb_font_get_parent
hb_font_get_ppem
hb_font_get_ptem

View File

@ -518,6 +518,7 @@ struct hb_aat_apply_context_t :
static return_t default_return_value (void) { return false; }
bool stop_sublookup_iteration (return_t r) const { return r; }
hb_ot_shape_plan_t *plan;
hb_font_t *font;
hb_face_t *face;
hb_buffer_t *buffer;
@ -527,15 +528,17 @@ struct hb_aat_apply_context_t :
unsigned int lookup_index;
unsigned int debug_depth;
inline hb_aat_apply_context_t (hb_font_t *font_,
inline hb_aat_apply_context_t (hb_ot_shape_plan_t *plan_,
hb_font_t *font_,
hb_buffer_t *buffer_,
hb_blob_t *table) :
font (font_), face (font->face), buffer (buffer_),
plan (plan_), font (font_), face (font->face), buffer (buffer_),
sanitizer (), lookup_index (0), debug_depth (0)
{
sanitizer.init (table);
sanitizer.set_num_glyphs (face->get_num_glyphs ());
sanitizer.start_processing ();
sanitizer.set_max_ops (HB_SANITIZE_MAX_OPS_MAX);
}
inline void set_lookup_index (unsigned int i) { lookup_index = i; }

View File

@ -59,7 +59,9 @@ struct KerxSubTableFormat0
{
TRACE_APPLY (this);
/* TODO */
hb_kern_machine_t<KerxSubTableFormat0> machine (*this);
machine.kern (c->font, c->buffer, c->plan->kern_mask);
return_trace (true);
}
@ -110,11 +112,9 @@ struct KerxSubTableFormat2
unsigned int l = *(this+leftClassTable).get_value (left, num_glyphs);
unsigned int r = *(this+rightClassTable).get_value (right, num_glyphs);
unsigned int offset = l + r;
const FWORD *arr = &(this+array);
if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end))
return 0;
const FWORD *v = &StructAtOffset<FWORD> (arr, offset);
if (unlikely ((const void *) v < (const void *) arr || (const void *) (v + 1) > (const void *) end))
const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset);
if (unlikely ((const char *) v < (const char *) &array ||
(const char *) v > (const char *) end - 2))
return 0;
return *v;
}
@ -123,7 +123,11 @@ struct KerxSubTableFormat2
{
TRACE_APPLY (this);
/* TODO */
accelerator_t accel (*this,
c->sanitizer.end,
c->face->get_num_glyphs ());
hb_kern_machine_t<accelerator_t> machine (accel);
machine.kern (c->font, c->buffer, c->plan->kern_mask);
return_trace (true);
}
@ -138,6 +142,22 @@ struct KerxSubTableFormat2
array.sanitize (c, this)));
}
struct accelerator_t
{
const KerxSubTableFormat2 &table;
const char *end;
unsigned int num_glyphs;
inline accelerator_t (const KerxSubTableFormat2 &table_,
const char *end_, unsigned int num_glyphs_)
: table (table_), end (end_), num_glyphs (num_glyphs_) {}
inline int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
{
return table.get_kerning (left, right, end, num_glyphs);
}
};
protected:
HBUINT32 rowWidth; /* The width, in bytes, of a row in the table. */
LOffsetTo<Lookup<HBUINT16> >
@ -222,7 +242,7 @@ struct KerxTable
Vertical = 0x80000000, /* Set if table has vertical kerning values. */
CrossStream = 0x40000000, /* Set if table has cross-stream kerning values. */
Variation = 0x20000000, /* Set if table has variation kerning values. */
ProcessDirection = 0x10000000, /* If clear, process the glyphs forwards, that
Backwards = 0x10000000, /* If clear, process the glyphs forwards, that
* is, from first to last in the glyph stream.
* If we, process them from last to first.
* This flag only applies to state-table based
@ -272,22 +292,6 @@ public:
DEFINE_SIZE_MIN (12);
};
struct SubtableXXX
{
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (likely (c->check_struct (this)));
}
protected:
HBUINT32 length;
HBUINT32 coverage;
HBUINT32 tupleCount;
public:
DEFINE_SIZE_STATIC (12);
};
/*
* The 'kerx' Table
@ -313,9 +317,9 @@ struct kerx
goto skip;
if (table->coverage & KerxTable::CrossStream)
goto skip; /* We do NOT handle cross-stream kerning. */
goto skip; /* We do NOT handle cross-stream kerning. None of Apple fonts use it. */
reverse = bool (table->coverage & KerxTable::ProcessDirection) !=
reverse = bool (table->coverage & KerxTable::Backwards) !=
HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
if (!c->buffer->message (c->font, "start kerx subtable %d", c->lookup_index))
@ -324,7 +328,12 @@ struct kerx
if (reverse)
c->buffer->reverse ();
/* XXX Reverse-kern is not working yet... */
c->sanitizer.set_object (*table);
/* XXX Reverse-kern is not working yet...
* hb_kern_machine_t would need to know that it's reverse-kerning.
* Or better yet, make it work in reverse as well, so we don't have
* to reverse and reverse back? */
table->dispatch (c);
if (reverse)

View File

@ -752,7 +752,7 @@ struct ChainSubtable
Vertical = 0x80000000, /* If set, this subtable will only be applied
* to vertical text. If clear, this subtable
* will only be applied to horizontal text. */
Descending = 0x40000000, /* If set, this subtable will process glyphs
Backwards = 0x40000000, /* If set, this subtable will process glyphs
* in descending order. If clear, it will
* process the glyphs in ascending order. */
AllDirections = 0x20000000, /* If set, this subtable will be applied to
@ -876,8 +876,8 @@ struct Chain
may be right-to-left or left-to-right).
*/
reverse = subtable->coverage & ChainSubtable::Logical ?
bool (subtable->coverage & ChainSubtable::Descending) :
bool (subtable->coverage & ChainSubtable::Descending) !=
bool (subtable->coverage & ChainSubtable::Backwards) :
bool (subtable->coverage & ChainSubtable::Backwards) !=
HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
if (!c->buffer->message (c->font, "start chain subtable %d", c->lookup_index))
@ -886,6 +886,8 @@ struct Chain
if (reverse)
c->buffer->reverse ();
c->sanitizer.set_object (*subtable);
subtable->dispatch (c);
if (reverse)

View File

@ -62,17 +62,21 @@ hb_aat_layout_has_substitution (hb_face_t *face)
}
void
hb_aat_layout_substitute (hb_font_t *font, hb_buffer_t *buffer)
hb_aat_layout_substitute (hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
hb_blob_t *blob;
const AAT::morx& morx = _get_morx (font->face, &blob);
AAT::hb_aat_apply_context_t c (font, buffer, blob);
AAT::hb_aat_apply_context_t c (plan, font, buffer, blob);
morx.apply (&c);
}
void
hb_aat_layout_position (hb_font_t *font, hb_buffer_t *buffer)
hb_aat_layout_position (hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer)
{
#if 0
hb_blob_t *blob;

View File

@ -29,17 +29,19 @@
#include "hb.hh"
#include "hb-font.hh"
#include "hb-buffer.hh"
#include "hb-open-type.hh"
#include "hb-ot-shape.hh"
HB_INTERNAL hb_bool_t
hb_aat_layout_has_substitution (hb_face_t *face);
HB_INTERNAL void
hb_aat_layout_substitute (hb_font_t *font, hb_buffer_t *buffer);
hb_aat_layout_substitute (hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
HB_INTERNAL void
hb_aat_layout_position (hb_font_t *font, hb_buffer_t *buffer);
hb_aat_layout_position (hb_ot_shape_plan_t *plan,
hb_font_t *font,
hb_buffer_t *buffer);
#endif /* HB_AAT_LAYOUT_HH */

View File

@ -260,7 +260,8 @@ struct hb_buffer_t
{
if (have_output)
{
if (unlikely (out_info != info || out_len != idx)) {
if (out_info != info || out_len != idx)
{
if (unlikely (!make_room_for (1, 1))) return;
out_info[out_len] = info[idx];
}
@ -269,6 +270,23 @@ struct hb_buffer_t
idx++;
}
/* Copies n glyphs at idx to output and advance idx.
* If there's no output, just advance idx. */
inline void
next_glyphs (unsigned int n)
{
if (have_output)
{
if (out_info != info || out_len != idx)
{
if (unlikely (!make_room_for (n, n))) return;
memmove (out_info + out_len, info + idx, n * sizeof (out_info[0]));
}
out_len += n;
}
idx += n;
}
/* Advance idx without copying to output. */
inline void skip_glyph (void)
{

View File

@ -31,6 +31,8 @@
#include "hb-font.hh"
#include "hb-machinery.hh"
#include "hb-ot.h"
/*
* hb_font_funcs_t
@ -101,9 +103,42 @@ hb_font_get_nominal_glyph_default (hb_font_t *font,
hb_codepoint_t *glyph,
void *user_data HB_UNUSED)
{
if (font->has_nominal_glyphs_func ())
{
return font->get_nominal_glyphs (1, &unicode, 0, glyph, 0);
}
return font->parent->get_nominal_glyph (unicode, glyph);
}
#define hb_font_get_nominal_glyphs_nil hb_font_get_nominal_glyphs_default
static unsigned int
hb_font_get_nominal_glyphs_default (hb_font_t *font,
void *font_data HB_UNUSED,
unsigned int count,
const hb_codepoint_t *first_unicode,
unsigned int unicode_stride,
hb_codepoint_t *first_glyph,
unsigned int glyph_stride,
void *user_data HB_UNUSED)
{
if (font->has_nominal_glyph_func ())
{
for (unsigned int i = 0; i < count; i++)
{
if (!font->get_nominal_glyph (*first_unicode, first_glyph))
return i;
first_unicode = &StructAtOffset<hb_codepoint_t> (first_unicode, unicode_stride);
first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride);
}
return count;
}
return font->parent->get_nominal_glyphs (count,
first_unicode, unicode_stride,
first_glyph, glyph_stride);
}
static hb_bool_t
hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
@ -807,7 +842,7 @@ hb_font_get_glyph_v_advance (hb_font_t *font,
**/
void
hb_font_get_glyph_h_advances (hb_font_t* font,
unsigned count,
unsigned int count,
const hb_codepoint_t *first_glyph,
unsigned glyph_stride,
hb_position_t *first_advance,
@ -825,7 +860,7 @@ hb_font_get_glyph_h_advances (hb_font_t* font,
**/
void
hb_font_get_glyph_v_advances (hb_font_t* font,
unsigned count,
unsigned int count,
const hb_codepoint_t *first_glyph,
unsigned glyph_stride,
hb_position_t *first_advance,
@ -1052,7 +1087,7 @@ hb_font_get_glyph_advance_for_direction (hb_font_t *font,
HB_EXTERN void
hb_font_get_glyph_advances_for_direction (hb_font_t* font,
hb_direction_t direction,
unsigned count,
unsigned int count,
const hb_codepoint_t *first_glyph,
unsigned glyph_stride,
hb_position_t *first_advance,
@ -1271,18 +1306,8 @@ DEFINE_NULL_INSTANCE (hb_font_t) =
};
/**
* hb_font_create: (Xconstructor)
* @face: a face.
*
*
*
* Return value: (transfer full):
*
* Since: 0.9.2
**/
hb_font_t *
hb_font_create (hb_face_t *face)
static hb_font_t *
_hb_font_create (hb_face_t *face)
{
hb_font_t *font;
@ -1301,6 +1326,27 @@ hb_font_create (hb_face_t *face)
return font;
}
/**
* hb_font_create: (Xconstructor)
* @face: a face.
*
*
*
* Return value: (transfer full):
*
* Since: 0.9.2
**/
hb_font_t *
hb_font_create (hb_face_t *face)
{
hb_font_t *font = _hb_font_create (face);
/* Install our in-house, very lightweight, funcs. */
hb_ot_font_set_funcs (font);
return font;
}
/**
* hb_font_create_sub_font:
* @parent: parent font.
@ -1317,7 +1363,7 @@ hb_font_create_sub_font (hb_font_t *parent)
if (unlikely (!parent))
parent = hb_font_get_empty ();
hb_font_t *font = hb_font_create (parent->face);
hb_font_t *font = _hb_font_create (parent->face);
if (unlikely (hb_object_is_inert (font)))
return font;

View File

@ -125,6 +125,14 @@ typedef hb_bool_t (*hb_font_get_variation_glyph_func_t) (hb_font_t *font, void *
hb_codepoint_t *glyph,
void *user_data);
typedef unsigned int (*hb_font_get_nominal_glyphs_func_t) (hb_font_t *font, void *font_data,
unsigned int count,
const hb_codepoint_t *first_unicode,
unsigned int unicode_stride,
hb_codepoint_t *first_glyph,
unsigned int glyph_stride,
void *user_data);
typedef hb_position_t (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
@ -133,7 +141,7 @@ typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_h_advance_func_t;
typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_v_advance_func_t;
typedef void (*hb_font_get_glyph_advances_func_t) (hb_font_t* font, void* font_data,
unsigned count,
unsigned int count,
const hb_codepoint_t *first_glyph,
unsigned glyph_stride,
hb_position_t *first_advance,
@ -220,6 +228,22 @@ hb_font_funcs_set_nominal_glyph_func (hb_font_funcs_t *ffuncs,
hb_font_get_nominal_glyph_func_t func,
void *user_data, hb_destroy_func_t destroy);
/**
* hb_font_funcs_set_nominal_glyphs_func:
* @ffuncs: font functions.
* @func: (closure user_data) (destroy destroy) (scope notified):
* @user_data:
* @destroy:
*
*
*
* Since: REPLACEME
**/
HB_EXTERN void
hb_font_funcs_set_nominal_glyphs_func (hb_font_funcs_t *ffuncs,
hb_font_get_nominal_glyphs_func_t func,
void *user_data, hb_destroy_func_t destroy);
/**
* hb_font_funcs_set_variation_glyph_func:
* @ffuncs: font functions.
@ -423,14 +447,14 @@ hb_font_get_glyph_v_advance (hb_font_t *font,
HB_EXTERN void
hb_font_get_glyph_h_advances (hb_font_t* font,
unsigned count,
unsigned int count,
const hb_codepoint_t *first_glyph,
unsigned glyph_stride,
hb_position_t *first_advance,
unsigned advance_stride);
HB_EXTERN void
hb_font_get_glyph_v_advances (hb_font_t* font,
unsigned count,
unsigned int count,
const hb_codepoint_t *first_glyph,
unsigned glyph_stride,
hb_position_t *first_advance,
@ -486,7 +510,7 @@ hb_font_get_glyph_advance_for_direction (hb_font_t *font,
HB_EXTERN void
hb_font_get_glyph_advances_for_direction (hb_font_t* font,
hb_direction_t direction,
unsigned count,
unsigned int count,
const hb_codepoint_t *first_glyph,
unsigned glyph_stride,
hb_position_t *first_advance,

View File

@ -43,6 +43,7 @@
HB_FONT_FUNC_IMPLEMENT (font_h_extents) \
HB_FONT_FUNC_IMPLEMENT (font_v_extents) \
HB_FONT_FUNC_IMPLEMENT (nominal_glyph) \
HB_FONT_FUNC_IMPLEMENT (nominal_glyphs) \
HB_FONT_FUNC_IMPLEMENT (variation_glyph) \
HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \
HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \
@ -212,6 +213,18 @@ struct hb_font_t
unicode, glyph,
klass->user_data.nominal_glyph);
}
inline unsigned int get_nominal_glyphs (unsigned int count,
const hb_codepoint_t *first_unicode,
unsigned int unicode_stride,
hb_codepoint_t *first_glyph,
unsigned int glyph_stride)
{
return klass->get.f.nominal_glyphs (this, user_data,
count,
first_unicode, unicode_stride,
first_glyph, glyph_stride,
klass->user_data.nominal_glyphs);
}
inline hb_bool_t get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph)
@ -377,7 +390,7 @@ struct hb_font_t
*y = get_glyph_v_advance (glyph);
}
inline void get_glyph_advances_for_direction (hb_direction_t direction,
unsigned count,
unsigned int count,
const hb_codepoint_t *first_glyph,
unsigned glyph_stride,
hb_position_t *first_advance,

View File

@ -45,26 +45,22 @@
* In general, this file does a fine job of what it's supposed to do.
* There are, however, things that need more work:
*
* - I remember seeing FT_Get_Advance() without the NO_HINTING flag to be buggy.
* Have not investigated.
*
* - FreeType works in 26.6 mode. Clients can decide to use that mode, and everything
* would work fine. However, we also abuse this API for performing in font-space,
* but don't pass the correct flags to FreeType. We just abuse the no-hinting mode
* for that, such that no rounding etc happens. As such, we don't set ppem, and
* pass NO_HINTING as load_flags. Would be much better to use NO_SCALE, and scale
* ourselves, like we do in uniscribe, etc.
* ourselves.
*
* - We don't handle / allow for emboldening / obliqueing.
*
* - In the future, we should add constructors to create fonts in font space?
*
* - FT_Load_Glyph() is extremely costly. Do something about it?
*/
struct hb_ft_font_t
{
mutable hb_mutex_t lock;
FT_Face ft_face;
int load_flags;
bool symbol; /* Whether selected cmap is symbol cmap. */
@ -82,6 +78,7 @@ _hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref)
if (unlikely (!ft_font))
return nullptr;
ft_font->lock.init ();
ft_font->ft_face = ft_face;
ft_font->symbol = symbol;
ft_font->unref = unref;
@ -110,6 +107,8 @@ _hb_ft_font_destroy (void *data)
if (ft_font->unref)
_hb_ft_face_destroy (ft_font->ft_face);
ft_font->lock.fini ();
free (ft_font);
}
@ -177,6 +176,7 @@ hb_ft_get_nominal_glyph (hb_font_t *font HB_UNUSED,
void *user_data HB_UNUSED)
{
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
hb_lock_t lock (ft_font->lock);
unsigned int g = FT_Get_Char_Index (ft_font->ft_face, unicode);
if (unlikely (!g))
@ -200,6 +200,32 @@ hb_ft_get_nominal_glyph (hb_font_t *font HB_UNUSED,
return true;
}
static unsigned int
hb_ft_get_nominal_glyphs (hb_font_t *font HB_UNUSED,
void *font_data,
unsigned int count,
const hb_codepoint_t *first_unicode,
unsigned int unicode_stride,
hb_codepoint_t *first_glyph,
unsigned int glyph_stride,
void *user_data HB_UNUSED)
{
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
hb_lock_t lock (ft_font->lock);
unsigned int done;
for (done = 0;
done < count && (*first_glyph = FT_Get_Char_Index (ft_font->ft_face, *first_unicode));
done++)
{
first_unicode = &StructAtOffset<hb_codepoint_t> (first_unicode, unicode_stride);
first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride);
}
/* We don't need to do ft_font->symbol dance here, since HB calls the singular
* nominal_glyph() for what we don't handle here. */
return done;
}
static hb_bool_t
hb_ft_get_variation_glyph (hb_font_t *font HB_UNUSED,
void *font_data,
@ -209,6 +235,7 @@ hb_ft_get_variation_glyph (hb_font_t *font HB_UNUSED,
void *user_data HB_UNUSED)
{
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
hb_lock_t lock (ft_font->lock);
unsigned int g = FT_Face_GetCharVariantIndex (ft_font->ft_face, unicode, variation_selector);
if (unlikely (!g))
@ -228,6 +255,7 @@ hb_ft_get_glyph_h_advances (hb_font_t* font, void* font_data,
void *user_data HB_UNUSED)
{
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
hb_lock_t lock (ft_font->lock);
FT_Face ft_face = ft_font->ft_face;
int load_flags = ft_font->load_flags;
int mult = font->x_scale < 0 ? -1 : +1;
@ -265,6 +293,7 @@ hb_ft_get_glyph_v_advance (hb_font_t *font,
void *user_data HB_UNUSED)
{
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
hb_lock_t lock (ft_font->lock);
FT_Fixed v;
if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags | FT_LOAD_VERTICAL_LAYOUT, &v)))
@ -287,6 +316,7 @@ hb_ft_get_glyph_v_origin (hb_font_t *font,
void *user_data HB_UNUSED)
{
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
hb_lock_t lock (ft_font->lock);
FT_Face ft_face = ft_font->ft_face;
if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
@ -313,6 +343,7 @@ hb_ft_get_glyph_extents (hb_font_t *font,
void *user_data HB_UNUSED)
{
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
hb_lock_t lock (ft_font->lock);
FT_Face ft_face = ft_font->ft_face;
if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
@ -345,6 +376,7 @@ hb_ft_get_glyph_contour_point (hb_font_t *font HB_UNUSED,
void *user_data HB_UNUSED)
{
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
hb_lock_t lock (ft_font->lock);
FT_Face ft_face = ft_font->ft_face;
if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
@ -370,8 +402,10 @@ hb_ft_get_glyph_name (hb_font_t *font HB_UNUSED,
void *user_data HB_UNUSED)
{
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
hb_lock_t lock (ft_font->lock);
FT_Face ft_face = ft_font->ft_face;
hb_bool_t ret = !FT_Get_Glyph_Name (ft_font->ft_face, glyph, name, size);
hb_bool_t ret = !FT_Get_Glyph_Name (ft_face, glyph, name, size);
if (ret && (size && !*name))
ret = false;
@ -386,6 +420,7 @@ hb_ft_get_glyph_from_name (hb_font_t *font HB_UNUSED,
void *user_data HB_UNUSED)
{
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
hb_lock_t lock (ft_font->lock);
FT_Face ft_face = ft_font->ft_face;
if (len < 0)
@ -418,6 +453,7 @@ hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED,
void *user_data HB_UNUSED)
{
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
hb_lock_t lock (ft_font->lock);
FT_Face ft_face = ft_font->ft_face;
metrics->ascender = ft_face->size->metrics.ascender;
metrics->descender = ft_face->size->metrics.descender;
@ -444,6 +480,7 @@ static struct hb_ft_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ft
hb_font_funcs_set_font_h_extents_func (funcs, hb_ft_get_font_h_extents, nullptr, nullptr);
//hb_font_funcs_set_font_v_extents_func (funcs, hb_ft_get_font_v_extents, nullptr, nullptr);
hb_font_funcs_set_nominal_glyph_func (funcs, hb_ft_get_nominal_glyph, nullptr, nullptr);
hb_font_funcs_set_nominal_glyphs_func (funcs, hb_ft_get_nominal_glyphs, nullptr, nullptr);
hb_font_funcs_set_variation_glyph_func (funcs, hb_ft_get_variation_glyph, 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);

View File

@ -217,6 +217,9 @@ struct hb_dispatch_context_t
#ifndef HB_SANITIZE_MAX_OPS_MIN
#define HB_SANITIZE_MAX_OPS_MIN 16384
#endif
#ifndef HB_SANITIZE_MAX_OPS_MAX
#define HB_SANITIZE_MAX_OPS_MAX 0x3FFFFFFF
#endif
struct hb_sanitize_context_t :
hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE>
@ -252,6 +255,16 @@ struct hb_sanitize_context_t :
}
inline unsigned int get_num_glyphs (void) { return num_glyphs; }
inline void set_max_ops (int max_ops_) { max_ops = max_ops_; }
template <typename T>
inline void set_object (const T& obj)
{
this->start = (const char *) &obj;
this->end = (const char *) &obj + obj.get_size ();
assert (this->start <= this->end); /* Must not overflow. */
}
inline void start_processing (void)
{
this->start = this->blob->data;

View File

@ -137,5 +137,13 @@ struct hb_mutex_t
inline void fini (void) { hb_mutex_impl_finish (&m); }
};
struct hb_lock_t
{
inline hb_lock_t (hb_mutex_t &mutex_) : mutex (mutex_) { mutex.lock (); }
inline ~hb_lock_t (void) { mutex.unlock (); }
private:
hb_mutex_t &mutex;
};
#endif /* HB_MUTEX_HH */

View File

@ -50,7 +50,30 @@ hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED,
void *user_data HB_UNUSED)
{
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);
return ot_face->cmap.get ()->get_nominal_glyph (unicode, glyph);
}
static unsigned int
hb_ot_get_nominal_glyphs (hb_font_t *font HB_UNUSED,
void *font_data,
unsigned int count,
const hb_codepoint_t *first_unicode,
unsigned int unicode_stride,
hb_codepoint_t *first_glyph,
unsigned int glyph_stride,
void *user_data HB_UNUSED)
{
const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
const OT::cmap_accelerator_t &cmap = *ot_face->cmap.get ();
unsigned int done;
for (done = 0;
done < count && cmap.get_nominal_glyph (*first_unicode, first_glyph);
done++)
{
first_unicode = &StructAtOffset<hb_codepoint_t> (first_unicode, unicode_stride);
first_glyph = &StructAtOffset<hb_codepoint_t> (first_glyph, glyph_stride);
}
return done;
}
static hb_bool_t
@ -62,7 +85,7 @@ hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED,
void *user_data HB_UNUSED)
{
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);
return ot_face->cmap.get ()->get_variation_glyph (unicode, variation_selector, glyph);
}
static void
@ -195,6 +218,7 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot
hb_font_funcs_set_font_h_extents_func (funcs, hb_ot_get_font_h_extents, nullptr, nullptr);
hb_font_funcs_set_font_v_extents_func (funcs, hb_ot_get_font_v_extents, nullptr, nullptr);
hb_font_funcs_set_nominal_glyph_func (funcs, hb_ot_get_nominal_glyph, nullptr, nullptr);
hb_font_funcs_set_nominal_glyphs_func (funcs, hb_ot_get_nominal_glyphs, nullptr, nullptr);
hb_font_funcs_set_variation_glyph_func (funcs, hb_ot_get_variation_glyph, 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_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr);
@ -241,9 +265,6 @@ 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_face = hb_ot_face_data (font->face);
/* Load them lazy. We access it with get_relaxed() for performance. */
ot_face->cmap.get ();
hb_font_set_funcs (font,
_hb_ot_get_font_funcs (),
ot_face,

View File

@ -194,11 +194,9 @@ struct KernSubTableFormat2
unsigned int l = (this+leftClassTable).get_class (left);
unsigned int r = (this+rightClassTable).get_class (right);
unsigned int offset = l + r;
const FWORD *arr = &(this+array);
if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end))
return 0;
const FWORD *v = &StructAtOffset<FWORD> (arr, offset);
if (unlikely ((const void *) v < (const void *) arr || (const void *) (v + 1) > (const void *) end))
const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset);
if (unlikely ((const char *) v < (const char *) &array ||
(const char *) v > (const char *) end - 2))
return 0;
return *v;
}
@ -283,7 +281,7 @@ struct KernSubTableWrapper
TRACE_SANITIZE (this);
return_trace (c->check_struct (thiz()) &&
thiz()->length >= T::min_size &&
c->check_array (thiz(), thiz()->length, 1) &&
c->check_range (thiz(), thiz()->length) &&
thiz()->subtable.sanitize (c, thiz()->format));
}
};
@ -294,7 +292,7 @@ struct KernTable
/* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
inline const T* thiz (void) const { return static_cast<const T *> (this); }
inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const
inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
{
int v = 0;
const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ);
@ -303,7 +301,7 @@ struct KernTable
{
if (st->is_override ())
v = 0;
v += st->get_h_kerning (left, right, table_length + (const char *) this);
v += st->get_h_kerning (left, right, st->length + (const char *) st);
st = &StructAfter<typename T::SubTableWrapper> (*st);
}
return v;
@ -337,6 +335,7 @@ struct KernOT : KernTable<KernOT>
struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper>
{
friend struct KernTable<KernOT>;
friend struct KernSubTableWrapper<SubTableWrapper>;
enum Coverage
@ -378,6 +377,7 @@ struct KernAAT : KernTable<KernAAT>
struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper>
{
friend struct KernTable<KernAAT>;
friend struct KernSubTableWrapper<SubTableWrapper>;
enum Coverage
@ -418,11 +418,11 @@ struct kern
inline bool has_data (void) const
{ return u.version32 != 0; }
inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right, unsigned int table_length) const
inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
{
switch (u.major) {
case 0: return u.ot.get_h_kerning (left, right, table_length);
case 1: return u.aat.get_h_kerning (left, right, table_length);
case 0: return u.ot.get_h_kerning (left, right);
case 1: return u.aat.get_h_kerning (left, right);
default:return 0;
}
}
@ -430,7 +430,7 @@ struct kern
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (!u.major.sanitize (c)) return_trace (false);
if (!u.version32.sanitize (c)) return_trace (false);
switch (u.major) {
case 0: return_trace (u.ot.sanitize (c));
case 1: return_trace (u.aat.sanitize (c));
@ -444,7 +444,6 @@ struct kern
{
blob = hb_sanitize_context_t().reference_table<kern> (face);
table = blob->as<kern> ();
table_length = blob->length;
}
inline void fini (void)
{
@ -455,7 +454,7 @@ struct kern
{ return table->has_data (); }
inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
{ return table->get_h_kerning (left, right, table_length); }
{ return table->get_h_kerning (left, right); }
inline int get_kerning (hb_codepoint_t first, hb_codepoint_t second) const
{ return get_h_kerning (first, second); }
@ -464,6 +463,7 @@ struct kern
hb_buffer_t *buffer,
hb_mask_t kern_mask) const
{
/* We only apply horizontal kerning in this table. */
if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
return;
@ -475,18 +475,17 @@ struct kern
private:
hb_blob_t *blob;
const kern *table;
unsigned int table_length;
};
protected:
union {
HBUINT16 major;
HBUINT32 version32;
HBUINT16 major;
KernOT ot;
KernAAT aat;
} u;
public:
DEFINE_SIZE_UNION (2, major);
DEFINE_SIZE_UNION (4, version32);
};
struct kern_accelerator_t : kern::accelerator_t {};

View File

@ -599,7 +599,7 @@ postprocess_glyphs_arabic (const hb_ot_shape_plan_t *plan,
HB_BUFFER_DEALLOCATE_VAR (buffer, arabic_shaping_action);
}
/* https://unicode.org/reports/tr53/tr53-1.pdf */
/* http://www.unicode.org/reports/tr53/ */
static hb_codepoint_t
modifier_combining_marks[] =

View File

@ -264,15 +264,6 @@ decompose_multi_char_cluster (const hb_ot_shape_normalize_context_t *c, unsigned
decompose_current_character (c, short_circuit);
}
static inline void
decompose_cluster (const hb_ot_shape_normalize_context_t *c, unsigned int end, bool might_short_circuit, bool always_short_circuit)
{
if (likely (c->buffer->idx + 1 == end))
decompose_current_character (c, might_short_circuit);
else
decompose_multi_char_cluster (c, end, always_short_circuit);
}
static int
compare_combining_class (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
@ -328,45 +319,80 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
/* First round, decompose */
buffer->clear_output ();
count = buffer->len;
for (buffer->idx = 0; buffer->idx < count && buffer->successful;)
bool all_simple = true;
{
unsigned int end;
for (end = buffer->idx + 1; end < count; end++)
if (likely (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[end]))))
break;
buffer->clear_output ();
count = buffer->len;
buffer->idx = 0;
do
{
unsigned int end;
for (end = buffer->idx + 1; end < count; end++)
if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[end]))))
break;
decompose_cluster (&c, end, might_short_circuit, always_short_circuit);
if (end < count)
end--; /* Leave one base for the marks to cluster with. */
/* From idx to end are simple clusters. */
if (might_short_circuit)
{
unsigned int done = font->get_nominal_glyphs (end - buffer->idx,
&buffer->cur().codepoint,
sizeof (buffer->info[0]),
&buffer->cur().glyph_index(),
sizeof (buffer->info[0]));
buffer->next_glyphs (done);
}
while (buffer->idx < end && buffer->successful)
decompose_current_character (&c, might_short_circuit);
if (buffer->idx == count || !buffer->successful)
break;
all_simple = false;
/* Find all the marks now. */
for (end = buffer->idx + 1; end < count; end++)
if (!HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[end])))
break;
/* idx to end is one non-simple cluster. */
decompose_multi_char_cluster (&c, end, always_short_circuit);
}
while (buffer->idx < count && buffer->successful);
buffer->swap_buffers ();
}
buffer->swap_buffers ();
/* Second round, reorder (inplace) */
count = buffer->len;
for (unsigned int i = 0; i < count; i++)
if (!all_simple)
{
if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]) == 0)
continue;
count = buffer->len;
for (unsigned int i = 0; i < count; i++)
{
if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]) == 0)
continue;
unsigned int end;
for (end = i + 1; end < count; end++)
if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0)
break;
unsigned int end;
for (end = i + 1; end < count; end++)
if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0)
break;
/* We are going to do a O(n^2). Only do this if the sequence is short. */
if (end - i > HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS) {
i = end;
continue;
}
buffer->sort (i, end, compare_combining_class);
if (plan->shaper->reorder_marks)
plan->shaper->reorder_marks (plan, buffer, i, end);
/* We are going to do a O(n^2). Only do this if the sequence is short. */
if (end - i > HB_OT_SHAPE_COMPLEX_MAX_COMBINING_MARKS) {
i = end;
continue;
}
buffer->sort (i, end, compare_combining_class);
if (plan->shaper->reorder_marks)
plan->shaper->reorder_marks (plan, buffer, i, end);
i = end;
}
if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_CGJ)
{
@ -385,8 +411,9 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
/* Third round, recompose */
if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS ||
mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT)
if (!all_simple &&
(mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS ||
mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT))
{
/* As noted in the comment earlier, we don't try to combine
* ccc=0 chars with their previous Starter. */

View File

@ -668,7 +668,7 @@ hb_ot_substitute_complex (const hb_ot_shape_context_t *c)
hb_synthesize_glyph_classes (c);
if (unlikely (c->plan->apply_morx))
hb_aat_layout_substitute (c->font, c->buffer);
hb_aat_layout_substitute (c->plan, c->font, c->buffer);
else
c->plan->substitute (c->font, buffer);
}

View File

@ -34,8 +34,8 @@
#include <hb-ot.h>
#include <glib.h>
static char *font_path = "fonts/Inconsolata-Regular.abc.ttf";
static char *text = "abc";
static const char *font_path = "fonts/Inconsolata-Regular.abc.ttf";
static const char *text = "abc";
static int num_threads = 30;
static int num_iters = 200;
@ -164,11 +164,8 @@ main (int argc, char **argv)
test_body ();
/* hb-font backed by FreeType functions can only be used from
* one thread at a time, because that's FT_Face's MT guarantee.
* So, disable this, even though it works "most of the time". */
//hb_ft_font_set_funcs (font);
//test_body ();
hb_ft_font_set_funcs (font);
test_body ();
hb_buffer_destroy (ref_buffer);