Merge branch 'master' into cff-subset
This commit is contained in:
commit
c06a5dff0b
|
@ -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
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
51
src/hb-ft.cc
51
src/hb-ft.cc
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {};
|
||||
|
|
|
@ -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[] =
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue