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_advances_func
|
||||||
hb_font_funcs_set_glyph_v_origin_func
|
hb_font_funcs_set_glyph_v_origin_func
|
||||||
hb_font_funcs_set_nominal_glyph_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_user_data
|
||||||
hb_font_funcs_set_variation_glyph_func
|
hb_font_funcs_set_variation_glyph_func
|
||||||
hb_font_funcs_t
|
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_glyph_v_origin_func_t
|
||||||
hb_font_get_nominal_glyph
|
hb_font_get_nominal_glyph
|
||||||
hb_font_get_nominal_glyph_func_t
|
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_parent
|
||||||
hb_font_get_ppem
|
hb_font_get_ppem
|
||||||
hb_font_get_ptem
|
hb_font_get_ptem
|
||||||
|
|
|
@ -518,6 +518,7 @@ struct hb_aat_apply_context_t :
|
||||||
static return_t default_return_value (void) { return false; }
|
static return_t default_return_value (void) { return false; }
|
||||||
bool stop_sublookup_iteration (return_t r) const { return r; }
|
bool stop_sublookup_iteration (return_t r) const { return r; }
|
||||||
|
|
||||||
|
hb_ot_shape_plan_t *plan;
|
||||||
hb_font_t *font;
|
hb_font_t *font;
|
||||||
hb_face_t *face;
|
hb_face_t *face;
|
||||||
hb_buffer_t *buffer;
|
hb_buffer_t *buffer;
|
||||||
|
@ -527,15 +528,17 @@ struct hb_aat_apply_context_t :
|
||||||
unsigned int lookup_index;
|
unsigned int lookup_index;
|
||||||
unsigned int debug_depth;
|
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_buffer_t *buffer_,
|
||||||
hb_blob_t *table) :
|
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 (), lookup_index (0), debug_depth (0)
|
||||||
{
|
{
|
||||||
sanitizer.init (table);
|
sanitizer.init (table);
|
||||||
sanitizer.set_num_glyphs (face->get_num_glyphs ());
|
sanitizer.set_num_glyphs (face->get_num_glyphs ());
|
||||||
sanitizer.start_processing ();
|
sanitizer.start_processing ();
|
||||||
|
sanitizer.set_max_ops (HB_SANITIZE_MAX_OPS_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void set_lookup_index (unsigned int i) { lookup_index = i; }
|
inline void set_lookup_index (unsigned int i) { lookup_index = i; }
|
||||||
|
|
|
@ -59,7 +59,9 @@ struct KerxSubTableFormat0
|
||||||
{
|
{
|
||||||
TRACE_APPLY (this);
|
TRACE_APPLY (this);
|
||||||
|
|
||||||
/* TODO */
|
hb_kern_machine_t<KerxSubTableFormat0> machine (*this);
|
||||||
|
|
||||||
|
machine.kern (c->font, c->buffer, c->plan->kern_mask);
|
||||||
|
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
@ -110,11 +112,9 @@ struct KerxSubTableFormat2
|
||||||
unsigned int l = *(this+leftClassTable).get_value (left, num_glyphs);
|
unsigned int l = *(this+leftClassTable).get_value (left, num_glyphs);
|
||||||
unsigned int r = *(this+rightClassTable).get_value (right, num_glyphs);
|
unsigned int r = *(this+rightClassTable).get_value (right, num_glyphs);
|
||||||
unsigned int offset = l + r;
|
unsigned int offset = l + r;
|
||||||
const FWORD *arr = &(this+array);
|
const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset);
|
||||||
if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end))
|
if (unlikely ((const char *) v < (const char *) &array ||
|
||||||
return 0;
|
(const char *) v > (const char *) end - 2))
|
||||||
const FWORD *v = &StructAtOffset<FWORD> (arr, offset);
|
|
||||||
if (unlikely ((const void *) v < (const void *) arr || (const void *) (v + 1) > (const void *) end))
|
|
||||||
return 0;
|
return 0;
|
||||||
return *v;
|
return *v;
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,11 @@ struct KerxSubTableFormat2
|
||||||
{
|
{
|
||||||
TRACE_APPLY (this);
|
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);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
@ -138,6 +142,22 @@ struct KerxSubTableFormat2
|
||||||
array.sanitize (c, this)));
|
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:
|
protected:
|
||||||
HBUINT32 rowWidth; /* The width, in bytes, of a row in the table. */
|
HBUINT32 rowWidth; /* The width, in bytes, of a row in the table. */
|
||||||
LOffsetTo<Lookup<HBUINT16> >
|
LOffsetTo<Lookup<HBUINT16> >
|
||||||
|
@ -222,7 +242,7 @@ struct KerxTable
|
||||||
Vertical = 0x80000000, /* Set if table has vertical kerning values. */
|
Vertical = 0x80000000, /* Set if table has vertical kerning values. */
|
||||||
CrossStream = 0x40000000, /* Set if table has cross-stream kerning values. */
|
CrossStream = 0x40000000, /* Set if table has cross-stream kerning values. */
|
||||||
Variation = 0x20000000, /* Set if table has variation 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.
|
* is, from first to last in the glyph stream.
|
||||||
* If we, process them from last to first.
|
* If we, process them from last to first.
|
||||||
* This flag only applies to state-table based
|
* This flag only applies to state-table based
|
||||||
|
@ -272,22 +292,6 @@ public:
|
||||||
DEFINE_SIZE_MIN (12);
|
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
|
* The 'kerx' Table
|
||||||
|
@ -313,9 +317,9 @@ struct kerx
|
||||||
goto skip;
|
goto skip;
|
||||||
|
|
||||||
if (table->coverage & KerxTable::CrossStream)
|
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);
|
HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
|
||||||
|
|
||||||
if (!c->buffer->message (c->font, "start kerx subtable %d", c->lookup_index))
|
if (!c->buffer->message (c->font, "start kerx subtable %d", c->lookup_index))
|
||||||
|
@ -324,7 +328,12 @@ struct kerx
|
||||||
if (reverse)
|
if (reverse)
|
||||||
c->buffer->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);
|
table->dispatch (c);
|
||||||
|
|
||||||
if (reverse)
|
if (reverse)
|
||||||
|
|
|
@ -752,7 +752,7 @@ struct ChainSubtable
|
||||||
Vertical = 0x80000000, /* If set, this subtable will only be applied
|
Vertical = 0x80000000, /* If set, this subtable will only be applied
|
||||||
* to vertical text. If clear, this subtable
|
* to vertical text. If clear, this subtable
|
||||||
* will only be applied to horizontal text. */
|
* 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
|
* in descending order. If clear, it will
|
||||||
* process the glyphs in ascending order. */
|
* process the glyphs in ascending order. */
|
||||||
AllDirections = 0x20000000, /* If set, this subtable will be applied to
|
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).
|
may be right-to-left or left-to-right).
|
||||||
*/
|
*/
|
||||||
reverse = subtable->coverage & ChainSubtable::Logical ?
|
reverse = subtable->coverage & ChainSubtable::Logical ?
|
||||||
bool (subtable->coverage & ChainSubtable::Descending) :
|
bool (subtable->coverage & ChainSubtable::Backwards) :
|
||||||
bool (subtable->coverage & ChainSubtable::Descending) !=
|
bool (subtable->coverage & ChainSubtable::Backwards) !=
|
||||||
HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
|
HB_DIRECTION_IS_BACKWARD (c->buffer->props.direction);
|
||||||
|
|
||||||
if (!c->buffer->message (c->font, "start chain subtable %d", c->lookup_index))
|
if (!c->buffer->message (c->font, "start chain subtable %d", c->lookup_index))
|
||||||
|
@ -886,6 +886,8 @@ struct Chain
|
||||||
if (reverse)
|
if (reverse)
|
||||||
c->buffer->reverse ();
|
c->buffer->reverse ();
|
||||||
|
|
||||||
|
c->sanitizer.set_object (*subtable);
|
||||||
|
|
||||||
subtable->dispatch (c);
|
subtable->dispatch (c);
|
||||||
|
|
||||||
if (reverse)
|
if (reverse)
|
||||||
|
|
|
@ -62,17 +62,21 @@ hb_aat_layout_has_substitution (hb_face_t *face)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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;
|
hb_blob_t *blob;
|
||||||
const AAT::morx& morx = _get_morx (font->face, &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);
|
morx.apply (&c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
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
|
#if 0
|
||||||
hb_blob_t *blob;
|
hb_blob_t *blob;
|
||||||
|
|
|
@ -29,17 +29,19 @@
|
||||||
|
|
||||||
#include "hb.hh"
|
#include "hb.hh"
|
||||||
|
|
||||||
#include "hb-font.hh"
|
#include "hb-ot-shape.hh"
|
||||||
#include "hb-buffer.hh"
|
|
||||||
#include "hb-open-type.hh"
|
|
||||||
|
|
||||||
HB_INTERNAL hb_bool_t
|
HB_INTERNAL hb_bool_t
|
||||||
hb_aat_layout_has_substitution (hb_face_t *face);
|
hb_aat_layout_has_substitution (hb_face_t *face);
|
||||||
|
|
||||||
HB_INTERNAL void
|
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_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 */
|
#endif /* HB_AAT_LAYOUT_HH */
|
||||||
|
|
|
@ -260,7 +260,8 @@ struct hb_buffer_t
|
||||||
{
|
{
|
||||||
if (have_output)
|
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;
|
if (unlikely (!make_room_for (1, 1))) return;
|
||||||
out_info[out_len] = info[idx];
|
out_info[out_len] = info[idx];
|
||||||
}
|
}
|
||||||
|
@ -269,6 +270,23 @@ struct hb_buffer_t
|
||||||
|
|
||||||
idx++;
|
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. */
|
/* Advance idx without copying to output. */
|
||||||
inline void skip_glyph (void)
|
inline void skip_glyph (void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -31,6 +31,8 @@
|
||||||
#include "hb-font.hh"
|
#include "hb-font.hh"
|
||||||
#include "hb-machinery.hh"
|
#include "hb-machinery.hh"
|
||||||
|
|
||||||
|
#include "hb-ot.h"
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* hb_font_funcs_t
|
* hb_font_funcs_t
|
||||||
|
@ -101,9 +103,42 @@ hb_font_get_nominal_glyph_default (hb_font_t *font,
|
||||||
hb_codepoint_t *glyph,
|
hb_codepoint_t *glyph,
|
||||||
void *user_data HB_UNUSED)
|
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);
|
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
|
static hb_bool_t
|
||||||
hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED,
|
hb_font_get_variation_glyph_nil (hb_font_t *font HB_UNUSED,
|
||||||
void *font_data HB_UNUSED,
|
void *font_data HB_UNUSED,
|
||||||
|
@ -807,7 +842,7 @@ hb_font_get_glyph_v_advance (hb_font_t *font,
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
hb_font_get_glyph_h_advances (hb_font_t* font,
|
hb_font_get_glyph_h_advances (hb_font_t* font,
|
||||||
unsigned count,
|
unsigned int count,
|
||||||
const hb_codepoint_t *first_glyph,
|
const hb_codepoint_t *first_glyph,
|
||||||
unsigned glyph_stride,
|
unsigned glyph_stride,
|
||||||
hb_position_t *first_advance,
|
hb_position_t *first_advance,
|
||||||
|
@ -825,7 +860,7 @@ hb_font_get_glyph_h_advances (hb_font_t* font,
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
hb_font_get_glyph_v_advances (hb_font_t* font,
|
hb_font_get_glyph_v_advances (hb_font_t* font,
|
||||||
unsigned count,
|
unsigned int count,
|
||||||
const hb_codepoint_t *first_glyph,
|
const hb_codepoint_t *first_glyph,
|
||||||
unsigned glyph_stride,
|
unsigned glyph_stride,
|
||||||
hb_position_t *first_advance,
|
hb_position_t *first_advance,
|
||||||
|
@ -1052,7 +1087,7 @@ hb_font_get_glyph_advance_for_direction (hb_font_t *font,
|
||||||
HB_EXTERN void
|
HB_EXTERN void
|
||||||
hb_font_get_glyph_advances_for_direction (hb_font_t* font,
|
hb_font_get_glyph_advances_for_direction (hb_font_t* font,
|
||||||
hb_direction_t direction,
|
hb_direction_t direction,
|
||||||
unsigned count,
|
unsigned int count,
|
||||||
const hb_codepoint_t *first_glyph,
|
const hb_codepoint_t *first_glyph,
|
||||||
unsigned glyph_stride,
|
unsigned glyph_stride,
|
||||||
hb_position_t *first_advance,
|
hb_position_t *first_advance,
|
||||||
|
@ -1271,18 +1306,8 @@ DEFINE_NULL_INSTANCE (hb_font_t) =
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
static hb_font_t *
|
||||||
* hb_font_create: (Xconstructor)
|
_hb_font_create (hb_face_t *face)
|
||||||
* @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_t *font;
|
||||||
|
|
||||||
|
@ -1301,6 +1326,27 @@ hb_font_create (hb_face_t *face)
|
||||||
return font;
|
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:
|
* hb_font_create_sub_font:
|
||||||
* @parent: parent font.
|
* @parent: parent font.
|
||||||
|
@ -1317,7 +1363,7 @@ hb_font_create_sub_font (hb_font_t *parent)
|
||||||
if (unlikely (!parent))
|
if (unlikely (!parent))
|
||||||
parent = hb_font_get_empty ();
|
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)))
|
if (unlikely (hb_object_is_inert (font)))
|
||||||
return 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,
|
hb_codepoint_t *glyph,
|
||||||
void *user_data);
|
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,
|
typedef hb_position_t (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, void *font_data,
|
||||||
hb_codepoint_t glyph,
|
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 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,
|
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,
|
const hb_codepoint_t *first_glyph,
|
||||||
unsigned glyph_stride,
|
unsigned glyph_stride,
|
||||||
hb_position_t *first_advance,
|
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,
|
hb_font_get_nominal_glyph_func_t func,
|
||||||
void *user_data, hb_destroy_func_t destroy);
|
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:
|
* hb_font_funcs_set_variation_glyph_func:
|
||||||
* @ffuncs: font functions.
|
* @ffuncs: font functions.
|
||||||
|
@ -423,14 +447,14 @@ hb_font_get_glyph_v_advance (hb_font_t *font,
|
||||||
|
|
||||||
HB_EXTERN void
|
HB_EXTERN void
|
||||||
hb_font_get_glyph_h_advances (hb_font_t* font,
|
hb_font_get_glyph_h_advances (hb_font_t* font,
|
||||||
unsigned count,
|
unsigned int count,
|
||||||
const hb_codepoint_t *first_glyph,
|
const hb_codepoint_t *first_glyph,
|
||||||
unsigned glyph_stride,
|
unsigned glyph_stride,
|
||||||
hb_position_t *first_advance,
|
hb_position_t *first_advance,
|
||||||
unsigned advance_stride);
|
unsigned advance_stride);
|
||||||
HB_EXTERN void
|
HB_EXTERN void
|
||||||
hb_font_get_glyph_v_advances (hb_font_t* font,
|
hb_font_get_glyph_v_advances (hb_font_t* font,
|
||||||
unsigned count,
|
unsigned int count,
|
||||||
const hb_codepoint_t *first_glyph,
|
const hb_codepoint_t *first_glyph,
|
||||||
unsigned glyph_stride,
|
unsigned glyph_stride,
|
||||||
hb_position_t *first_advance,
|
hb_position_t *first_advance,
|
||||||
|
@ -486,7 +510,7 @@ hb_font_get_glyph_advance_for_direction (hb_font_t *font,
|
||||||
HB_EXTERN void
|
HB_EXTERN void
|
||||||
hb_font_get_glyph_advances_for_direction (hb_font_t* font,
|
hb_font_get_glyph_advances_for_direction (hb_font_t* font,
|
||||||
hb_direction_t direction,
|
hb_direction_t direction,
|
||||||
unsigned count,
|
unsigned int count,
|
||||||
const hb_codepoint_t *first_glyph,
|
const hb_codepoint_t *first_glyph,
|
||||||
unsigned glyph_stride,
|
unsigned glyph_stride,
|
||||||
hb_position_t *first_advance,
|
hb_position_t *first_advance,
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
HB_FONT_FUNC_IMPLEMENT (font_h_extents) \
|
HB_FONT_FUNC_IMPLEMENT (font_h_extents) \
|
||||||
HB_FONT_FUNC_IMPLEMENT (font_v_extents) \
|
HB_FONT_FUNC_IMPLEMENT (font_v_extents) \
|
||||||
HB_FONT_FUNC_IMPLEMENT (nominal_glyph) \
|
HB_FONT_FUNC_IMPLEMENT (nominal_glyph) \
|
||||||
|
HB_FONT_FUNC_IMPLEMENT (nominal_glyphs) \
|
||||||
HB_FONT_FUNC_IMPLEMENT (variation_glyph) \
|
HB_FONT_FUNC_IMPLEMENT (variation_glyph) \
|
||||||
HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \
|
HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \
|
||||||
HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \
|
HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \
|
||||||
|
@ -212,6 +213,18 @@ struct hb_font_t
|
||||||
unicode, glyph,
|
unicode, glyph,
|
||||||
klass->user_data.nominal_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,
|
inline hb_bool_t get_variation_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector,
|
||||||
hb_codepoint_t *glyph)
|
hb_codepoint_t *glyph)
|
||||||
|
@ -377,7 +390,7 @@ struct hb_font_t
|
||||||
*y = get_glyph_v_advance (glyph);
|
*y = get_glyph_v_advance (glyph);
|
||||||
}
|
}
|
||||||
inline void get_glyph_advances_for_direction (hb_direction_t direction,
|
inline void get_glyph_advances_for_direction (hb_direction_t direction,
|
||||||
unsigned count,
|
unsigned int count,
|
||||||
const hb_codepoint_t *first_glyph,
|
const hb_codepoint_t *first_glyph,
|
||||||
unsigned glyph_stride,
|
unsigned glyph_stride,
|
||||||
hb_position_t *first_advance,
|
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.
|
* In general, this file does a fine job of what it's supposed to do.
|
||||||
* There are, however, things that need more work:
|
* 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
|
* - 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,
|
* 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
|
* 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
|
* 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
|
* 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.
|
* - We don't handle / allow for emboldening / obliqueing.
|
||||||
*
|
*
|
||||||
* - In the future, we should add constructors to create fonts in font space?
|
* - 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
|
struct hb_ft_font_t
|
||||||
{
|
{
|
||||||
|
mutable hb_mutex_t lock;
|
||||||
FT_Face ft_face;
|
FT_Face ft_face;
|
||||||
int load_flags;
|
int load_flags;
|
||||||
bool symbol; /* Whether selected cmap is symbol cmap. */
|
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))
|
if (unlikely (!ft_font))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
ft_font->lock.init ();
|
||||||
ft_font->ft_face = ft_face;
|
ft_font->ft_face = ft_face;
|
||||||
ft_font->symbol = symbol;
|
ft_font->symbol = symbol;
|
||||||
ft_font->unref = unref;
|
ft_font->unref = unref;
|
||||||
|
@ -110,6 +107,8 @@ _hb_ft_font_destroy (void *data)
|
||||||
if (ft_font->unref)
|
if (ft_font->unref)
|
||||||
_hb_ft_face_destroy (ft_font->ft_face);
|
_hb_ft_face_destroy (ft_font->ft_face);
|
||||||
|
|
||||||
|
ft_font->lock.fini ();
|
||||||
|
|
||||||
free (ft_font);
|
free (ft_font);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,6 +176,7 @@ hb_ft_get_nominal_glyph (hb_font_t *font HB_UNUSED,
|
||||||
void *user_data HB_UNUSED)
|
void *user_data HB_UNUSED)
|
||||||
{
|
{
|
||||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
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);
|
unsigned int g = FT_Get_Char_Index (ft_font->ft_face, unicode);
|
||||||
|
|
||||||
if (unlikely (!g))
|
if (unlikely (!g))
|
||||||
|
@ -200,6 +200,32 @@ hb_ft_get_nominal_glyph (hb_font_t *font HB_UNUSED,
|
||||||
return true;
|
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
|
static hb_bool_t
|
||||||
hb_ft_get_variation_glyph (hb_font_t *font HB_UNUSED,
|
hb_ft_get_variation_glyph (hb_font_t *font HB_UNUSED,
|
||||||
void *font_data,
|
void *font_data,
|
||||||
|
@ -209,6 +235,7 @@ hb_ft_get_variation_glyph (hb_font_t *font HB_UNUSED,
|
||||||
void *user_data HB_UNUSED)
|
void *user_data HB_UNUSED)
|
||||||
{
|
{
|
||||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
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);
|
unsigned int g = FT_Face_GetCharVariantIndex (ft_font->ft_face, unicode, variation_selector);
|
||||||
|
|
||||||
if (unlikely (!g))
|
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)
|
void *user_data HB_UNUSED)
|
||||||
{
|
{
|
||||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
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;
|
FT_Face ft_face = ft_font->ft_face;
|
||||||
int load_flags = ft_font->load_flags;
|
int load_flags = ft_font->load_flags;
|
||||||
int mult = font->x_scale < 0 ? -1 : +1;
|
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)
|
void *user_data HB_UNUSED)
|
||||||
{
|
{
|
||||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
||||||
|
hb_lock_t lock (ft_font->lock);
|
||||||
FT_Fixed v;
|
FT_Fixed v;
|
||||||
|
|
||||||
if (unlikely (FT_Get_Advance (ft_font->ft_face, glyph, ft_font->load_flags | FT_LOAD_VERTICAL_LAYOUT, &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)
|
void *user_data HB_UNUSED)
|
||||||
{
|
{
|
||||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
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;
|
FT_Face ft_face = ft_font->ft_face;
|
||||||
|
|
||||||
if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
|
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)
|
void *user_data HB_UNUSED)
|
||||||
{
|
{
|
||||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
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;
|
FT_Face ft_face = ft_font->ft_face;
|
||||||
|
|
||||||
if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
|
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)
|
void *user_data HB_UNUSED)
|
||||||
{
|
{
|
||||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
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;
|
FT_Face ft_face = ft_font->ft_face;
|
||||||
|
|
||||||
if (unlikely (FT_Load_Glyph (ft_face, glyph, ft_font->load_flags)))
|
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)
|
void *user_data HB_UNUSED)
|
||||||
{
|
{
|
||||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
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))
|
if (ret && (size && !*name))
|
||||||
ret = false;
|
ret = false;
|
||||||
|
|
||||||
|
@ -386,6 +420,7 @@ hb_ft_get_glyph_from_name (hb_font_t *font HB_UNUSED,
|
||||||
void *user_data HB_UNUSED)
|
void *user_data HB_UNUSED)
|
||||||
{
|
{
|
||||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
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;
|
FT_Face ft_face = ft_font->ft_face;
|
||||||
|
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
|
@ -418,6 +453,7 @@ hb_ft_get_font_h_extents (hb_font_t *font HB_UNUSED,
|
||||||
void *user_data HB_UNUSED)
|
void *user_data HB_UNUSED)
|
||||||
{
|
{
|
||||||
const hb_ft_font_t *ft_font = (const hb_ft_font_t *) font_data;
|
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;
|
FT_Face ft_face = ft_font->ft_face;
|
||||||
metrics->ascender = ft_face->size->metrics.ascender;
|
metrics->ascender = ft_face->size->metrics.ascender;
|
||||||
metrics->descender = ft_face->size->metrics.descender;
|
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_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_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_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_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_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_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
|
#ifndef HB_SANITIZE_MAX_OPS_MIN
|
||||||
#define HB_SANITIZE_MAX_OPS_MIN 16384
|
#define HB_SANITIZE_MAX_OPS_MIN 16384
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef HB_SANITIZE_MAX_OPS_MAX
|
||||||
|
#define HB_SANITIZE_MAX_OPS_MAX 0x3FFFFFFF
|
||||||
|
#endif
|
||||||
|
|
||||||
struct hb_sanitize_context_t :
|
struct hb_sanitize_context_t :
|
||||||
hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE>
|
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 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)
|
inline void start_processing (void)
|
||||||
{
|
{
|
||||||
this->start = this->blob->data;
|
this->start = this->blob->data;
|
||||||
|
|
|
@ -137,5 +137,13 @@ struct hb_mutex_t
|
||||||
inline void fini (void) { hb_mutex_impl_finish (&m); }
|
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 */
|
#endif /* HB_MUTEX_HH */
|
||||||
|
|
|
@ -50,7 +50,30 @@ hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED,
|
||||||
void *user_data HB_UNUSED)
|
void *user_data HB_UNUSED)
|
||||||
{
|
{
|
||||||
const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
|
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
|
static hb_bool_t
|
||||||
|
@ -62,7 +85,7 @@ hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED,
|
||||||
void *user_data HB_UNUSED)
|
void *user_data HB_UNUSED)
|
||||||
{
|
{
|
||||||
const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
|
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
|
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_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_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_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_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_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);
|
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;
|
if (unlikely (!hb_ot_shaper_face_data_ensure (font->face))) return;
|
||||||
hb_ot_face_data_t *ot_face = hb_ot_face_data (font->face);
|
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_font_set_funcs (font,
|
||||||
_hb_ot_get_font_funcs (),
|
_hb_ot_get_font_funcs (),
|
||||||
ot_face,
|
ot_face,
|
||||||
|
|
|
@ -194,11 +194,9 @@ struct KernSubTableFormat2
|
||||||
unsigned int l = (this+leftClassTable).get_class (left);
|
unsigned int l = (this+leftClassTable).get_class (left);
|
||||||
unsigned int r = (this+rightClassTable).get_class (right);
|
unsigned int r = (this+rightClassTable).get_class (right);
|
||||||
unsigned int offset = l + r;
|
unsigned int offset = l + r;
|
||||||
const FWORD *arr = &(this+array);
|
const FWORD *v = &StructAtOffset<FWORD> (&(this+array), offset);
|
||||||
if (unlikely ((const void *) arr < (const void *) this || (const void *) arr >= (const void *) end))
|
if (unlikely ((const char *) v < (const char *) &array ||
|
||||||
return 0;
|
(const char *) v > (const char *) end - 2))
|
||||||
const FWORD *v = &StructAtOffset<FWORD> (arr, offset);
|
|
||||||
if (unlikely ((const void *) v < (const void *) arr || (const void *) (v + 1) > (const void *) end))
|
|
||||||
return 0;
|
return 0;
|
||||||
return *v;
|
return *v;
|
||||||
}
|
}
|
||||||
|
@ -283,7 +281,7 @@ struct KernSubTableWrapper
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return_trace (c->check_struct (thiz()) &&
|
return_trace (c->check_struct (thiz()) &&
|
||||||
thiz()->length >= T::min_size &&
|
thiz()->length >= T::min_size &&
|
||||||
c->check_array (thiz(), thiz()->length, 1) &&
|
c->check_range (thiz(), thiz()->length) &&
|
||||||
thiz()->subtable.sanitize (c, thiz()->format));
|
thiz()->subtable.sanitize (c, thiz()->format));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -294,7 +292,7 @@ struct KernTable
|
||||||
/* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
|
/* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */
|
||||||
inline const T* thiz (void) const { return static_cast<const T *> (this); }
|
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;
|
int v = 0;
|
||||||
const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ);
|
const typename T::SubTableWrapper *st = CastP<typename T::SubTableWrapper> (&thiz()->dataZ);
|
||||||
|
@ -303,7 +301,7 @@ struct KernTable
|
||||||
{
|
{
|
||||||
if (st->is_override ())
|
if (st->is_override ())
|
||||||
v = 0;
|
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);
|
st = &StructAfter<typename T::SubTableWrapper> (*st);
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
|
@ -337,6 +335,7 @@ struct KernOT : KernTable<KernOT>
|
||||||
|
|
||||||
struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper>
|
struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper>
|
||||||
{
|
{
|
||||||
|
friend struct KernTable<KernOT>;
|
||||||
friend struct KernSubTableWrapper<SubTableWrapper>;
|
friend struct KernSubTableWrapper<SubTableWrapper>;
|
||||||
|
|
||||||
enum Coverage
|
enum Coverage
|
||||||
|
@ -378,6 +377,7 @@ struct KernAAT : KernTable<KernAAT>
|
||||||
|
|
||||||
struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper>
|
struct SubTableWrapper : KernSubTableWrapper<SubTableWrapper>
|
||||||
{
|
{
|
||||||
|
friend struct KernTable<KernAAT>;
|
||||||
friend struct KernSubTableWrapper<SubTableWrapper>;
|
friend struct KernSubTableWrapper<SubTableWrapper>;
|
||||||
|
|
||||||
enum Coverage
|
enum Coverage
|
||||||
|
@ -418,11 +418,11 @@ struct kern
|
||||||
inline bool has_data (void) const
|
inline bool has_data (void) const
|
||||||
{ return u.version32 != 0; }
|
{ 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) {
|
switch (u.major) {
|
||||||
case 0: return u.ot.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, table_length);
|
case 1: return u.aat.get_h_kerning (left, right);
|
||||||
default:return 0;
|
default:return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -430,7 +430,7 @@ struct kern
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
if (!u.major.sanitize (c)) return_trace (false);
|
if (!u.version32.sanitize (c)) return_trace (false);
|
||||||
switch (u.major) {
|
switch (u.major) {
|
||||||
case 0: return_trace (u.ot.sanitize (c));
|
case 0: return_trace (u.ot.sanitize (c));
|
||||||
case 1: return_trace (u.aat.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);
|
blob = hb_sanitize_context_t().reference_table<kern> (face);
|
||||||
table = blob->as<kern> ();
|
table = blob->as<kern> ();
|
||||||
table_length = blob->length;
|
|
||||||
}
|
}
|
||||||
inline void fini (void)
|
inline void fini (void)
|
||||||
{
|
{
|
||||||
|
@ -455,7 +454,7 @@ struct kern
|
||||||
{ return table->has_data (); }
|
{ return table->has_data (); }
|
||||||
|
|
||||||
inline int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
|
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
|
inline int get_kerning (hb_codepoint_t first, hb_codepoint_t second) const
|
||||||
{ return get_h_kerning (first, second); }
|
{ return get_h_kerning (first, second); }
|
||||||
|
@ -464,6 +463,7 @@ struct kern
|
||||||
hb_buffer_t *buffer,
|
hb_buffer_t *buffer,
|
||||||
hb_mask_t kern_mask) const
|
hb_mask_t kern_mask) const
|
||||||
{
|
{
|
||||||
|
/* We only apply horizontal kerning in this table. */
|
||||||
if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
|
if (!HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -475,18 +475,17 @@ struct kern
|
||||||
private:
|
private:
|
||||||
hb_blob_t *blob;
|
hb_blob_t *blob;
|
||||||
const kern *table;
|
const kern *table;
|
||||||
unsigned int table_length;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
union {
|
union {
|
||||||
HBUINT16 major;
|
|
||||||
HBUINT32 version32;
|
HBUINT32 version32;
|
||||||
|
HBUINT16 major;
|
||||||
KernOT ot;
|
KernOT ot;
|
||||||
KernAAT aat;
|
KernAAT aat;
|
||||||
} u;
|
} u;
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_UNION (2, major);
|
DEFINE_SIZE_UNION (4, version32);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct kern_accelerator_t : kern::accelerator_t {};
|
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);
|
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
|
static hb_codepoint_t
|
||||||
modifier_combining_marks[] =
|
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);
|
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
|
static int
|
||||||
compare_combining_class (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
|
compare_combining_class (const hb_glyph_info_t *pa, const hb_glyph_info_t *pb)
|
||||||
|
@ -328,22 +319,56 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
|
||||||
|
|
||||||
/* First round, decompose */
|
/* First round, decompose */
|
||||||
|
|
||||||
|
bool all_simple = true;
|
||||||
|
{
|
||||||
buffer->clear_output ();
|
buffer->clear_output ();
|
||||||
count = buffer->len;
|
count = buffer->len;
|
||||||
for (buffer->idx = 0; buffer->idx < count && buffer->successful;)
|
buffer->idx = 0;
|
||||||
|
do
|
||||||
{
|
{
|
||||||
unsigned int end;
|
unsigned int end;
|
||||||
for (end = buffer->idx + 1; end < count; 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]))))
|
if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_MARK (_hb_glyph_info_get_general_category (&buffer->info[end]))))
|
||||||
break;
|
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) */
|
/* Second round, reorder (inplace) */
|
||||||
|
|
||||||
|
if (!all_simple)
|
||||||
|
{
|
||||||
count = buffer->len;
|
count = buffer->len;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
|
@ -368,6 +393,7 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
|
||||||
|
|
||||||
i = end;
|
i = end;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_CGJ)
|
if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_CGJ)
|
||||||
{
|
{
|
||||||
/* For all CGJ, check if it prevented any reordering at all.
|
/* For all CGJ, check if it prevented any reordering at all.
|
||||||
|
@ -385,8 +411,9 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
|
||||||
|
|
||||||
/* Third round, recompose */
|
/* Third round, recompose */
|
||||||
|
|
||||||
if (mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS ||
|
if (!all_simple &&
|
||||||
mode == HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT)
|
(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
|
/* As noted in the comment earlier, we don't try to combine
|
||||||
* ccc=0 chars with their previous Starter. */
|
* 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);
|
hb_synthesize_glyph_classes (c);
|
||||||
|
|
||||||
if (unlikely (c->plan->apply_morx))
|
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
|
else
|
||||||
c->plan->substitute (c->font, buffer);
|
c->plan->substitute (c->font, buffer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,8 @@
|
||||||
#include <hb-ot.h>
|
#include <hb-ot.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
static char *font_path = "fonts/Inconsolata-Regular.abc.ttf";
|
static const char *font_path = "fonts/Inconsolata-Regular.abc.ttf";
|
||||||
static char *text = "abc";
|
static const char *text = "abc";
|
||||||
|
|
||||||
static int num_threads = 30;
|
static int num_threads = 30;
|
||||||
static int num_iters = 200;
|
static int num_iters = 200;
|
||||||
|
@ -164,11 +164,8 @@ main (int argc, char **argv)
|
||||||
|
|
||||||
test_body ();
|
test_body ();
|
||||||
|
|
||||||
/* hb-font backed by FreeType functions can only be used from
|
hb_ft_font_set_funcs (font);
|
||||||
* one thread at a time, because that's FT_Face's MT guarantee.
|
test_body ();
|
||||||
* So, disable this, even though it works "most of the time". */
|
|
||||||
//hb_ft_font_set_funcs (font);
|
|
||||||
//test_body ();
|
|
||||||
|
|
||||||
hb_buffer_destroy (ref_buffer);
|
hb_buffer_destroy (ref_buffer);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue