Merge branch 'master' into cff-subset
This commit is contained in:
commit
b403be8ad9
|
@ -26,8 +26,6 @@
|
||||||
* Google Author(s): Behdad Esfahbod
|
* Google Author(s): Behdad Esfahbod
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define HB_SHAPER coretext
|
|
||||||
|
|
||||||
#include "hb.hh"
|
#include "hb.hh"
|
||||||
#include "hb-shaper-impl.hh"
|
#include "hb-shaper-impl.hh"
|
||||||
|
|
||||||
|
@ -101,11 +99,6 @@ _hb_cg_font_release (void *data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
HB_SHAPER_DATA_ENSURE_DEFINE(coretext, face);
|
|
||||||
HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(coretext, font,
|
|
||||||
fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size_from_ptem (font->ptem)) <= .5
|
|
||||||
);
|
|
||||||
|
|
||||||
static CTFontDescriptorRef
|
static CTFontDescriptorRef
|
||||||
get_last_resort_font_desc (void)
|
get_last_resort_font_desc (void)
|
||||||
{
|
{
|
||||||
|
@ -312,8 +305,7 @@ hb_coretext_face_create (CGFontRef cg_font)
|
||||||
CGFontRef
|
CGFontRef
|
||||||
hb_coretext_face_get_cg_font (hb_face_t *face)
|
hb_coretext_face_get_cg_font (hb_face_t *face)
|
||||||
{
|
{
|
||||||
if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return nullptr;
|
return (CGFontRef) (const void *) face->data.coretext;
|
||||||
return (CGFontRef) HB_SHAPER_DATA_GET (face);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -321,8 +313,9 @@ hb_coretext_font_data_t *
|
||||||
_hb_coretext_shaper_font_data_create (hb_font_t *font)
|
_hb_coretext_shaper_font_data_create (hb_font_t *font)
|
||||||
{
|
{
|
||||||
hb_face_t *face = font->face;
|
hb_face_t *face = font->face;
|
||||||
if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return nullptr;
|
const hb_coretext_face_data_t *face_data = face->data.coretext;
|
||||||
CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face);
|
if (unlikely (!face_data)) return nullptr;
|
||||||
|
CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext;
|
||||||
|
|
||||||
CTFontRef ct_font = create_ct_font (cg_font, coretext_font_size_from_ptem (font->ptem));
|
CTFontRef ct_font = create_ct_font (cg_font, coretext_font_size_from_ptem (font->ptem));
|
||||||
|
|
||||||
|
@ -341,6 +334,38 @@ _hb_coretext_shaper_font_data_destroy (hb_coretext_font_data_t *data)
|
||||||
CFRelease ((CTFontRef) data);
|
CFRelease ((CTFontRef) data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const hb_coretext_font_data_t *
|
||||||
|
hb_coretext_font_data_sync (hb_font_t *font)
|
||||||
|
{
|
||||||
|
retry:
|
||||||
|
const hb_coretext_font_data_t *data = font->data.coretext;
|
||||||
|
if (unlikely (!data)) return nullptr;
|
||||||
|
|
||||||
|
if (fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size_from_ptem (font->ptem)) > .5)
|
||||||
|
{
|
||||||
|
/* XXX-MT-bug
|
||||||
|
* Note that evaluating condition above can be dangerous if another thread
|
||||||
|
* got here first and destructed data. That's, as always, bad use pattern.
|
||||||
|
* If you modify the font (change font size), other threads must not be
|
||||||
|
* using it at the same time. However, since this check is delayed to
|
||||||
|
* when one actually tries to shape something, this is a XXX race condition
|
||||||
|
* (and the only one we have that I know of) right now. Ie. you modify the
|
||||||
|
* font size in one thread, then (supposedly safely) try to use it from two
|
||||||
|
* or more threads and BOOM! I'm not sure how to fix this. We want RCU.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Drop and recreate. */
|
||||||
|
/* If someone dropped it in the mean time, throw it away and don't touch it.
|
||||||
|
* Otherwise, destruct it. */
|
||||||
|
if (likely (font->data.coretext.cmpexch (const_cast<hb_coretext_font_data_t *> (data), nullptr)))
|
||||||
|
_hb_coretext_shaper_font_data_destroy (const_cast<hb_coretext_font_data_t *> (data));
|
||||||
|
else
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
return font->data.coretext;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since: 1.7.2
|
* Since: 1.7.2
|
||||||
*/
|
*/
|
||||||
|
@ -359,7 +384,7 @@ hb_coretext_font_create (CTFontRef ct_font)
|
||||||
hb_font_set_ptem (font, coretext_font_size_to_ptem (CTFontGetSize(ct_font)));
|
hb_font_set_ptem (font, coretext_font_size_to_ptem (CTFontGetSize(ct_font)));
|
||||||
|
|
||||||
/* Let there be dragons here... */
|
/* Let there be dragons here... */
|
||||||
HB_SHAPER_DATA (HB_SHAPER, font).set_relaxed ((hb_coretext_font_data_t *) CFRetain (ct_font));
|
font->data.coretext.cmpexch (nullptr, (hb_coretext_font_data_t *) CFRetain (ct_font));
|
||||||
|
|
||||||
return font;
|
return font;
|
||||||
}
|
}
|
||||||
|
@ -367,8 +392,8 @@ hb_coretext_font_create (CTFontRef ct_font)
|
||||||
CTFontRef
|
CTFontRef
|
||||||
hb_coretext_font_get_ct_font (hb_font_t *font)
|
hb_coretext_font_get_ct_font (hb_font_t *font)
|
||||||
{
|
{
|
||||||
if (unlikely (!hb_coretext_shaper_font_data_ensure (font))) return nullptr;
|
const hb_coretext_font_data_t *data = hb_coretext_font_data_sync (font);
|
||||||
return (CTFontRef) HB_SHAPER_DATA_GET (font);
|
return data ? (CTFontRef) data : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -427,8 +452,8 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
|
||||||
unsigned int num_features)
|
unsigned int num_features)
|
||||||
{
|
{
|
||||||
hb_face_t *face = font->face;
|
hb_face_t *face = font->face;
|
||||||
CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face);
|
CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext;
|
||||||
CTFontRef ct_font = (CTFontRef) HB_SHAPER_DATA_GET (font);
|
CTFontRef ct_font = (CTFontRef) hb_coretext_font_data_sync (font);
|
||||||
|
|
||||||
CGFloat ct_font_size = CTFontGetSize (ct_font);
|
CGFloat ct_font_size = CTFontGetSize (ct_font);
|
||||||
CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size;
|
CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size;
|
||||||
|
@ -1129,9 +1154,6 @@ fail:
|
||||||
* AAT shaper
|
* AAT shaper
|
||||||
*/
|
*/
|
||||||
|
|
||||||
HB_SHAPER_DATA_ENSURE_DEFINE(coretext_aat, face);
|
|
||||||
HB_SHAPER_DATA_ENSURE_DEFINE(coretext_aat, font);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* shaper face data
|
* shaper face data
|
||||||
*/
|
*/
|
||||||
|
@ -1149,7 +1171,7 @@ _hb_coretext_aat_shaper_face_data_create (hb_face_t *face)
|
||||||
if (hb_blob_get_length (blob))
|
if (hb_blob_get_length (blob))
|
||||||
{
|
{
|
||||||
hb_blob_destroy (blob);
|
hb_blob_destroy (blob);
|
||||||
return hb_coretext_shaper_face_data_ensure (face) ? (hb_coretext_aat_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
|
return face->data.coretext ? (hb_coretext_aat_face_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
|
||||||
}
|
}
|
||||||
hb_blob_destroy (blob);
|
hb_blob_destroy (blob);
|
||||||
}
|
}
|
||||||
|
@ -1172,7 +1194,7 @@ struct hb_coretext_aat_font_data_t {};
|
||||||
hb_coretext_aat_font_data_t *
|
hb_coretext_aat_font_data_t *
|
||||||
_hb_coretext_aat_shaper_font_data_create (hb_font_t *font)
|
_hb_coretext_aat_shaper_font_data_create (hb_font_t *font)
|
||||||
{
|
{
|
||||||
return hb_coretext_shaper_font_data_ensure (font) ? (hb_coretext_aat_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
|
return font->data.coretext ? (hb_coretext_aat_font_data_t *) HB_SHAPER_DATA_SUCCEEDED : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "hb.hh"
|
#include "hb.hh"
|
||||||
#define HB_SHAPER directwrite
|
|
||||||
#include "hb-shaper-impl.hh"
|
#include "hb-shaper-impl.hh"
|
||||||
|
|
||||||
#include <DWrite_1.h>
|
#include <DWrite_1.h>
|
||||||
|
@ -31,10 +30,6 @@
|
||||||
#include "hb-directwrite.h"
|
#include "hb-directwrite.h"
|
||||||
|
|
||||||
|
|
||||||
HB_SHAPER_DATA_ENSURE_DEFINE (directwrite, face);
|
|
||||||
HB_SHAPER_DATA_ENSURE_DEFINE (directwrite, font);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* hb-directwrite uses new/delete syntatically but as we let users
|
* hb-directwrite uses new/delete syntatically but as we let users
|
||||||
* to override malloc/free, we will redefine new/delete so users
|
* to override malloc/free, we will redefine new/delete so users
|
||||||
|
@ -240,8 +235,6 @@ struct hb_directwrite_font_data_t
|
||||||
hb_directwrite_font_data_t *
|
hb_directwrite_font_data_t *
|
||||||
_hb_directwrite_shaper_font_data_create (hb_font_t *font)
|
_hb_directwrite_shaper_font_data_create (hb_font_t *font)
|
||||||
{
|
{
|
||||||
if (unlikely (!hb_directwrite_shaper_face_data_ensure (font->face))) return nullptr;
|
|
||||||
|
|
||||||
hb_directwrite_font_data_t *data = new hb_directwrite_font_data_t;
|
hb_directwrite_font_data_t *data = new hb_directwrite_font_data_t;
|
||||||
if (unlikely (!data))
|
if (unlikely (!data))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -534,8 +527,8 @@ _hb_directwrite_shape_full (hb_shape_plan_t *shape_plan,
|
||||||
float lineWidth)
|
float lineWidth)
|
||||||
{
|
{
|
||||||
hb_face_t *face = font->face;
|
hb_face_t *face = font->face;
|
||||||
hb_directwrite_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
|
const hb_directwrite_face_data_t *face_data = face->data.directwrite;
|
||||||
hb_directwrite_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
|
const hb_directwrite_font_data_t *font_data = font->data.directwrite;
|
||||||
IDWriteFactory *dwriteFactory = face_data->dwriteFactory;
|
IDWriteFactory *dwriteFactory = face_data->dwriteFactory;
|
||||||
IDWriteFontFace *fontFace = face_data->fontFace;
|
IDWriteFontFace *fontFace = face_data->fontFace;
|
||||||
|
|
||||||
|
|
|
@ -90,12 +90,6 @@ DEFINE_NULL_INSTANCE (hb_face_t) =
|
||||||
HB_ATOMIC_INT_INIT (1000), /* upem */
|
HB_ATOMIC_INT_INIT (1000), /* upem */
|
||||||
HB_ATOMIC_INT_INIT (0), /* num_glyphs */
|
HB_ATOMIC_INT_INIT (0), /* num_glyphs */
|
||||||
|
|
||||||
{
|
|
||||||
#define HB_SHAPER_IMPLEMENT(shaper) HB_ATOMIC_PTR_INIT (HB_SHAPER_DATA_INVALID),
|
|
||||||
#include "hb-shaper-list.hh"
|
|
||||||
#undef HB_SHAPER_IMPLEMENT
|
|
||||||
},
|
|
||||||
|
|
||||||
/* Zero for the rest is fine. */
|
/* Zero for the rest is fine. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -131,6 +125,7 @@ hb_face_create_for_tables (hb_reference_table_func_t reference_table_func,
|
||||||
|
|
||||||
face->num_glyphs.set_relaxed (-1);
|
face->num_glyphs.set_relaxed (-1);
|
||||||
|
|
||||||
|
face->data.init0 (face);
|
||||||
face->table.init0 (face);
|
face->table.init0 (face);
|
||||||
|
|
||||||
return face;
|
return face;
|
||||||
|
@ -272,10 +267,7 @@ hb_face_destroy (hb_face_t *face)
|
||||||
node = next;
|
node = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, face);
|
face->data.fini ();
|
||||||
#include "hb-shaper-list.hh"
|
|
||||||
#undef HB_SHAPER_IMPLEMENT
|
|
||||||
|
|
||||||
face->table.fini ();
|
face->table.fini ();
|
||||||
|
|
||||||
if (face->destroy)
|
if (face->destroy)
|
||||||
|
|
|
@ -40,6 +40,10 @@
|
||||||
* hb_face_t
|
* hb_face_t
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INSTANTIATE_SHAPERS(shaper, face);
|
||||||
|
#include "hb-shaper-list.hh"
|
||||||
|
#undef HB_SHAPER_IMPLEMENT
|
||||||
|
|
||||||
struct hb_face_t
|
struct hb_face_t
|
||||||
{
|
{
|
||||||
hb_object_header_t header;
|
hb_object_header_t header;
|
||||||
|
@ -52,8 +56,7 @@ struct hb_face_t
|
||||||
mutable hb_atomic_int_t upem; /* Units-per-EM. */
|
mutable hb_atomic_int_t upem; /* Units-per-EM. */
|
||||||
mutable hb_atomic_int_t num_glyphs; /* Number of glyphs. */
|
mutable hb_atomic_int_t num_glyphs; /* Number of glyphs. */
|
||||||
|
|
||||||
struct hb_shaper_data_t shaper_data; /* Various shaper data. */
|
hb_shaper_object_dataset_t<hb_face_t> data;/* Various shaper data. */
|
||||||
|
|
||||||
hb_ot_face_t table; /* All the face's tables. */
|
hb_ot_face_t table; /* All the face's tables. */
|
||||||
|
|
||||||
/* Cache */
|
/* Cache */
|
||||||
|
@ -102,11 +105,5 @@ struct hb_face_t
|
||||||
};
|
};
|
||||||
DECLARE_NULL_INSTANCE (hb_face_t);
|
DECLARE_NULL_INSTANCE (hb_face_t);
|
||||||
|
|
||||||
#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
|
|
||||||
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, face);
|
|
||||||
#include "hb-shaper-list.hh"
|
|
||||||
#undef HB_SHAPER_IMPLEMENT
|
|
||||||
#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* HB_FACE_HH */
|
#endif /* HB_FACE_HH */
|
||||||
|
|
|
@ -24,14 +24,9 @@
|
||||||
* Google Author(s): Behdad Esfahbod
|
* Google Author(s): Behdad Esfahbod
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define HB_SHAPER fallback
|
|
||||||
#include "hb-shaper-impl.hh"
|
#include "hb-shaper-impl.hh"
|
||||||
|
|
||||||
|
|
||||||
HB_SHAPER_DATA_ENSURE_DEFINE(fallback, face);
|
|
||||||
HB_SHAPER_DATA_ENSURE_DEFINE(fallback, font);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* shaper face data
|
* shaper face data
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -1307,14 +1307,8 @@ DEFINE_NULL_INSTANCE (hb_font_t) =
|
||||||
nullptr, /* coords */
|
nullptr, /* coords */
|
||||||
|
|
||||||
const_cast<hb_font_funcs_t *> (&_hb_Null_hb_font_funcs_t),
|
const_cast<hb_font_funcs_t *> (&_hb_Null_hb_font_funcs_t),
|
||||||
nullptr, /* user_data */
|
|
||||||
nullptr, /* destroy */
|
|
||||||
|
|
||||||
{
|
/* Zero for the rest is fine. */
|
||||||
#define HB_SHAPER_IMPLEMENT(shaper) HB_ATOMIC_PTR_INIT (HB_SHAPER_DATA_INVALID),
|
|
||||||
#include "hb-shaper-list.hh"
|
|
||||||
#undef HB_SHAPER_IMPLEMENT
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1332,7 +1326,7 @@ _hb_font_create (hb_face_t *face)
|
||||||
font->parent = hb_font_get_empty ();
|
font->parent = hb_font_get_empty ();
|
||||||
font->face = hb_face_reference (face);
|
font->face = hb_face_reference (face);
|
||||||
font->klass = hb_font_funcs_get_empty ();
|
font->klass = hb_font_funcs_get_empty ();
|
||||||
|
font->data.init0 (font);
|
||||||
font->x_scale = font->y_scale = hb_face_get_upem (face);
|
font->x_scale = font->y_scale = hb_face_get_upem (face);
|
||||||
|
|
||||||
return font;
|
return font;
|
||||||
|
@ -1448,9 +1442,7 @@ hb_font_destroy (hb_font_t *font)
|
||||||
{
|
{
|
||||||
if (!hb_object_destroy (font)) return;
|
if (!hb_object_destroy (font)) return;
|
||||||
|
|
||||||
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font);
|
font->data.fini ();
|
||||||
#include "hb-shaper-list.hh"
|
|
||||||
#undef HB_SHAPER_IMPLEMENT
|
|
||||||
|
|
||||||
if (font->destroy)
|
if (font->destroy)
|
||||||
font->destroy (font->user_data);
|
font->destroy (font->user_data);
|
||||||
|
|
|
@ -96,6 +96,10 @@ DECLARE_NULL_INSTANCE (hb_font_funcs_t);
|
||||||
* hb_font_t
|
* hb_font_t
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INSTANTIATE_SHAPERS(shaper, font);
|
||||||
|
#include "hb-shaper-list.hh"
|
||||||
|
#undef HB_SHAPER_IMPLEMENT
|
||||||
|
|
||||||
struct hb_font_t
|
struct hb_font_t
|
||||||
{
|
{
|
||||||
hb_object_header_t header;
|
hb_object_header_t header;
|
||||||
|
@ -119,7 +123,7 @@ struct hb_font_t
|
||||||
void *user_data;
|
void *user_data;
|
||||||
hb_destroy_func_t destroy;
|
hb_destroy_func_t destroy;
|
||||||
|
|
||||||
struct hb_shaper_data_t shaper_data;
|
hb_shaper_object_dataset_t<hb_font_t> data; /* Various shaper data. */
|
||||||
|
|
||||||
|
|
||||||
/* Convert from font-space to user-space */
|
/* Convert from font-space to user-space */
|
||||||
|
@ -609,11 +613,5 @@ struct hb_font_t
|
||||||
};
|
};
|
||||||
DECLARE_NULL_INSTANCE (hb_font_t);
|
DECLARE_NULL_INSTANCE (hb_font_t);
|
||||||
|
|
||||||
#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
|
|
||||||
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, font);
|
|
||||||
#include "hb-shaper-list.hh"
|
|
||||||
#undef HB_SHAPER_IMPLEMENT
|
|
||||||
#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* HB_FONT_HH */
|
#endif /* HB_FONT_HH */
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
* Google Author(s): Behdad Esfahbod
|
* Google Author(s): Behdad Esfahbod
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define HB_SHAPER graphite2
|
|
||||||
#include "hb-shaper-impl.hh"
|
#include "hb-shaper-impl.hh"
|
||||||
|
|
||||||
#include "hb-graphite2.h"
|
#include "hb-graphite2.h"
|
||||||
|
@ -46,10 +45,6 @@
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
|
||||||
HB_SHAPER_DATA_ENSURE_DEFINE(graphite2, face);
|
|
||||||
HB_SHAPER_DATA_ENSURE_DEFINE(graphite2, font);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* shaper face data
|
* shaper face data
|
||||||
*/
|
*/
|
||||||
|
@ -185,8 +180,8 @@ _hb_graphite2_shaper_face_data_destroy (hb_graphite2_face_data_t *data)
|
||||||
gr_face *
|
gr_face *
|
||||||
hb_graphite2_face_get_gr_face (hb_face_t *face)
|
hb_graphite2_face_get_gr_face (hb_face_t *face)
|
||||||
{
|
{
|
||||||
if (unlikely (!hb_graphite2_shaper_face_data_ensure (face))) return nullptr;
|
const hb_graphite2_face_data_t *data = face->data.graphite2;
|
||||||
return HB_SHAPER_DATA_GET (face)->grface;
|
return data ? data->grface : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -241,7 +236,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
|
||||||
unsigned int num_features)
|
unsigned int num_features)
|
||||||
{
|
{
|
||||||
hb_face_t *face = font->face;
|
hb_face_t *face = font->face;
|
||||||
gr_face *grface = HB_SHAPER_DATA_GET (face)->grface;
|
gr_face *grface = face->data.graphite2->grface;
|
||||||
|
|
||||||
const char *lang = hb_language_to_string (hb_buffer_get_language (buffer));
|
const char *lang = hb_language_to_string (hb_buffer_get_language (buffer));
|
||||||
const char *lang_end = lang ? strchr (lang, '-') : nullptr;
|
const char *lang_end = lang ? strchr (lang, '-') : nullptr;
|
||||||
|
|
|
@ -755,10 +755,7 @@ struct hb_data_wrapper_t
|
||||||
inline bool is_inert (void) const { return !get_data (); }
|
inline bool is_inert (void) const { return !get_data (); }
|
||||||
|
|
||||||
template <typename Stored, typename Subclass>
|
template <typename Stored, typename Subclass>
|
||||||
inline Stored * call_create (void) const
|
inline Stored * call_create (void) const { return Subclass::create (get_data ()); }
|
||||||
{
|
|
||||||
return Subclass::create (this->get_data ());
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
template <>
|
template <>
|
||||||
struct hb_data_wrapper_t<void, 0>
|
struct hb_data_wrapper_t<void, 0>
|
||||||
|
@ -766,10 +763,7 @@ struct hb_data_wrapper_t<void, 0>
|
||||||
inline bool is_inert (void) const { return false; }
|
inline bool is_inert (void) const { return false; }
|
||||||
|
|
||||||
template <typename Stored, typename Funcs>
|
template <typename Stored, typename Funcs>
|
||||||
inline Stored * call_create (void) const
|
inline Stored * call_create (void) const { return Funcs::create (); }
|
||||||
{
|
|
||||||
return Funcs::create ();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T1, typename T2> struct hb_non_void_t { typedef T1 value; };
|
template <typename T1, typename T2> struct hb_non_void_t { typedef T1 value; };
|
||||||
|
@ -796,7 +790,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
|
||||||
{
|
{
|
||||||
retry:
|
retry:
|
||||||
Stored *p = instance.get ();
|
Stored *p = instance.get ();
|
||||||
if (unlikely (p && !this->instance.cmpexch (p, nullptr)))
|
if (unlikely (p && !cmpexch (p, nullptr)))
|
||||||
goto retry;
|
goto retry;
|
||||||
do_destroy (p);
|
do_destroy (p);
|
||||||
}
|
}
|
||||||
|
@ -809,6 +803,8 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
|
||||||
|
|
||||||
inline const Returned * operator -> (void) const { return get (); }
|
inline const Returned * operator -> (void) const { return get (); }
|
||||||
inline const Returned & operator * (void) const { return *get (); }
|
inline const Returned & operator * (void) const { return *get (); }
|
||||||
|
explicit_operator inline operator bool (void) const
|
||||||
|
{ return get_stored () != Funcs::get_null (); }
|
||||||
template <typename C> inline operator const C * (void) const { return get (); }
|
template <typename C> inline operator const C * (void) const { return get (); }
|
||||||
|
|
||||||
inline Stored * get_stored (void) const
|
inline Stored * get_stored (void) const
|
||||||
|
@ -824,7 +820,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
|
||||||
if (unlikely (!p))
|
if (unlikely (!p))
|
||||||
p = const_cast<Stored *> (Funcs::get_null ());
|
p = const_cast<Stored *> (Funcs::get_null ());
|
||||||
|
|
||||||
if (unlikely (!this->instance.cmpexch (nullptr, p)))
|
if (unlikely (!cmpexch (nullptr, p)))
|
||||||
{
|
{
|
||||||
do_destroy (p);
|
do_destroy (p);
|
||||||
goto retry;
|
goto retry;
|
||||||
|
@ -837,15 +833,10 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
|
||||||
return this->instance.get_relaxed ();
|
return this->instance.get_relaxed ();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void set_stored (Stored *instance_)
|
inline bool cmpexch (Stored *current, Stored *value) const
|
||||||
{
|
{
|
||||||
/* This *must* be called when there are no other threads accessing.
|
/* This *must* be called when there are no other threads accessing. */
|
||||||
* However, to make TSan, etc, happy, we using cmpexch. */
|
return this->instance.cmpexch (current, value);
|
||||||
retry:
|
|
||||||
Stored *p = this->instance.get ();
|
|
||||||
if (unlikely (!this->instance.cmpexch (p, instance_)))
|
|
||||||
goto retry;
|
|
||||||
do_destroy (p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const Returned * get (void) const { return Funcs::convert (get_stored ()); }
|
inline const Returned * get (void) const { return Funcs::convert (get_stored ()); }
|
||||||
|
@ -877,7 +868,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
|
||||||
free (p);
|
free (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
// private:
|
||||||
/* Must only have one pointer. */
|
/* Must only have one pointer. */
|
||||||
hb_atomic_ptr_t<Stored *> instance;
|
hb_atomic_ptr_t<Stored *> instance;
|
||||||
};
|
};
|
||||||
|
|
|
@ -58,7 +58,7 @@ struct IntType
|
||||||
{
|
{
|
||||||
typedef Type type;
|
typedef Type type;
|
||||||
inline void set (Type i) { v.set (i); }
|
inline void set (Type i) { v.set (i); }
|
||||||
inline operator Type(void) const { return v; }
|
inline operator Type (void) const { return v; }
|
||||||
inline bool operator == (const IntType<Type,Size> &o) const { return (Type) v == (Type) o.v; }
|
inline bool operator == (const IntType<Type,Size> &o) const { return (Type) v == (Type) o.v; }
|
||||||
inline bool operator != (const IntType<Type,Size> &o) const { return !(*this == o); }
|
inline bool operator != (const IntType<Type,Size> &o) const { return !(*this == o); }
|
||||||
static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); }
|
static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); }
|
||||||
|
@ -173,7 +173,7 @@ struct Offset : Type
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (sizeof(Type));
|
DEFINE_SIZE_STATIC (sizeof (Type));
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Offset<HBUINT16> Offset16;
|
typedef Offset<HBUINT16> Offset16;
|
||||||
|
@ -211,7 +211,7 @@ struct CheckSum : HBUINT32
|
||||||
template <typename FixedType=HBUINT16>
|
template <typename FixedType=HBUINT16>
|
||||||
struct FixedVersion
|
struct FixedVersion
|
||||||
{
|
{
|
||||||
inline uint32_t to_int (void) const { return (major << (sizeof(FixedType) * 8)) + minor; }
|
inline uint32_t to_int (void) const { return (major << (sizeof (FixedType) * 8)) + minor; }
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
|
@ -222,7 +222,7 @@ struct FixedVersion
|
||||||
FixedType major;
|
FixedType major;
|
||||||
FixedType minor;
|
FixedType minor;
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (2 * sizeof(FixedType));
|
DEFINE_SIZE_STATIC (2 * sizeof (FixedType));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -241,12 +241,12 @@ struct OffsetTo : Offset<OffsetType, has_null>
|
||||||
|
|
||||||
inline const Type& operator () (const void *base) const
|
inline const Type& operator () (const void *base) const
|
||||||
{
|
{
|
||||||
if (unlikely (this->is_null ())) return Null(Type);
|
if (unlikely (this->is_null ())) return Null (Type);
|
||||||
return StructAtOffset<const Type> (base, *this);
|
return StructAtOffset<const Type> (base, *this);
|
||||||
}
|
}
|
||||||
inline Type& operator () (void *base) const
|
inline Type& operator () (void *base) const
|
||||||
{
|
{
|
||||||
if (unlikely (this->is_null ())) return Crap(Type);
|
if (unlikely (this->is_null ())) return Crap (Type);
|
||||||
return StructAtOffset<Type> (base, *this);
|
return StructAtOffset<Type> (base, *this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,7 +258,7 @@ struct OffsetTo : Offset<OffsetType, has_null>
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline void serialize_subset (hb_subset_context_t *c, const T &src, const void *base)
|
inline void serialize_subset (hb_subset_context_t *c, const T &src, const void *base)
|
||||||
{
|
{
|
||||||
if (&src == &Null(T))
|
if (&src == &Null (T))
|
||||||
{
|
{
|
||||||
this->set (0);
|
this->set (0);
|
||||||
return;
|
return;
|
||||||
|
@ -319,7 +319,7 @@ struct OffsetTo : Offset<OffsetType, has_null>
|
||||||
if (!has_null) return false;
|
if (!has_null) return false;
|
||||||
return c->try_set (this, 0);
|
return c->try_set (this, 0);
|
||||||
}
|
}
|
||||||
DEFINE_SIZE_STATIC (sizeof(OffsetType));
|
DEFINE_SIZE_STATIC (sizeof (OffsetType));
|
||||||
};
|
};
|
||||||
template <typename Type, bool has_null=true> struct LOffsetTo : OffsetTo<Type, HBUINT32, has_null> {};
|
template <typename Type, bool has_null=true> struct LOffsetTo : OffsetTo<Type, HBUINT32, has_null> {};
|
||||||
template <typename Base, typename OffsetType, bool has_null, typename Type>
|
template <typename Base, typename OffsetType, bool has_null, typename Type>
|
||||||
|
@ -344,7 +344,7 @@ struct UnsizedArrayOf
|
||||||
* 1. For UnsizedArrayOf, it's not totally unimaginable to want to look
|
* 1. For UnsizedArrayOf, it's not totally unimaginable to want to look
|
||||||
* at items before the start of current array.
|
* at items before the start of current array.
|
||||||
* 2. Fixes MSVC 2008 "overloads have similar conversions" issue with the
|
* 2. Fixes MSVC 2008 "overloads have similar conversions" issue with the
|
||||||
* built-in operator [] that takes int, in expressions like sizeof(array[0])).
|
* built-in operator [] that takes int, in expressions like sizeof (array[0])).
|
||||||
* I suppose I could fix that by replacing 0 with 0u, but like this fix
|
* I suppose I could fix that by replacing 0 with 0u, but like this fix
|
||||||
* more now. */
|
* more now. */
|
||||||
inline const Type& operator [] (int i) const { return arrayZ[i]; }
|
inline const Type& operator [] (int i) const { return arrayZ[i]; }
|
||||||
|
@ -381,7 +381,7 @@ struct UnsizedArrayOf
|
||||||
if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
|
if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (unlikely (!arrayZ[i].sanitize (c, base)))
|
if (unlikely (!arrayZ[i].sanitize (c, base)))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -391,7 +391,7 @@ struct UnsizedArrayOf
|
||||||
if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
|
if (unlikely (!sanitize_shallow (c, count))) return_trace (false);
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
|
if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -455,12 +455,12 @@ struct ArrayOf
|
||||||
|
|
||||||
inline const Type& operator [] (unsigned int i) const
|
inline const Type& operator [] (unsigned int i) const
|
||||||
{
|
{
|
||||||
if (unlikely (i >= len)) return Null(Type);
|
if (unlikely (i >= len)) return Null (Type);
|
||||||
return arrayZ[i];
|
return arrayZ[i];
|
||||||
}
|
}
|
||||||
inline Type& operator [] (unsigned int i)
|
inline Type& operator [] (unsigned int i)
|
||||||
{
|
{
|
||||||
if (unlikely (i >= len)) return Crap(Type);
|
if (unlikely (i >= len)) return Crap (Type);
|
||||||
return arrayZ[i];
|
return arrayZ[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -511,7 +511,7 @@ struct ArrayOf
|
||||||
unsigned int count = len;
|
unsigned int count = len;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (unlikely (!arrayZ[i].sanitize (c, base)))
|
if (unlikely (!arrayZ[i].sanitize (c, base)))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -522,7 +522,7 @@ struct ArrayOf
|
||||||
unsigned int count = len;
|
unsigned int count = len;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
|
if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -532,7 +532,7 @@ struct ArrayOf
|
||||||
unsigned int count = len;
|
unsigned int count = len;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (!this->arrayZ[i].cmp (x))
|
if (!this->arrayZ[i].cmp (x))
|
||||||
return i;
|
return i;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,12 +570,12 @@ struct OffsetListOf : OffsetArrayOf<Type>
|
||||||
{
|
{
|
||||||
inline const Type& operator [] (unsigned int i) const
|
inline const Type& operator [] (unsigned int i) const
|
||||||
{
|
{
|
||||||
if (unlikely (i >= this->len)) return Null(Type);
|
if (unlikely (i >= this->len)) return Null (Type);
|
||||||
return this+this->arrayZ[i];
|
return this+this->arrayZ[i];
|
||||||
}
|
}
|
||||||
inline const Type& operator [] (unsigned int i)
|
inline const Type& operator [] (unsigned int i)
|
||||||
{
|
{
|
||||||
if (unlikely (i >= this->len)) return Crap(Type);
|
if (unlikely (i >= this->len)) return Crap (Type);
|
||||||
return this+this->arrayZ[i];
|
return this+this->arrayZ[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -613,12 +613,12 @@ struct HeadlessArrayOf
|
||||||
|
|
||||||
inline const Type& operator [] (unsigned int i) const
|
inline const Type& operator [] (unsigned int i) const
|
||||||
{
|
{
|
||||||
if (unlikely (i >= lenP1 || !i)) return Null(Type);
|
if (unlikely (i >= lenP1 || !i)) return Null (Type);
|
||||||
return arrayZ[i-1];
|
return arrayZ[i-1];
|
||||||
}
|
}
|
||||||
inline Type& operator [] (unsigned int i)
|
inline Type& operator [] (unsigned int i)
|
||||||
{
|
{
|
||||||
if (unlikely (i >= lenP1 || !i)) return Crap(Type);
|
if (unlikely (i >= lenP1 || !i)) return Crap (Type);
|
||||||
return arrayZ[i-1];
|
return arrayZ[i-1];
|
||||||
}
|
}
|
||||||
inline unsigned int get_size (void) const
|
inline unsigned int get_size (void) const
|
||||||
|
@ -679,12 +679,12 @@ struct ArrayOfM1
|
||||||
|
|
||||||
inline const Type& operator [] (unsigned int i) const
|
inline const Type& operator [] (unsigned int i) const
|
||||||
{
|
{
|
||||||
if (unlikely (i > lenM1)) return Null(Type);
|
if (unlikely (i > lenM1)) return Null (Type);
|
||||||
return arrayZ[i];
|
return arrayZ[i];
|
||||||
}
|
}
|
||||||
inline Type& operator [] (unsigned int i)
|
inline Type& operator [] (unsigned int i)
|
||||||
{
|
{
|
||||||
if (unlikely (i > lenM1)) return Crap(Type);
|
if (unlikely (i > lenM1)) return Crap (Type);
|
||||||
return arrayZ[i];
|
return arrayZ[i];
|
||||||
}
|
}
|
||||||
inline unsigned int get_size (void) const
|
inline unsigned int get_size (void) const
|
||||||
|
@ -698,7 +698,7 @@ struct ArrayOfM1
|
||||||
unsigned int count = lenM1 + 1;
|
unsigned int count = lenM1 + 1;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
|
if (unlikely (!arrayZ[i].sanitize (c, base, user_data)))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -731,12 +731,9 @@ struct SortedArrayOf : ArrayOf<Type, LenType>
|
||||||
{
|
{
|
||||||
int mid = ((unsigned int) min + (unsigned int) max) / 2;
|
int mid = ((unsigned int) min + (unsigned int) max) / 2;
|
||||||
int c = arr[mid].cmp (x);
|
int c = arr[mid].cmp (x);
|
||||||
if (c < 0)
|
if (c < 0) max = mid - 1;
|
||||||
max = mid - 1;
|
else if (c > 0) min = mid + 1;
|
||||||
else if (c > 0)
|
else return mid;
|
||||||
min = mid + 1;
|
|
||||||
else
|
|
||||||
return mid;
|
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -813,7 +810,7 @@ struct VarSizedBinSearchArrayOf
|
||||||
|
|
||||||
inline const Type& operator [] (unsigned int i) const
|
inline const Type& operator [] (unsigned int i) const
|
||||||
{
|
{
|
||||||
if (unlikely (i >= header.nUnits)) return Null(Type);
|
if (unlikely (i >= header.nUnits)) return Null (Type);
|
||||||
return StructAtOffset<Type> (&bytesZ, i * header.unitSize);
|
return StructAtOffset<Type> (&bytesZ, i * header.unitSize);
|
||||||
}
|
}
|
||||||
inline Type& operator [] (unsigned int i)
|
inline Type& operator [] (unsigned int i)
|
||||||
|
@ -846,7 +843,7 @@ struct VarSizedBinSearchArrayOf
|
||||||
unsigned int count = header.nUnits;
|
unsigned int count = header.nUnits;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (unlikely (!(*this)[i].sanitize (c, base)))
|
if (unlikely (!(*this)[i].sanitize (c, base)))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
@ -857,7 +854,7 @@ struct VarSizedBinSearchArrayOf
|
||||||
unsigned int count = header.nUnits;
|
unsigned int count = header.nUnits;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (unlikely (!(*this)[i].sanitize (c, base, user_data)))
|
if (unlikely (!(*this)[i].sanitize (c, base, user_data)))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -871,12 +868,9 @@ struct VarSizedBinSearchArrayOf
|
||||||
int mid = ((unsigned int) min + (unsigned int) max) / 2;
|
int mid = ((unsigned int) min + (unsigned int) max) / 2;
|
||||||
const Type *p = (const Type *) (((const char *) &bytesZ) + (mid * size));
|
const Type *p = (const Type *) (((const char *) &bytesZ) + (mid * size));
|
||||||
int c = p->cmp (key);
|
int c = p->cmp (key);
|
||||||
if (c < 0)
|
if (c < 0) max = mid - 1;
|
||||||
max = mid - 1;
|
else if (c > 0) min = mid + 1;
|
||||||
else if (c > 0)
|
else return p;
|
||||||
min = mid + 1;
|
|
||||||
else
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ struct CmapSubtableFormat0
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < 256; i++)
|
for (unsigned int i = 0; i < 256; i++)
|
||||||
if (glyphIdArray[i])
|
if (glyphIdArray[i])
|
||||||
out->add (i);
|
out->add (i);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
@ -82,8 +82,8 @@ struct CmapSubtableFormat4
|
||||||
};
|
};
|
||||||
|
|
||||||
bool serialize (hb_serialize_context_t *c,
|
bool serialize (hb_serialize_context_t *c,
|
||||||
const hb_subset_plan_t *plan,
|
const hb_subset_plan_t *plan,
|
||||||
const hb_vector_t<segment_plan> &segments)
|
const hb_vector_t<segment_plan> &segments)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
|
|
||||||
|
@ -96,8 +96,8 @@ struct CmapSubtableFormat4
|
||||||
this->entrySelector.set (MAX (1u, hb_bit_storage (segments.len)) - 1);
|
this->entrySelector.set (MAX (1u, hb_bit_storage (segments.len)) - 1);
|
||||||
this->searchRange.set (2 * (1u << this->entrySelector));
|
this->searchRange.set (2 * (1u << this->entrySelector));
|
||||||
this->rangeShift.set (segments.len * 2 > this->searchRange
|
this->rangeShift.set (segments.len * 2 > this->searchRange
|
||||||
? 2 * segments.len - this->searchRange
|
? 2 * segments.len - this->searchRange
|
||||||
: 0);
|
: 0);
|
||||||
|
|
||||||
HBUINT16 *end_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.len);
|
HBUINT16 *end_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.len);
|
||||||
c->allocate_size<HBUINT16> (HBUINT16::static_size); // 2 bytes of padding.
|
c->allocate_size<HBUINT16> (HBUINT16::static_size); // 2 bytes of padding.
|
||||||
|
@ -114,40 +114,40 @@ struct CmapSubtableFormat4
|
||||||
start_count[i].set (segments[i].start_code);
|
start_count[i].set (segments[i].start_code);
|
||||||
if (segments[i].use_delta)
|
if (segments[i].use_delta)
|
||||||
{
|
{
|
||||||
hb_codepoint_t cp = segments[i].start_code;
|
hb_codepoint_t cp = segments[i].start_code;
|
||||||
hb_codepoint_t start_gid = 0;
|
hb_codepoint_t start_gid = 0;
|
||||||
if (unlikely (!plan->new_gid_for_codepoint (cp, &start_gid) && cp != 0xFFFF))
|
if (unlikely (!plan->new_gid_for_codepoint (cp, &start_gid) && cp != 0xFFFF))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
id_delta[i].set (start_gid - segments[i].start_code);
|
id_delta[i].set (start_gid - segments[i].start_code);
|
||||||
} else {
|
} else {
|
||||||
id_delta[i].set (0);
|
id_delta[i].set (0);
|
||||||
unsigned int num_codepoints = segments[i].end_code - segments[i].start_code + 1;
|
unsigned int num_codepoints = segments[i].end_code - segments[i].start_code + 1;
|
||||||
HBUINT16 *glyph_id_array = c->allocate_size<HBUINT16> (HBUINT16::static_size * num_codepoints);
|
HBUINT16 *glyph_id_array = c->allocate_size<HBUINT16> (HBUINT16::static_size * num_codepoints);
|
||||||
if (glyph_id_array == nullptr)
|
if (glyph_id_array == nullptr)
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
// From the cmap spec:
|
// From the cmap spec:
|
||||||
//
|
//
|
||||||
// id_range_offset[i]/2
|
// id_range_offset[i]/2
|
||||||
// + (cp - segments[i].start_code)
|
// + (cp - segments[i].start_code)
|
||||||
// + (id_range_offset + i)
|
// + (id_range_offset + i)
|
||||||
// =
|
// =
|
||||||
// glyph_id_array + (cp - segments[i].start_code)
|
// glyph_id_array + (cp - segments[i].start_code)
|
||||||
//
|
//
|
||||||
// So, solve for id_range_offset[i]:
|
// So, solve for id_range_offset[i]:
|
||||||
//
|
//
|
||||||
// id_range_offset[i]
|
// id_range_offset[i]
|
||||||
// =
|
// =
|
||||||
// 2 * (glyph_id_array - id_range_offset - i)
|
// 2 * (glyph_id_array - id_range_offset - i)
|
||||||
id_range_offset[i].set (2 * (
|
id_range_offset[i].set (2 * (
|
||||||
glyph_id_array - id_range_offset - i));
|
glyph_id_array - id_range_offset - i));
|
||||||
for (unsigned int j = 0; j < num_codepoints; j++)
|
for (unsigned int j = 0; j < num_codepoints; j++)
|
||||||
{
|
{
|
||||||
hb_codepoint_t cp = segments[i].start_code + j;
|
hb_codepoint_t cp = segments[i].start_code + j;
|
||||||
hb_codepoint_t new_gid;
|
hb_codepoint_t new_gid;
|
||||||
if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid)))
|
if (unlikely (!plan->new_gid_for_codepoint (cp, &new_gid)))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
glyph_id_array[j].set (new_gid);
|
glyph_id_array[j].set (new_gid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,23 +161,23 @@ struct CmapSubtableFormat4
|
||||||
{
|
{
|
||||||
// Parallel array entries
|
// Parallel array entries
|
||||||
segment_size +=
|
segment_size +=
|
||||||
2 // end count
|
2 // end count
|
||||||
+ 2 // start count
|
+ 2 // start count
|
||||||
+ 2 // delta
|
+ 2 // delta
|
||||||
+ 2; // range offset
|
+ 2; // range offset
|
||||||
|
|
||||||
if (!segments[i].use_delta)
|
if (!segments[i].use_delta)
|
||||||
// Add bytes for the glyph index array entries for this segment.
|
// Add bytes for the glyph index array entries for this segment.
|
||||||
segment_size += (segments[i].end_code - segments[i].start_code + 1) * 2;
|
segment_size += (segments[i].end_code - segments[i].start_code + 1) * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
return min_size
|
return min_size
|
||||||
+ 2 // Padding
|
+ 2 // Padding
|
||||||
+ segment_size;
|
+ segment_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool create_sub_table_plan (const hb_subset_plan_t *plan,
|
static inline bool create_sub_table_plan (const hb_subset_plan_t *plan,
|
||||||
hb_vector_t<segment_plan> *segments)
|
hb_vector_t<segment_plan> *segments)
|
||||||
{
|
{
|
||||||
segment_plan *segment = nullptr;
|
segment_plan *segment = nullptr;
|
||||||
hb_codepoint_t last_gid = 0;
|
hb_codepoint_t last_gid = 0;
|
||||||
|
@ -191,24 +191,22 @@ struct CmapSubtableFormat4
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cp > 0xFFFF) {
|
/* Stop adding to cmap if we are now outside of unicode BMP. */
|
||||||
// We are now outside of unicode BMP, stop adding to this cmap.
|
if (cp > 0xFFFF) break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!segment
|
if (!segment ||
|
||||||
|| cp != segment->end_code + 1u)
|
cp != segment->end_code + 1u)
|
||||||
{
|
{
|
||||||
segment = segments->push ();
|
segment = segments->push ();
|
||||||
segment->start_code.set (cp);
|
segment->start_code.set (cp);
|
||||||
segment->end_code.set (cp);
|
segment->end_code.set (cp);
|
||||||
segment->use_delta = true;
|
segment->use_delta = true;
|
||||||
} else {
|
} else {
|
||||||
segment->end_code.set (cp);
|
segment->end_code.set (cp);
|
||||||
if (last_gid + 1u != new_gid)
|
if (last_gid + 1u != new_gid)
|
||||||
// gid's are not consecutive in this segment so delta
|
// gid's are not consecutive in this segment so delta
|
||||||
// cannot be used.
|
// cannot be used.
|
||||||
segment->use_delta = false;
|
segment->use_delta = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
last_gid = new_gid;
|
last_gid = new_gid;
|
||||||
|
@ -253,7 +251,7 @@ struct CmapSubtableFormat4
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
while (min <= max)
|
while (min <= max)
|
||||||
{
|
{
|
||||||
int mid = ((unsigned int) min + (unsigned int) max) / 2;
|
int mid = ((unsigned int) min + (unsigned int) max) / 2;
|
||||||
if (codepoint < startCount[mid])
|
if (codepoint < startCount[mid])
|
||||||
max = mid - 1;
|
max = mid - 1;
|
||||||
else if (codepoint > endCount[mid])
|
else if (codepoint > endCount[mid])
|
||||||
|
@ -296,7 +294,7 @@ struct CmapSubtableFormat4
|
||||||
{
|
{
|
||||||
unsigned int count = this->segCount;
|
unsigned int count = this->segCount;
|
||||||
if (count && this->startCount[count - 1] == 0xFFFFu)
|
if (count && this->startCount[count - 1] == 0xFFFFu)
|
||||||
count--; /* Skip sentinel segment. */
|
count--; /* Skip sentinel segment. */
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
unsigned int rangeOffset = this->idRangeOffset[i];
|
unsigned int rangeOffset = this->idRangeOffset[i];
|
||||||
|
@ -438,7 +436,7 @@ struct CmapSubtableTrimmed
|
||||||
unsigned int count = glyphIdArray.len;
|
unsigned int count = glyphIdArray.len;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (glyphIdArray[i])
|
if (glyphIdArray[i])
|
||||||
out->add (start + i);
|
out->add (start + i);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
@ -495,7 +493,7 @@ struct CmapSubtableLongSegmented
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool serialize (hb_serialize_context_t *c,
|
inline bool serialize (hb_serialize_context_t *c,
|
||||||
const hb_vector_t<CmapSubtableLongGroup> &group_data)
|
const hb_vector_t<CmapSubtableLongGroup> &group_data)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
if (unlikely (!c->extend_min (*this))) return_trace (false);
|
if (unlikely (!c->extend_min (*this))) return_trace (false);
|
||||||
|
@ -523,7 +521,7 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
|
||||||
|
|
||||||
|
|
||||||
bool serialize (hb_serialize_context_t *c,
|
bool serialize (hb_serialize_context_t *c,
|
||||||
const hb_vector_t<CmapSubtableLongGroup> &groups)
|
const hb_vector_t<CmapSubtableLongGroup> &groups)
|
||||||
{
|
{
|
||||||
if (unlikely (!c->extend_min (*this))) return false;
|
if (unlikely (!c->extend_min (*this))) return false;
|
||||||
|
|
||||||
|
@ -540,7 +538,7 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool create_sub_table_plan (const hb_subset_plan_t *plan,
|
static inline bool create_sub_table_plan (const hb_subset_plan_t *plan,
|
||||||
hb_vector_t<CmapSubtableLongGroup> *groups)
|
hb_vector_t<CmapSubtableLongGroup> *groups)
|
||||||
{
|
{
|
||||||
CmapSubtableLongGroup *group = nullptr;
|
CmapSubtableLongGroup *group = nullptr;
|
||||||
|
|
||||||
|
@ -555,14 +553,12 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
|
||||||
|
|
||||||
if (!group || !_is_gid_consecutive (group, cp, new_gid))
|
if (!group || !_is_gid_consecutive (group, cp, new_gid))
|
||||||
{
|
{
|
||||||
group = groups->push ();
|
group = groups->push ();
|
||||||
group->startCharCode.set (cp);
|
group->startCharCode.set (cp);
|
||||||
group->endCharCode.set (cp);
|
group->endCharCode.set (cp);
|
||||||
group->glyphID.set (new_gid);
|
group->glyphID.set (new_gid);
|
||||||
} else
|
|
||||||
{
|
|
||||||
group->endCharCode.set (cp);
|
|
||||||
}
|
}
|
||||||
|
else group->endCharCode.set (cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_MSG(SUBSET, nullptr, "cmap");
|
DEBUG_MSG(SUBSET, nullptr, "cmap");
|
||||||
|
@ -855,12 +851,12 @@ struct cmap
|
||||||
|
|
||||||
struct subset_plan
|
struct subset_plan
|
||||||
{
|
{
|
||||||
inline size_t final_size() const
|
inline size_t final_size () const
|
||||||
{
|
{
|
||||||
return 4 // header
|
return 4 // header
|
||||||
+ 8 * 3 // 3 EncodingRecord
|
+ 8 * 3 // 3 EncodingRecord
|
||||||
+ CmapSubtableFormat4::get_sub_table_size (this->format4_segments)
|
+ CmapSubtableFormat4::get_sub_table_size (this->format4_segments)
|
||||||
+ CmapSubtableFormat12::get_sub_table_size (this->format12_groups);
|
+ CmapSubtableFormat12::get_sub_table_size (this->format12_groups);
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_vector_t<CmapSubtableFormat4::segment_plan> format4_segments;
|
hb_vector_t<CmapSubtableFormat4::segment_plan> format4_segments;
|
||||||
|
@ -876,16 +872,16 @@ struct cmap
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool _create_plan (const hb_subset_plan_t *plan,
|
inline bool _create_plan (const hb_subset_plan_t *plan,
|
||||||
subset_plan *cmap_plan) const
|
subset_plan *cmap_plan) const
|
||||||
{
|
{
|
||||||
if (unlikely( !CmapSubtableFormat4::create_sub_table_plan (plan, &cmap_plan->format4_segments)))
|
if (unlikely (!CmapSubtableFormat4::create_sub_table_plan (plan, &cmap_plan->format4_segments)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return CmapSubtableFormat12::create_sub_table_plan (plan, &cmap_plan->format12_groups);
|
return CmapSubtableFormat12::create_sub_table_plan (plan, &cmap_plan->format12_groups);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool _subset (const hb_subset_plan_t *plan,
|
inline bool _subset (const hb_subset_plan_t *plan,
|
||||||
const subset_plan &cmap_subset_plan,
|
const subset_plan &cmap_subset_plan,
|
||||||
size_t dest_sz,
|
size_t dest_sz,
|
||||||
void *dest) const
|
void *dest) const
|
||||||
{
|
{
|
||||||
|
@ -927,7 +923,7 @@ struct cmap
|
||||||
|
|
||||||
CmapSubtableFormat4 &format4 = subtable.u.format4;
|
CmapSubtableFormat4 &format4 = subtable.u.format4;
|
||||||
if (unlikely (!format4.serialize (&c, plan, cmap_subset_plan.format4_segments)))
|
if (unlikely (!format4.serialize (&c, plan, cmap_subset_plan.format4_segments)))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write out format 12 sub table.
|
// Write out format 12 sub table.
|
||||||
|
@ -937,7 +933,7 @@ struct cmap
|
||||||
|
|
||||||
CmapSubtableFormat12 &format12 = subtable.u.format12;
|
CmapSubtableFormat12 &format12 = subtable.u.format12;
|
||||||
if (unlikely (!format12.serialize (&c, cmap_subset_plan.format12_groups)))
|
if (unlikely (!format12.serialize (&c, cmap_subset_plan.format12_groups)))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
c.end_serialize ();
|
c.end_serialize ();
|
||||||
|
@ -956,7 +952,7 @@ struct cmap
|
||||||
}
|
}
|
||||||
|
|
||||||
// We now know how big our blob needs to be
|
// We now know how big our blob needs to be
|
||||||
size_t dest_sz = cmap_subset_plan.final_size();
|
size_t dest_sz = cmap_subset_plan.final_size ();
|
||||||
void *dest = malloc (dest_sz);
|
void *dest = malloc (dest_sz);
|
||||||
if (unlikely (!dest)) {
|
if (unlikely (!dest)) {
|
||||||
DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for cmap subset output", (unsigned long) dest_sz);
|
DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for cmap subset output", (unsigned long) dest_sz);
|
||||||
|
@ -971,11 +967,11 @@ struct cmap
|
||||||
}
|
}
|
||||||
|
|
||||||
// all done, write the blob into dest
|
// all done, write the blob into dest
|
||||||
hb_blob_t *cmap_prime = hb_blob_create ((const char *)dest,
|
hb_blob_t *cmap_prime = hb_blob_create ((const char *) dest,
|
||||||
dest_sz,
|
dest_sz,
|
||||||
HB_MEMORY_MODE_READONLY,
|
HB_MEMORY_MODE_READONLY,
|
||||||
dest,
|
dest,
|
||||||
free);
|
free);
|
||||||
bool result = plan->add_table (HB_OT_TAG_cmap, cmap_prime);
|
bool result = plan->add_table (HB_OT_TAG_cmap, cmap_prime);
|
||||||
hb_blob_destroy (cmap_prime);
|
hb_blob_destroy (cmap_prime);
|
||||||
return result;
|
return result;
|
||||||
|
@ -1007,17 +1003,17 @@ struct cmap
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Meh. */
|
/* Meh. */
|
||||||
return &Null(CmapSubtable);
|
return &Null (CmapSubtable);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct accelerator_t
|
struct accelerator_t
|
||||||
{
|
{
|
||||||
inline void init (hb_face_t *face)
|
inline void init (hb_face_t *face)
|
||||||
{
|
{
|
||||||
this->table = hb_sanitize_context_t().reference_table<cmap> (face);
|
this->table = hb_sanitize_context_t ().reference_table<cmap> (face);
|
||||||
bool symbol;
|
bool symbol;
|
||||||
this->subtable = table->find_best_subtable (&symbol);
|
this->subtable = table->find_best_subtable (&symbol);
|
||||||
this->subtable_uvs = &Null(CmapSubtableFormat14);
|
this->subtable_uvs = &Null (CmapSubtableFormat14);
|
||||||
{
|
{
|
||||||
const CmapSubtable *st = table->find_subtable (0, 5);
|
const CmapSubtable *st = table->find_subtable (0, 5);
|
||||||
if (st && st->u.format == 14)
|
if (st && st->u.format == 14)
|
||||||
|
|
|
@ -102,7 +102,7 @@ struct glyf
|
||||||
static bool
|
static bool
|
||||||
_add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca)
|
_add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca)
|
||||||
{
|
{
|
||||||
hb_blob_t *head_blob = hb_sanitize_context_t().reference_table<head> (plan->source);
|
hb_blob_t *head_blob = hb_sanitize_context_t ().reference_table<head> (plan->source);
|
||||||
hb_blob_t *head_prime_blob = hb_blob_copy_writable_or_fail (head_blob);
|
hb_blob_t *head_prime_blob = hb_blob_copy_writable_or_fail (head_blob);
|
||||||
hb_blob_destroy (head_blob);
|
hb_blob_destroy (head_blob);
|
||||||
|
|
||||||
|
@ -120,9 +120,9 @@ struct glyf
|
||||||
struct GlyphHeader
|
struct GlyphHeader
|
||||||
{
|
{
|
||||||
HBINT16 numberOfContours; /* If the number of contours is
|
HBINT16 numberOfContours; /* If the number of contours is
|
||||||
* greater than or equal to zero,
|
* greater than or equal to zero,
|
||||||
* this is a simple glyph; if negative,
|
* this is a simple glyph; if negative,
|
||||||
* this is a composite glyph. */
|
* this is a composite glyph. */
|
||||||
FWORD xMin; /* Minimum x for coordinate data. */
|
FWORD xMin; /* Minimum x for coordinate data. */
|
||||||
FWORD yMin; /* Minimum y for coordinate data. */
|
FWORD yMin; /* Minimum y for coordinate data. */
|
||||||
FWORD xMax; /* Maximum x for coordinate data. */
|
FWORD xMax; /* Maximum x for coordinate data. */
|
||||||
|
@ -154,23 +154,18 @@ struct glyf
|
||||||
inline unsigned int get_size (void) const
|
inline unsigned int get_size (void) const
|
||||||
{
|
{
|
||||||
unsigned int size = min_size;
|
unsigned int size = min_size;
|
||||||
if (flags & ARG_1_AND_2_ARE_WORDS) {
|
// arg1 and 2 are int16
|
||||||
// arg1 and 2 are int16
|
if (flags & ARG_1_AND_2_ARE_WORDS) size += 4;
|
||||||
size += 4;
|
// arg1 and 2 are int8
|
||||||
} else {
|
else size += 2;
|
||||||
// arg1 and 2 are int8
|
|
||||||
size += 2;
|
// One x 16 bit (scale)
|
||||||
}
|
if (flags & WE_HAVE_A_SCALE) size += 2;
|
||||||
if (flags & WE_HAVE_A_SCALE) {
|
// Two x 16 bit (xscale, yscale)
|
||||||
// One x 16 bit (scale)
|
else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) size += 4;
|
||||||
size += 2;
|
// Four x 16 bit (xscale, scale01, scale10, yscale)
|
||||||
} else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) {
|
else if (flags & WE_HAVE_A_TWO_BY_TWO) size += 8;
|
||||||
// Two x 16 bit (xscale, yscale)
|
|
||||||
size += 4;
|
|
||||||
} else if (flags & WE_HAVE_A_TWO_BY_TWO) {
|
|
||||||
// Four x 16 bit (xscale, scale01, scale10, yscale)
|
|
||||||
size += 8;
|
|
||||||
}
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -198,7 +193,7 @@ struct glyf
|
||||||
{
|
{
|
||||||
return (const char *) composite >= glyph_start
|
return (const char *) composite >= glyph_start
|
||||||
&& ((const char *) composite + CompositeGlyphHeader::min_size) <= glyph_end
|
&& ((const char *) composite + CompositeGlyphHeader::min_size) <= glyph_end
|
||||||
&& ((const char *) composite + composite->get_size()) <= glyph_end;
|
&& ((const char *) composite + composite->get_size ()) <= glyph_end;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -212,15 +207,15 @@ struct glyf
|
||||||
const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyph_data, 0);
|
const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyph_data, 0);
|
||||||
if (glyph_header.numberOfContours < 0)
|
if (glyph_header.numberOfContours < 0)
|
||||||
{
|
{
|
||||||
const CompositeGlyphHeader *possible =
|
const CompositeGlyphHeader *possible =
|
||||||
&StructAfter<CompositeGlyphHeader, GlyphHeader> (glyph_header);
|
&StructAfter<CompositeGlyphHeader, GlyphHeader> (glyph_header);
|
||||||
|
|
||||||
iterator->glyph_start = glyph_data;
|
iterator->glyph_start = glyph_data;
|
||||||
iterator->glyph_end = (const char *) glyph_data + length;
|
iterator->glyph_end = (const char *) glyph_data + length;
|
||||||
if (!iterator->in_range (possible))
|
if (!iterator->in_range (possible))
|
||||||
return false;
|
return false;
|
||||||
iterator->current = possible;
|
iterator->current = possible;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -241,8 +236,8 @@ struct glyf
|
||||||
return;
|
return;
|
||||||
short_offset = 0 == head.indexToLocFormat;
|
short_offset = 0 == head.indexToLocFormat;
|
||||||
|
|
||||||
loca_table = hb_sanitize_context_t().reference_table<loca> (face);
|
loca_table = hb_sanitize_context_t ().reference_table<loca> (face);
|
||||||
glyf_table = hb_sanitize_context_t().reference_table<glyf> (face);
|
glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face);
|
||||||
|
|
||||||
num_glyphs = MAX (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1;
|
num_glyphs = MAX (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1;
|
||||||
}
|
}
|
||||||
|
@ -266,7 +261,7 @@ struct glyf
|
||||||
|
|
||||||
unsigned int start_offset, end_offset;
|
unsigned int start_offset, end_offset;
|
||||||
if (!get_offsets (glyph, &start_offset, &end_offset))
|
if (!get_offsets (glyph, &start_offset, &end_offset))
|
||||||
return false; /* glyph not found */
|
return false; /* glyph not found */
|
||||||
|
|
||||||
return CompositeGlyphHeader::get_iterator ((const char *) this->glyf_table + start_offset,
|
return CompositeGlyphHeader::get_iterator ((const char *) this->glyf_table + start_offset,
|
||||||
end_offset - start_offset,
|
end_offset - start_offset,
|
||||||
|
@ -282,11 +277,10 @@ struct glyf
|
||||||
};
|
};
|
||||||
|
|
||||||
/* based on FontTools _g_l_y_f.py::trim */
|
/* based on FontTools _g_l_y_f.py::trim */
|
||||||
inline bool remove_padding(unsigned int start_offset,
|
inline bool remove_padding (unsigned int start_offset,
|
||||||
unsigned int *end_offset) const
|
unsigned int *end_offset) const
|
||||||
{
|
{
|
||||||
if (*end_offset - start_offset < GlyphHeader::static_size)
|
if (*end_offset - start_offset < GlyphHeader::static_size) return true;
|
||||||
return true;
|
|
||||||
|
|
||||||
const char *glyph = ((const char *) glyf_table) + start_offset;
|
const char *glyph = ((const char *) glyf_table) + start_offset;
|
||||||
const char * const glyph_end = glyph + (*end_offset - start_offset);
|
const char * const glyph_end = glyph + (*end_offset - start_offset);
|
||||||
|
@ -294,87 +288,83 @@ struct glyf
|
||||||
int16_t num_contours = (int16_t) glyph_header.numberOfContours;
|
int16_t num_contours = (int16_t) glyph_header.numberOfContours;
|
||||||
|
|
||||||
if (num_contours < 0)
|
if (num_contours < 0)
|
||||||
/* Trimming for composites not implemented.
|
/* Trimming for composites not implemented.
|
||||||
* If removing hints it falls out of that. */
|
* If removing hints it falls out of that. */
|
||||||
return true;
|
return true;
|
||||||
else if (num_contours > 0)
|
else if (num_contours > 0)
|
||||||
{
|
{
|
||||||
/* simple glyph w/contours, possibly trimmable */
|
/* simple glyph w/contours, possibly trimmable */
|
||||||
glyph += GlyphHeader::static_size + 2 * num_contours;
|
glyph += GlyphHeader::static_size + 2 * num_contours;
|
||||||
|
|
||||||
if (unlikely (glyph + 2 >= glyph_end)) return false;
|
if (unlikely (glyph + 2 >= glyph_end)) return false;
|
||||||
uint16_t nCoordinates = (uint16_t) StructAtOffset<HBUINT16>(glyph - 2, 0) + 1;
|
uint16_t nCoordinates = (uint16_t) StructAtOffset<HBUINT16> (glyph - 2, 0) + 1;
|
||||||
uint16_t nInstructions = (uint16_t) StructAtOffset<HBUINT16>(glyph, 0);
|
uint16_t nInstructions = (uint16_t) StructAtOffset<HBUINT16> (glyph, 0);
|
||||||
|
|
||||||
glyph += 2 + nInstructions;
|
glyph += 2 + nInstructions;
|
||||||
if (unlikely (glyph + 2 >= glyph_end)) return false;
|
if (unlikely (glyph + 2 >= glyph_end)) return false;
|
||||||
|
|
||||||
unsigned int coordBytes = 0;
|
unsigned int coordBytes = 0;
|
||||||
unsigned int coordsWithFlags = 0;
|
unsigned int coordsWithFlags = 0;
|
||||||
while (glyph < glyph_end)
|
while (glyph < glyph_end)
|
||||||
{
|
{
|
||||||
uint8_t flag = (uint8_t) *glyph;
|
uint8_t flag = (uint8_t) *glyph;
|
||||||
glyph++;
|
glyph++;
|
||||||
|
|
||||||
unsigned int repeat = 1;
|
unsigned int repeat = 1;
|
||||||
if (flag & FLAG_REPEAT)
|
if (flag & FLAG_REPEAT)
|
||||||
{
|
{
|
||||||
if (glyph >= glyph_end)
|
if (glyph >= glyph_end)
|
||||||
{
|
{
|
||||||
DEBUG_MSG(SUBSET, nullptr, "Bad flag");
|
DEBUG_MSG(SUBSET, nullptr, "Bad flag");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
repeat = ((uint8_t) *glyph) + 1;
|
repeat = ((uint8_t) *glyph) + 1;
|
||||||
glyph++;
|
glyph++;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int xBytes, yBytes;
|
unsigned int xBytes, yBytes;
|
||||||
xBytes = yBytes = 0;
|
xBytes = yBytes = 0;
|
||||||
if (flag & FLAG_X_SHORT)
|
if (flag & FLAG_X_SHORT) xBytes = 1;
|
||||||
xBytes = 1;
|
else if ((flag & FLAG_X_SAME) == 0) xBytes = 2;
|
||||||
else if ((flag & FLAG_X_SAME) == 0)
|
|
||||||
xBytes = 2;
|
|
||||||
|
|
||||||
if (flag & FLAG_Y_SHORT)
|
if (flag & FLAG_Y_SHORT) yBytes = 1;
|
||||||
yBytes = 1;
|
else if ((flag & FLAG_Y_SAME) == 0) yBytes = 2;
|
||||||
else if ((flag & FLAG_Y_SAME) == 0)
|
|
||||||
yBytes = 2;
|
|
||||||
|
|
||||||
coordBytes += (xBytes + yBytes) * repeat;
|
coordBytes += (xBytes + yBytes) * repeat;
|
||||||
coordsWithFlags += repeat;
|
coordsWithFlags += repeat;
|
||||||
if (coordsWithFlags >= nCoordinates)
|
if (coordsWithFlags >= nCoordinates)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (coordsWithFlags != nCoordinates)
|
if (coordsWithFlags != nCoordinates)
|
||||||
{
|
{
|
||||||
DEBUG_MSG(SUBSET, nullptr, "Expect %d coords to have flags, got flags for %d", nCoordinates, coordsWithFlags);
|
DEBUG_MSG(SUBSET, nullptr, "Expect %d coords to have flags, got flags for %d", nCoordinates, coordsWithFlags);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
glyph += coordBytes;
|
glyph += coordBytes;
|
||||||
|
|
||||||
if (glyph < glyph_end)
|
if (glyph < glyph_end)
|
||||||
*end_offset -= glyph_end - glyph;
|
*end_offset -= glyph_end - glyph;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool get_offsets (hb_codepoint_t glyph,
|
inline bool get_offsets (hb_codepoint_t glyph,
|
||||||
unsigned int *start_offset /* OUT */,
|
unsigned int *start_offset /* OUT */,
|
||||||
unsigned int *end_offset /* OUT */) const
|
unsigned int *end_offset /* OUT */) const
|
||||||
{
|
{
|
||||||
if (unlikely (glyph >= num_glyphs))
|
if (unlikely (glyph >= num_glyphs))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (short_offset)
|
if (short_offset)
|
||||||
{
|
{
|
||||||
const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ.arrayZ;
|
const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ.arrayZ;
|
||||||
*start_offset = 2 * offsets[glyph];
|
*start_offset = 2 * offsets[glyph];
|
||||||
*end_offset = 2 * offsets[glyph + 1];
|
*end_offset = 2 * offsets[glyph + 1];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ.arrayZ;
|
const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ.arrayZ;
|
||||||
|
|
||||||
*start_offset = offsets[glyph];
|
*start_offset = offsets[glyph];
|
||||||
*end_offset = offsets[glyph + 1];
|
*end_offset = offsets[glyph + 1];
|
||||||
|
@ -386,51 +376,51 @@ struct glyf
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool get_instruction_offsets(unsigned int start_offset,
|
inline bool get_instruction_offsets (unsigned int start_offset,
|
||||||
unsigned int end_offset,
|
unsigned int end_offset,
|
||||||
unsigned int *instruction_start /* OUT */,
|
unsigned int *instruction_start /* OUT */,
|
||||||
unsigned int *instruction_end /* OUT */) const
|
unsigned int *instruction_end /* OUT */) const
|
||||||
{
|
{
|
||||||
if (end_offset - start_offset < GlyphHeader::static_size)
|
if (end_offset - start_offset < GlyphHeader::static_size)
|
||||||
{
|
{
|
||||||
*instruction_start = 0;
|
*instruction_start = 0;
|
||||||
*instruction_end = 0;
|
*instruction_end = 0;
|
||||||
return true; /* Empty glyph; no instructions. */
|
return true; /* Empty glyph; no instructions. */
|
||||||
}
|
}
|
||||||
const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table, start_offset);
|
const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table, start_offset);
|
||||||
int16_t num_contours = (int16_t) glyph_header.numberOfContours;
|
int16_t num_contours = (int16_t) glyph_header.numberOfContours;
|
||||||
if (num_contours < 0)
|
if (num_contours < 0)
|
||||||
{
|
{
|
||||||
CompositeGlyphHeader::Iterator composite_it;
|
CompositeGlyphHeader::Iterator composite_it;
|
||||||
if (unlikely (!CompositeGlyphHeader::get_iterator (
|
if (unlikely (!CompositeGlyphHeader::get_iterator (
|
||||||
(const char*) this->glyf_table + start_offset,
|
(const char*) this->glyf_table + start_offset,
|
||||||
end_offset - start_offset, &composite_it))) return false;
|
end_offset - start_offset, &composite_it))) return false;
|
||||||
const CompositeGlyphHeader *last;
|
const CompositeGlyphHeader *last;
|
||||||
do {
|
do {
|
||||||
last = composite_it.current;
|
last = composite_it.current;
|
||||||
} while (composite_it.move_to_next());
|
} while (composite_it.move_to_next ());
|
||||||
|
|
||||||
if ( (uint16_t) last->flags & CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS)
|
if ((uint16_t) last->flags & CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS)
|
||||||
*instruction_start = ((char *) last - (char *) glyf_table->dataZ.arrayZ) + last->get_size();
|
*instruction_start = ((char *) last - (char *) glyf_table->dataZ.arrayZ) + last->get_size ();
|
||||||
else
|
else
|
||||||
*instruction_start = end_offset;
|
*instruction_start = end_offset;
|
||||||
*instruction_end = end_offset;
|
*instruction_end = end_offset;
|
||||||
if (unlikely (*instruction_start > *instruction_end))
|
if (unlikely (*instruction_start > *instruction_end))
|
||||||
{
|
{
|
||||||
DEBUG_MSG(SUBSET, nullptr, "Invalid instruction offset, %d is outside [%d, %d]", *instruction_start, start_offset, end_offset);
|
DEBUG_MSG(SUBSET, nullptr, "Invalid instruction offset, %d is outside [%d, %d]", *instruction_start, start_offset, end_offset);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
unsigned int instruction_length_offset = start_offset + GlyphHeader::static_size + 2 * num_contours;
|
unsigned int instruction_length_offset = start_offset + GlyphHeader::static_size + 2 * num_contours;
|
||||||
if (unlikely (instruction_length_offset + 2 > end_offset))
|
if (unlikely (instruction_length_offset + 2 > end_offset))
|
||||||
{
|
{
|
||||||
DEBUG_MSG(SUBSET, nullptr, "Glyph size is too short, missing field instructionLength.");
|
DEBUG_MSG(SUBSET, nullptr, "Glyph size is too short, missing field instructionLength.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (glyf_table, instruction_length_offset);
|
const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (glyf_table, instruction_length_offset);
|
||||||
unsigned int start = instruction_length_offset + 2;
|
unsigned int start = instruction_length_offset + 2;
|
||||||
unsigned int end = start + (uint16_t) instruction_length;
|
unsigned int end = start + (uint16_t) instruction_length;
|
||||||
if (unlikely (end > end_offset)) // Out of bounds of the current glyph
|
if (unlikely (end > end_offset)) // Out of bounds of the current glyph
|
||||||
|
@ -440,7 +430,7 @@ struct glyf
|
||||||
}
|
}
|
||||||
|
|
||||||
*instruction_start = start;
|
*instruction_start = start;
|
||||||
*instruction_end = end;
|
*instruction_end = end;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -450,7 +440,7 @@ struct glyf
|
||||||
{
|
{
|
||||||
unsigned int start_offset, end_offset;
|
unsigned int start_offset, end_offset;
|
||||||
if (!get_offsets (glyph, &start_offset, &end_offset))
|
if (!get_offsets (glyph, &start_offset, &end_offset))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (end_offset - start_offset < GlyphHeader::static_size)
|
if (end_offset - start_offset < GlyphHeader::static_size)
|
||||||
return true; /* Empty glyph; zero extents. */
|
return true; /* Empty glyph; zero extents. */
|
||||||
|
|
|
@ -47,9 +47,9 @@ struct DeviceRecord
|
||||||
unsigned int sizeDeviceRecord;
|
unsigned int sizeDeviceRecord;
|
||||||
hb_subset_plan_t *subset_plan;
|
hb_subset_plan_t *subset_plan;
|
||||||
|
|
||||||
inline void init(const DeviceRecord *source_device_record,
|
inline void init (const DeviceRecord *source_device_record,
|
||||||
unsigned int sizeDeviceRecord,
|
unsigned int sizeDeviceRecord,
|
||||||
hb_subset_plan_t *subset_plan)
|
hb_subset_plan_t *subset_plan)
|
||||||
{
|
{
|
||||||
this->source_device_record = source_device_record;
|
this->source_device_record = source_device_record;
|
||||||
this->sizeDeviceRecord = sizeDeviceRecord;
|
this->sizeDeviceRecord = sizeDeviceRecord;
|
||||||
|
@ -63,15 +63,12 @@ struct DeviceRecord
|
||||||
|
|
||||||
inline const HBUINT8* operator [] (unsigned int i) const
|
inline const HBUINT8* operator [] (unsigned int i) const
|
||||||
{
|
{
|
||||||
if (unlikely (i >= len())) return nullptr;
|
if (unlikely (i >= len ())) return nullptr;
|
||||||
hb_codepoint_t gid = this->subset_plan->glyphs [i];
|
hb_codepoint_t gid = this->subset_plan->glyphs [i];
|
||||||
|
|
||||||
const HBUINT8* width = &(this->source_device_record->widthsZ[gid]);
|
if (gid >= sizeDeviceRecord - DeviceRecord::min_size)
|
||||||
|
return nullptr;
|
||||||
if (width < ((const HBUINT8 *) this->source_device_record) + sizeDeviceRecord)
|
return &(this->source_device_record->widthsZ[gid]);
|
||||||
return width;
|
|
||||||
else
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -84,18 +81,18 @@ struct DeviceRecord
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
|
|
||||||
unsigned int size = get_size (subset_view.len());
|
unsigned int size = get_size (subset_view.len ());
|
||||||
if (unlikely (!c->allocate_size<DeviceRecord> (size)))
|
if (unlikely (!c->allocate_size<DeviceRecord> (size)))
|
||||||
{
|
{
|
||||||
DEBUG_MSG (SUBSET, nullptr, "Couldn't allocate enough space for DeviceRecord: %d.",
|
DEBUG_MSG(SUBSET, nullptr, "Couldn't allocate enough space for DeviceRecord: %d.",
|
||||||
size);
|
size);
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->pixelSize.set (subset_view.source_device_record->pixelSize);
|
this->pixelSize.set (subset_view.source_device_record->pixelSize);
|
||||||
this->maxWidth.set (subset_view.source_device_record->maxWidth);
|
this->maxWidth.set (subset_view.source_device_record->maxWidth);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < subset_view.len(); i++)
|
for (unsigned int i = 0; i < subset_view.len (); i++)
|
||||||
{
|
{
|
||||||
const HBUINT8 *width = subset_view[i];
|
const HBUINT8 *width = subset_view[i];
|
||||||
if (!width)
|
if (!width)
|
||||||
|
@ -135,8 +132,10 @@ struct hdmx
|
||||||
|
|
||||||
inline const DeviceRecord& operator [] (unsigned int i) const
|
inline const DeviceRecord& operator [] (unsigned int i) const
|
||||||
{
|
{
|
||||||
if (unlikely (i >= numRecords)) return Null(DeviceRecord);
|
/* XXX Null(DeviceRecord) is NOT safe as it's num-glyphs lengthed.
|
||||||
return StructAtOffset<DeviceRecord> (&this->dataZ, i * sizeDeviceRecord);
|
* https://github.com/harfbuzz/harfbuzz/issues/1300 */
|
||||||
|
if (unlikely (i >= numRecords)) return Null (DeviceRecord);
|
||||||
|
return StructAtOffset<DeviceRecord> (&this->firstDeviceRecord, i * sizeDeviceRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool serialize (hb_serialize_context_t *c, const hdmx *source_hdmx, hb_subset_plan_t *plan)
|
inline bool serialize (hb_serialize_context_t *c, const hdmx *source_hdmx, hb_subset_plan_t *plan)
|
||||||
|
@ -200,19 +199,19 @@ struct hdmx
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return_trace (c->check_struct (this) && version == 0 &&
|
return_trace (c->check_struct (this) &&
|
||||||
!hb_unsigned_mul_overflows (numRecords, sizeDeviceRecord) &&
|
!hb_unsigned_mul_overflows (numRecords, sizeDeviceRecord) &&
|
||||||
sizeDeviceRecord >= DeviceRecord::min_size &&
|
sizeDeviceRecord >= DeviceRecord::min_size &&
|
||||||
c->check_range (this, get_size()));
|
c->check_range (this, get_size ()));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 version; /* Table version number (0) */
|
HBUINT16 version; /* Table version number (0) */
|
||||||
HBUINT16 numRecords; /* Number of device records. */
|
HBUINT16 numRecords; /* Number of device records. */
|
||||||
HBUINT32 sizeDeviceRecord; /* Size of a device record, 32-bit aligned. */
|
HBUINT32 sizeDeviceRecord; /* Size of a device record, 32-bit aligned. */
|
||||||
UnsizedArrayOf<HBUINT8> dataZ; /* Array of device records. */
|
DeviceRecord firstDeviceRecord; /* Array of device records. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY (8, dataZ);
|
DEFINE_SIZE_MIN (8);
|
||||||
};
|
};
|
||||||
|
|
||||||
} /* namespace OT */
|
} /* namespace OT */
|
||||||
|
|
|
@ -66,10 +66,10 @@ struct hmtxvmtx
|
||||||
|
|
||||||
|
|
||||||
inline bool subset_update_header (hb_subset_plan_t *plan,
|
inline bool subset_update_header (hb_subset_plan_t *plan,
|
||||||
unsigned int num_hmetrics) const
|
unsigned int num_hmetrics) const
|
||||||
{
|
{
|
||||||
hb_blob_t *src_blob = hb_sanitize_context_t().reference_table<H> (plan->source, H::tableTag);
|
hb_blob_t *src_blob = hb_sanitize_context_t ().reference_table<H> (plan->source, H::tableTag);
|
||||||
hb_blob_t *dest_blob = hb_blob_copy_writable_or_fail(src_blob);
|
hb_blob_t *dest_blob = hb_blob_copy_writable_or_fail (src_blob);
|
||||||
hb_blob_destroy (src_blob);
|
hb_blob_destroy (src_blob);
|
||||||
|
|
||||||
if (unlikely (!dest_blob)) {
|
if (unlikely (!dest_blob)) {
|
||||||
|
@ -96,15 +96,15 @@ struct hmtxvmtx
|
||||||
hb_vector_t<hb_codepoint_t> &gids = plan->glyphs;
|
hb_vector_t<hb_codepoint_t> &gids = plan->glyphs;
|
||||||
unsigned int num_advances = gids.len;
|
unsigned int num_advances = gids.len;
|
||||||
unsigned int last_advance = _mtx.get_advance (gids[num_advances - 1]);
|
unsigned int last_advance = _mtx.get_advance (gids[num_advances - 1]);
|
||||||
while (num_advances > 1
|
while (num_advances > 1 &&
|
||||||
&& last_advance == _mtx.get_advance (gids[num_advances - 2]))
|
last_advance == _mtx.get_advance (gids[num_advances - 2]))
|
||||||
{
|
{
|
||||||
num_advances--;
|
num_advances--;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* alloc the new table */
|
/* alloc the new table */
|
||||||
size_t dest_sz = num_advances * 4
|
size_t dest_sz = num_advances * 4
|
||||||
+ (gids.len - num_advances) * 2;
|
+ (gids.len - num_advances) * 2;
|
||||||
void *dest = (void *) malloc (dest_sz);
|
void *dest = (void *) malloc (dest_sz);
|
||||||
if (unlikely (!dest))
|
if (unlikely (!dest))
|
||||||
{
|
{
|
||||||
|
@ -277,7 +277,7 @@ struct hmtxvmtx
|
||||||
hb_font_t *font) const
|
hb_font_t *font) const
|
||||||
{
|
{
|
||||||
unsigned int advance = get_advance (glyph);
|
unsigned int advance = get_advance (glyph);
|
||||||
if (likely(glyph < num_metrics))
|
if (likely (glyph < num_metrics))
|
||||||
{
|
{
|
||||||
advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?!
|
advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?!
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,8 +131,8 @@ struct RecordArrayOf : SortedArrayOf<Record<Type> >
|
||||||
/* If we want to allow non-sorted data, we can lsearch(). */
|
/* If we want to allow non-sorted data, we can lsearch(). */
|
||||||
int i = this->/*lsearch*/bsearch (tag);
|
int i = this->/*lsearch*/bsearch (tag);
|
||||||
if (i != -1) {
|
if (i != -1) {
|
||||||
if (index) *index = i;
|
if (index) *index = i;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
if (index) *index = Index::NOT_FOUND_INDEX;
|
if (index) *index = Index::NOT_FOUND_INDEX;
|
||||||
return false;
|
return false;
|
||||||
|
@ -526,21 +526,21 @@ struct FeatureParams
|
||||||
{
|
{
|
||||||
if (tag == HB_TAG ('s','i','z','e'))
|
if (tag == HB_TAG ('s','i','z','e'))
|
||||||
return u.size;
|
return u.size;
|
||||||
return Null(FeatureParamsSize);
|
return Null (FeatureParamsSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const FeatureParamsStylisticSet& get_stylistic_set_params (hb_tag_t tag) const
|
inline const FeatureParamsStylisticSet& get_stylistic_set_params (hb_tag_t tag) const
|
||||||
{
|
{
|
||||||
if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
|
if ((tag & 0xFFFF0000u) == HB_TAG ('s','s','\0','\0')) /* ssXX */
|
||||||
return u.stylisticSet;
|
return u.stylisticSet;
|
||||||
return Null(FeatureParamsStylisticSet);
|
return Null (FeatureParamsStylisticSet);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const FeatureParamsCharacterVariants& get_character_variants_params (hb_tag_t tag) const
|
inline const FeatureParamsCharacterVariants& get_character_variants_params (hb_tag_t tag) const
|
||||||
{
|
{
|
||||||
if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
|
if ((tag & 0xFFFF0000u) == HB_TAG ('c','v','\0','\0')) /* cvXX */
|
||||||
return u.characterVariants;
|
return u.characterVariants;
|
||||||
return Null(FeatureParamsCharacterVariants);
|
return Null (FeatureParamsCharacterVariants);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -704,7 +704,7 @@ struct Lookup
|
||||||
for (unsigned int i = 0; i < count; i++) {
|
for (unsigned int i = 0; i < count; i++) {
|
||||||
typename context_t::return_t r = get_subtable<TSubTable> (i).dispatch (c, lookup_type);
|
typename context_t::return_t r = get_subtable<TSubTable> (i).dispatch (c, lookup_type);
|
||||||
if (c->stop_sublookup_iteration (r))
|
if (c->stop_sublookup_iteration (r))
|
||||||
return_trace (r);
|
return_trace (r);
|
||||||
}
|
}
|
||||||
return_trace (c->default_return_value ());
|
return_trace (c->default_return_value ());
|
||||||
}
|
}
|
||||||
|
@ -790,7 +790,7 @@ struct Lookup
|
||||||
unsigned int type = get_subtable<TSubTable> (0).u.extension.get_type ();
|
unsigned int type = get_subtable<TSubTable> (0).u.extension.get_type ();
|
||||||
unsigned int count = get_subtable_count ();
|
unsigned int count = get_subtable_count ();
|
||||||
for (unsigned int i = 1; i < count; i++)
|
for (unsigned int i = 1; i < count; i++)
|
||||||
if (get_subtable<TSubTable> (i).u.extension.get_type () != type)
|
if (get_subtable<TSubTable> (i).u.extension.get_type () != type)
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
}
|
}
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
|
@ -854,7 +854,7 @@ struct CoverageFormat1
|
||||||
unsigned int count = glyphArray.len;
|
unsigned int count = glyphArray.len;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (glyphs->has (glyphArray[i]))
|
if (glyphs->has (glyphArray[i]))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
|
inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
|
||||||
|
@ -920,7 +920,7 @@ struct CoverageFormat2
|
||||||
unsigned int num_ranges = 1;
|
unsigned int num_ranges = 1;
|
||||||
for (unsigned int i = 1; i < num_glyphs; i++)
|
for (unsigned int i = 1; i < num_glyphs; i++)
|
||||||
if (glyphs[i - 1] + 1 != glyphs[i])
|
if (glyphs[i - 1] + 1 != glyphs[i])
|
||||||
num_ranges++;
|
num_ranges++;
|
||||||
rangeRecord.len.set (num_ranges);
|
rangeRecord.len.set (num_ranges);
|
||||||
if (unlikely (!c->extend (rangeRecord))) return_trace (false);
|
if (unlikely (!c->extend (rangeRecord))) return_trace (false);
|
||||||
|
|
||||||
|
@ -932,9 +932,9 @@ struct CoverageFormat2
|
||||||
range++;
|
range++;
|
||||||
rangeRecord[range].start = glyphs[i];
|
rangeRecord[range].start = glyphs[i];
|
||||||
rangeRecord[range].value.set (i);
|
rangeRecord[range].value.set (i);
|
||||||
rangeRecord[range].end = glyphs[i];
|
rangeRecord[range].end = glyphs[i];
|
||||||
} else {
|
} else {
|
||||||
rangeRecord[range].end = glyphs[i];
|
rangeRecord[range].end = glyphs[i];
|
||||||
}
|
}
|
||||||
glyphs += num_glyphs;
|
glyphs += num_glyphs;
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
|
@ -952,7 +952,7 @@ struct CoverageFormat2
|
||||||
unsigned int count = rangeRecord.len;
|
unsigned int count = rangeRecord.len;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (rangeRecord[i].intersects (glyphs))
|
if (rangeRecord[i].intersects (glyphs))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
|
inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
|
||||||
|
@ -964,9 +964,9 @@ struct CoverageFormat2
|
||||||
if (range.value <= index &&
|
if (range.value <= index &&
|
||||||
index < (unsigned int) range.value + (range.end - range.start) &&
|
index < (unsigned int) range.value + (range.end - range.start) &&
|
||||||
range.intersects (glyphs))
|
range.intersects (glyphs))
|
||||||
return true;
|
return true;
|
||||||
else if (index < range.value)
|
else if (index < range.value)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -976,7 +976,7 @@ struct CoverageFormat2
|
||||||
unsigned int count = rangeRecord.len;
|
unsigned int count = rangeRecord.len;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
|
if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -992,8 +992,8 @@ struct CoverageFormat2
|
||||||
j = c->rangeRecord.len ? c->rangeRecord[0].start : 0;
|
j = c->rangeRecord.len ? c->rangeRecord[0].start : 0;
|
||||||
if (unlikely (c->rangeRecord[0].start > c->rangeRecord[0].end))
|
if (unlikely (c->rangeRecord[0].start > c->rangeRecord[0].end))
|
||||||
{
|
{
|
||||||
/* Broken table. Skip. */
|
/* Broken table. Skip. */
|
||||||
i = c->rangeRecord.len;
|
i = c->rangeRecord.len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline void fini (void) {}
|
inline void fini (void) {}
|
||||||
|
@ -1002,7 +1002,7 @@ struct CoverageFormat2
|
||||||
{
|
{
|
||||||
if (j >= c->rangeRecord[i].end)
|
if (j >= c->rangeRecord[i].end)
|
||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
if (more ())
|
if (more ())
|
||||||
{
|
{
|
||||||
hb_codepoint_t old = j;
|
hb_codepoint_t old = j;
|
||||||
|
@ -1060,7 +1060,7 @@ struct Coverage
|
||||||
unsigned int num_ranges = 1;
|
unsigned int num_ranges = 1;
|
||||||
for (unsigned int i = 1; i < num_glyphs; i++)
|
for (unsigned int i = 1; i < num_glyphs; i++)
|
||||||
if (glyphs[i - 1] + 1 != glyphs[i])
|
if (glyphs[i - 1] + 1 != glyphs[i])
|
||||||
num_ranges++;
|
num_ranges++;
|
||||||
u.format.set (num_glyphs * 2 < num_ranges * 3 ? 1 : 2);
|
u.format.set (num_glyphs * 2 < num_ranges * 3 ? 1 : 2);
|
||||||
switch (u.format)
|
switch (u.format)
|
||||||
{
|
{
|
||||||
|
@ -1213,7 +1213,7 @@ struct ClassDefFormat1
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if (classValue[i])
|
if (classValue[i])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (start != i)
|
if (start != i)
|
||||||
if (unlikely (!glyphs->add_range (startGlyph + start, startGlyph + i)))
|
if (unlikely (!glyphs->add_range (startGlyph + start, startGlyph + i)))
|
||||||
|
@ -1232,10 +1232,7 @@ struct ClassDefFormat1
|
||||||
inline bool add_class (set_t *glyphs, unsigned int klass) const {
|
inline bool add_class (set_t *glyphs, unsigned int klass) const {
|
||||||
unsigned int count = classValue.len;
|
unsigned int count = classValue.len;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
if (classValue[i] == klass) glyphs->add (startGlyph + i);
|
||||||
if (classValue[i] == klass)
|
|
||||||
glyphs->add (startGlyph + i);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1246,8 +1243,7 @@ struct ClassDefFormat1
|
||||||
hb_codepoint_t end = startGlyph + classValue.len;
|
hb_codepoint_t end = startGlyph + classValue.len;
|
||||||
for (hb_codepoint_t iter = startGlyph - 1;
|
for (hb_codepoint_t iter = startGlyph - 1;
|
||||||
hb_set_next (glyphs, &iter) && iter < end;)
|
hb_set_next (glyphs, &iter) && iter < end;)
|
||||||
if (classValue[iter - start])
|
if (classValue[iter - start]) return true;
|
||||||
return true;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
|
inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
|
||||||
|
@ -1256,18 +1252,15 @@ struct ClassDefFormat1
|
||||||
{
|
{
|
||||||
/* Match if there's any glyph that is not listed! */
|
/* Match if there's any glyph that is not listed! */
|
||||||
hb_codepoint_t g = HB_SET_VALUE_INVALID;
|
hb_codepoint_t g = HB_SET_VALUE_INVALID;
|
||||||
if (!hb_set_next (glyphs, &g))
|
if (!hb_set_next (glyphs, &g)) return false;
|
||||||
return false;
|
if (g < startGlyph) return true;
|
||||||
if (g < startGlyph)
|
|
||||||
return true;
|
|
||||||
g = startGlyph + count - 1;
|
g = startGlyph + count - 1;
|
||||||
if (hb_set_next (glyphs, &g))
|
if (hb_set_next (glyphs, &g)) return true;
|
||||||
return true;
|
|
||||||
/* Fall through. */
|
/* Fall through. */
|
||||||
}
|
}
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (classValue[i] == klass && glyphs->has (startGlyph + i))
|
if (classValue[i] == klass && glyphs->has (startGlyph + i))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1317,7 +1310,7 @@ struct ClassDefFormat2
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if (rangeRecord[i].value == klass)
|
if (rangeRecord[i].value == klass)
|
||||||
if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
|
if (unlikely (!rangeRecord[i].add_coverage (glyphs)))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -1329,7 +1322,7 @@ struct ClassDefFormat2
|
||||||
unsigned int count = rangeRecord.len;
|
unsigned int count = rangeRecord.len;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (rangeRecord[i].intersects (glyphs))
|
if (rangeRecord[i].intersects (glyphs))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const
|
inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const
|
||||||
|
@ -1348,12 +1341,12 @@ struct ClassDefFormat2
|
||||||
g = rangeRecord[i].end;
|
g = rangeRecord[i].end;
|
||||||
}
|
}
|
||||||
if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g))
|
if (g != HB_SET_VALUE_INVALID && hb_set_next (glyphs, &g))
|
||||||
return true;
|
return true;
|
||||||
/* Fall through. */
|
/* Fall through. */
|
||||||
}
|
}
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs))
|
if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1498,7 +1491,7 @@ struct VarRegionList
|
||||||
int coord = i < coord_len ? coords[i] : 0;
|
int coord = i < coord_len ? coords[i] : 0;
|
||||||
float factor = axes[i].evaluate (coord);
|
float factor = axes[i].evaluate (coord);
|
||||||
if (factor == 0.f)
|
if (factor == 0.f)
|
||||||
return 0.;
|
return 0.;
|
||||||
v *= factor;
|
v *= factor;
|
||||||
}
|
}
|
||||||
return v;
|
return v;
|
||||||
|
@ -1582,7 +1575,7 @@ struct VarData
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return_trace (c->check_struct (this) &&
|
return_trace (c->check_struct (this) &&
|
||||||
regionIndices.sanitize(c) &&
|
regionIndices.sanitize (c) &&
|
||||||
shortCount <= regionIndices.len &&
|
shortCount <= regionIndices.len &&
|
||||||
c->check_range (&StructAfter<HBUINT8> (regionIndices),
|
c->check_range (&StructAfter<HBUINT8> (regionIndices),
|
||||||
itemCount,
|
itemCount,
|
||||||
|
@ -1714,7 +1707,7 @@ struct ConditionSet
|
||||||
unsigned int count = conditions.len;
|
unsigned int count = conditions.len;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (!(this+conditions.arrayZ[i]).evaluate (coords, coord_len))
|
if (!(this+conditions.arrayZ[i]).evaluate (coords, coord_len))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1972,7 +1965,7 @@ struct DeviceHeader
|
||||||
|
|
||||||
struct Device
|
struct Device
|
||||||
{
|
{
|
||||||
inline hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store=Null(VariationStore)) const
|
inline hb_position_t get_x_delta (hb_font_t *font, const VariationStore &store=Null (VariationStore)) const
|
||||||
{
|
{
|
||||||
switch (u.b.format)
|
switch (u.b.format)
|
||||||
{
|
{
|
||||||
|
@ -1984,7 +1977,7 @@ struct Device
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store=Null(VariationStore)) const
|
inline hb_position_t get_y_delta (hb_font_t *font, const VariationStore &store=Null (VariationStore)) const
|
||||||
{
|
{
|
||||||
switch (u.b.format)
|
switch (u.b.format)
|
||||||
{
|
{
|
||||||
|
|
|
@ -213,7 +213,7 @@ struct ValueFormat : HBUINT16
|
||||||
|
|
||||||
for (unsigned int i = 0; i < count; i++) {
|
for (unsigned int i = 0; i < count; i++) {
|
||||||
if (!sanitize_value_devices (c, base, values))
|
if (!sanitize_value_devices (c, base, values))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
values += len;
|
values += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ struct ValueFormat : HBUINT16
|
||||||
|
|
||||||
for (unsigned int i = 0; i < count; i++) {
|
for (unsigned int i = 0; i < count; i++) {
|
||||||
if (!sanitize_value_devices (c, base, values))
|
if (!sanitize_value_devices (c, base, values))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
values += stride;
|
values += stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,7 +634,7 @@ struct PairSet
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
if (glyphs->has (record->secondGlyph))
|
if (glyphs->has (record->secondGlyph))
|
||||||
return true;
|
return true;
|
||||||
record = &StructAtOffset<const PairValueRecord> (record, record_size);
|
record = &StructAtOffset<const PairValueRecord> (record, record_size);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -675,9 +675,9 @@ struct PairSet
|
||||||
const PairValueRecord *record = &StructAtOffset<PairValueRecord> (&firstPairValueRecord, record_size * mid);
|
const PairValueRecord *record = &StructAtOffset<PairValueRecord> (&firstPairValueRecord, record_size * mid);
|
||||||
hb_codepoint_t mid_x = record->secondGlyph;
|
hb_codepoint_t mid_x = record->secondGlyph;
|
||||||
if (x < mid_x)
|
if (x < mid_x)
|
||||||
max = mid - 1;
|
max = mid - 1;
|
||||||
else if (x > mid_x)
|
else if (x > mid_x)
|
||||||
min = mid + 1;
|
min = mid + 1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Note the intentional use of "|" instead of short-circuit "||". */
|
/* Note the intentional use of "|" instead of short-circuit "||". */
|
||||||
|
@ -734,10 +734,10 @@ struct PairPosFormat1
|
||||||
for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
|
for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
|
||||||
{
|
{
|
||||||
if (unlikely (iter.get_coverage () >= count))
|
if (unlikely (iter.get_coverage () >= count))
|
||||||
break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
|
break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
|
||||||
if (glyphs->has (iter.get_glyph ()) &&
|
if (glyphs->has (iter.get_glyph ()) &&
|
||||||
(this+pairSet[iter.get_coverage ()]).intersects (glyphs, valueFormat))
|
(this+pairSet[iter.get_coverage ()]).intersects (glyphs, valueFormat))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1421,7 +1421,7 @@ struct MarkMarkPosFormat1
|
||||||
if (id1 == 0) /* Marks belonging to the same base. */
|
if (id1 == 0) /* Marks belonging to the same base. */
|
||||||
goto good;
|
goto good;
|
||||||
else if (comp1 == comp2) /* Marks belonging to the same ligature component. */
|
else if (comp1 == comp2) /* Marks belonging to the same ligature component. */
|
||||||
goto good;
|
goto good;
|
||||||
} else {
|
} else {
|
||||||
/* If ligature ids don't match, it may be the case that one of the marks
|
/* If ligature ids don't match, it may be the case that one of the marks
|
||||||
* itself is a ligature. In which case match. */
|
* itself is a ligature. In which case match. */
|
||||||
|
|
|
@ -588,7 +588,7 @@ struct AlternateSubstFormat1
|
||||||
for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
|
for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
|
||||||
{
|
{
|
||||||
if (unlikely (iter.get_coverage () >= count))
|
if (unlikely (iter.get_coverage () >= count))
|
||||||
break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
|
break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
|
||||||
if (c->glyphs->has (iter.get_glyph ()))
|
if (c->glyphs->has (iter.get_glyph ()))
|
||||||
(this+alternateSet[iter.get_coverage ()]).closure (c);
|
(this+alternateSet[iter.get_coverage ()]).closure (c);
|
||||||
}
|
}
|
||||||
|
@ -602,7 +602,7 @@ struct AlternateSubstFormat1
|
||||||
for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
|
for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
|
||||||
{
|
{
|
||||||
if (unlikely (iter.get_coverage () >= count))
|
if (unlikely (iter.get_coverage () >= count))
|
||||||
break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
|
break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
|
||||||
(this+alternateSet[iter.get_coverage ()]).collect_glyphs (c);
|
(this+alternateSet[iter.get_coverage ()]).collect_glyphs (c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,14 +100,14 @@ struct hb_closure_context_t :
|
||||||
|
|
||||||
hb_closure_context_t (hb_face_t *face_,
|
hb_closure_context_t (hb_face_t *face_,
|
||||||
hb_set_t *glyphs_,
|
hb_set_t *glyphs_,
|
||||||
hb_map_t *done_lookups_,
|
hb_map_t *done_lookups_,
|
||||||
unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
|
unsigned int nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
|
||||||
face (face_),
|
face (face_),
|
||||||
glyphs (glyphs_),
|
glyphs (glyphs_),
|
||||||
recurse_func (nullptr),
|
recurse_func (nullptr),
|
||||||
nesting_level_left (nesting_level_left_),
|
nesting_level_left (nesting_level_left_),
|
||||||
debug_depth (0),
|
debug_depth (0),
|
||||||
done_lookups (done_lookups_) {}
|
done_lookups (done_lookups_) {}
|
||||||
|
|
||||||
~hb_closure_context_t (void)
|
~hb_closure_context_t (void)
|
||||||
{
|
{
|
||||||
|
@ -291,14 +291,14 @@ struct hb_ot_apply_context_t :
|
||||||
};
|
};
|
||||||
|
|
||||||
inline may_match_t may_match (const hb_glyph_info_t &info,
|
inline may_match_t may_match (const hb_glyph_info_t &info,
|
||||||
const HBUINT16 *glyph_data) const
|
const HBUINT16 *glyph_data) const
|
||||||
{
|
{
|
||||||
if (!(info.mask & mask) ||
|
if (!(info.mask & mask) ||
|
||||||
(syllable && syllable != info.syllable ()))
|
(syllable && syllable != info.syllable ()))
|
||||||
return MATCH_NO;
|
return MATCH_NO;
|
||||||
|
|
||||||
if (match_func)
|
if (match_func)
|
||||||
return match_func (info.codepoint, *glyph_data, match_data) ? MATCH_YES : MATCH_NO;
|
return match_func (info.codepoint, *glyph_data, match_data) ? MATCH_YES : MATCH_NO;
|
||||||
|
|
||||||
return MATCH_MAYBE;
|
return MATCH_MAYBE;
|
||||||
}
|
}
|
||||||
|
@ -852,9 +852,9 @@ static inline bool match_input (hb_ot_apply_context_t *c,
|
||||||
* component, otherwise we shouldn't ligate them... */
|
* component, otherwise we shouldn't ligate them... */
|
||||||
if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp)
|
if (first_lig_id != this_lig_id || first_lig_comp != this_lig_comp)
|
||||||
{
|
{
|
||||||
/* ...unless, we are attached to a base ligature and that base
|
/* ...unless, we are attached to a base ligature and that base
|
||||||
* ligature is ignorable. */
|
* ligature is ignorable. */
|
||||||
if (ligbase == LIGBASE_NOT_CHECKED)
|
if (ligbase == LIGBASE_NOT_CHECKED)
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
const hb_glyph_info_t *out = buffer->out_info;
|
const hb_glyph_info_t *out = buffer->out_info;
|
||||||
|
@ -876,7 +876,7 @@ static inline bool match_input (hb_ot_apply_context_t *c,
|
||||||
ligbase = LIGBASE_MAY_NOT_SKIP;
|
ligbase = LIGBASE_MAY_NOT_SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ligbase == LIGBASE_MAY_NOT_SKIP)
|
if (ligbase == LIGBASE_MAY_NOT_SKIP)
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -977,7 +977,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c,
|
||||||
{
|
{
|
||||||
if (is_ligature)
|
if (is_ligature)
|
||||||
{
|
{
|
||||||
unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
|
unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
|
||||||
if (this_comp == 0)
|
if (this_comp == 0)
|
||||||
this_comp = last_num_components;
|
this_comp = last_num_components;
|
||||||
unsigned int new_lig_comp = components_so_far - last_num_components +
|
unsigned int new_lig_comp = components_so_far - last_num_components +
|
||||||
|
@ -999,7 +999,7 @@ static inline bool ligate_input (hb_ot_apply_context_t *c,
|
||||||
/* Re-adjust components for any marks following. */
|
/* Re-adjust components for any marks following. */
|
||||||
for (unsigned int i = buffer->idx; i < buffer->len; i++) {
|
for (unsigned int i = buffer->idx; i < buffer->len; i++) {
|
||||||
if (last_lig_id == _hb_glyph_info_get_lig_id (&buffer->info[i])) {
|
if (last_lig_id == _hb_glyph_info_get_lig_id (&buffer->info[i])) {
|
||||||
unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->info[i]);
|
unsigned int this_comp = _hb_glyph_info_get_lig_comp (&buffer->info[i]);
|
||||||
if (!this_comp)
|
if (!this_comp)
|
||||||
break;
|
break;
|
||||||
unsigned int new_lig_comp = components_so_far - last_num_components +
|
unsigned int new_lig_comp = components_so_far - last_num_components +
|
||||||
|
@ -1133,7 +1133,7 @@ static inline bool apply_lookup (hb_ot_apply_context_t *c,
|
||||||
int delta = new_len - orig_len;
|
int delta = new_len - orig_len;
|
||||||
|
|
||||||
if (!delta)
|
if (!delta)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Recursed lookup changed buffer len. Adjust.
|
/* Recursed lookup changed buffer len. Adjust.
|
||||||
*
|
*
|
||||||
|
@ -1376,7 +1376,7 @@ struct RuleSet
|
||||||
unsigned int num_rules = rule.len;
|
unsigned int num_rules = rule.len;
|
||||||
for (unsigned int i = 0; i < num_rules; i++)
|
for (unsigned int i = 0; i < num_rules; i++)
|
||||||
if ((this+rule[i]).intersects (glyphs, lookup_context))
|
if ((this+rule[i]).intersects (glyphs, lookup_context))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1403,7 +1403,7 @@ struct RuleSet
|
||||||
for (unsigned int i = 0; i < num_rules; i++)
|
for (unsigned int i = 0; i < num_rules; i++)
|
||||||
{
|
{
|
||||||
if ((this+rule[i]).would_apply (c, lookup_context))
|
if ((this+rule[i]).would_apply (c, lookup_context))
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
}
|
}
|
||||||
|
@ -1415,7 +1415,7 @@ struct RuleSet
|
||||||
for (unsigned int i = 0; i < num_rules; i++)
|
for (unsigned int i = 0; i < num_rules; i++)
|
||||||
{
|
{
|
||||||
if ((this+rule[i]).apply (c, lookup_context))
|
if ((this+rule[i]).apply (c, lookup_context))
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
}
|
}
|
||||||
|
@ -1448,10 +1448,10 @@ struct ContextFormat1
|
||||||
for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
|
for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
|
||||||
{
|
{
|
||||||
if (unlikely (iter.get_coverage () >= count))
|
if (unlikely (iter.get_coverage () >= count))
|
||||||
break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
|
break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
|
||||||
if (glyphs->has (iter.get_glyph ()) &&
|
if (glyphs->has (iter.get_glyph ()) &&
|
||||||
(this+ruleSet[iter.get_coverage ()]).intersects (glyphs, lookup_context))
|
(this+ruleSet[iter.get_coverage ()]).intersects (glyphs, lookup_context))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1469,7 +1469,7 @@ struct ContextFormat1
|
||||||
for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
|
for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
|
||||||
{
|
{
|
||||||
if (unlikely (iter.get_coverage () >= count))
|
if (unlikely (iter.get_coverage () >= count))
|
||||||
break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
|
break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
|
||||||
if (c->glyphs->has (iter.get_glyph ()))
|
if (c->glyphs->has (iter.get_glyph ()))
|
||||||
(this+ruleSet[iter.get_coverage ()]).closure (c, lookup_context);
|
(this+ruleSet[iter.get_coverage ()]).closure (c, lookup_context);
|
||||||
}
|
}
|
||||||
|
@ -1564,7 +1564,7 @@ struct ContextFormat2
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (class_def.intersects_class (glyphs, i) &&
|
if (class_def.intersects_class (glyphs, i) &&
|
||||||
(this+ruleSet[i]).intersects (glyphs, lookup_context))
|
(this+ruleSet[i]).intersects (glyphs, lookup_context))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1868,15 +1868,15 @@ static inline void chain_context_closure_lookup (hb_closure_context_t *c,
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c,
|
static inline void chain_context_collect_glyphs_lookup (hb_collect_glyphs_context_t *c,
|
||||||
unsigned int backtrackCount,
|
unsigned int backtrackCount,
|
||||||
const HBUINT16 backtrack[],
|
const HBUINT16 backtrack[],
|
||||||
unsigned int inputCount, /* Including the first glyph (not matched) */
|
unsigned int inputCount, /* Including the first glyph (not matched) */
|
||||||
const HBUINT16 input[], /* Array of input values--start with second glyph */
|
const HBUINT16 input[], /* Array of input values--start with second glyph */
|
||||||
unsigned int lookaheadCount,
|
unsigned int lookaheadCount,
|
||||||
const HBUINT16 lookahead[],
|
const HBUINT16 lookahead[],
|
||||||
unsigned int lookupCount,
|
unsigned int lookupCount,
|
||||||
const LookupRecord lookupRecord[],
|
const LookupRecord lookupRecord[],
|
||||||
ChainContextCollectGlyphsLookupContext &lookup_context)
|
ChainContextCollectGlyphsLookupContext &lookup_context)
|
||||||
{
|
{
|
||||||
collect_array (c, c->before,
|
collect_array (c, c->before,
|
||||||
backtrackCount, backtrack,
|
backtrackCount, backtrack,
|
||||||
|
@ -1934,10 +1934,10 @@ static inline bool chain_context_apply_lookup (hb_ot_apply_context_t *c,
|
||||||
lookup_context.funcs.match, lookup_context.match_data[2],
|
lookup_context.funcs.match, lookup_context.match_data[2],
|
||||||
match_length, &end_index)
|
match_length, &end_index)
|
||||||
&& (c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index),
|
&& (c->buffer->unsafe_to_break_from_outbuffer (start_index, end_index),
|
||||||
apply_lookup (c,
|
apply_lookup (c,
|
||||||
inputCount, match_positions,
|
inputCount, match_positions,
|
||||||
lookupCount, lookupRecord,
|
lookupCount, lookupRecord,
|
||||||
match_length));
|
match_length));
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ChainRule
|
struct ChainRule
|
||||||
|
@ -2044,7 +2044,7 @@ struct ChainRuleSet
|
||||||
unsigned int num_rules = rule.len;
|
unsigned int num_rules = rule.len;
|
||||||
for (unsigned int i = 0; i < num_rules; i++)
|
for (unsigned int i = 0; i < num_rules; i++)
|
||||||
if ((this+rule[i]).intersects (glyphs, lookup_context))
|
if ((this+rule[i]).intersects (glyphs, lookup_context))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
|
inline void closure (hb_closure_context_t *c, ChainContextClosureLookupContext &lookup_context) const
|
||||||
|
@ -2069,7 +2069,7 @@ struct ChainRuleSet
|
||||||
unsigned int num_rules = rule.len;
|
unsigned int num_rules = rule.len;
|
||||||
for (unsigned int i = 0; i < num_rules; i++)
|
for (unsigned int i = 0; i < num_rules; i++)
|
||||||
if ((this+rule[i]).would_apply (c, lookup_context))
|
if ((this+rule[i]).would_apply (c, lookup_context))
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
|
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
}
|
}
|
||||||
|
@ -2080,7 +2080,7 @@ struct ChainRuleSet
|
||||||
unsigned int num_rules = rule.len;
|
unsigned int num_rules = rule.len;
|
||||||
for (unsigned int i = 0; i < num_rules; i++)
|
for (unsigned int i = 0; i < num_rules; i++)
|
||||||
if ((this+rule[i]).apply (c, lookup_context))
|
if ((this+rule[i]).apply (c, lookup_context))
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
|
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
}
|
}
|
||||||
|
@ -2112,10 +2112,10 @@ struct ChainContextFormat1
|
||||||
for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
|
for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
|
||||||
{
|
{
|
||||||
if (unlikely (iter.get_coverage () >= count))
|
if (unlikely (iter.get_coverage () >= count))
|
||||||
break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
|
break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
|
||||||
if (glyphs->has (iter.get_glyph ()) &&
|
if (glyphs->has (iter.get_glyph ()) &&
|
||||||
(this+ruleSet[iter.get_coverage ()]).intersects (glyphs, lookup_context))
|
(this+ruleSet[iter.get_coverage ()]).intersects (glyphs, lookup_context))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2133,7 +2133,7 @@ struct ChainContextFormat1
|
||||||
for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
|
for (Coverage::Iter iter (this+coverage); iter.more (); iter.next ())
|
||||||
{
|
{
|
||||||
if (unlikely (iter.get_coverage () >= count))
|
if (unlikely (iter.get_coverage () >= count))
|
||||||
break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
|
break; /* Work around malicious fonts. https://github.com/harfbuzz/harfbuzz/issues/363 */
|
||||||
if (c->glyphs->has (iter.get_glyph ()))
|
if (c->glyphs->has (iter.get_glyph ()))
|
||||||
(this+ruleSet[iter.get_coverage ()]).closure (c, lookup_context);
|
(this+ruleSet[iter.get_coverage ()]).closure (c, lookup_context);
|
||||||
}
|
}
|
||||||
|
@ -2230,7 +2230,7 @@ struct ChainContextFormat2
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (input_class_def.intersects_class (glyphs, i) &&
|
if (input_class_def.intersects_class (glyphs, i) &&
|
||||||
(this+ruleSet[i]).intersects (glyphs, lookup_context))
|
(this+ruleSet[i]).intersects (glyphs, lookup_context))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -2644,10 +2644,10 @@ struct hb_ot_layout_lookup_accelerator_t
|
||||||
|
|
||||||
inline bool apply (hb_ot_apply_context_t *c) const
|
inline bool apply (hb_ot_apply_context_t *c) const
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < subtables.len; i++)
|
for (unsigned int i = 0; i < subtables.len; i++)
|
||||||
if (subtables[i].apply (c))
|
if (subtables[i].apply (c))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -2702,7 +2702,7 @@ struct GSUBGPOS
|
||||||
const Feature *feature = (this+featureVars).find_substitute (variations_index,
|
const Feature *feature = (this+featureVars).find_substitute (variations_index,
|
||||||
feature_index);
|
feature_index);
|
||||||
if (feature)
|
if (feature)
|
||||||
return *feature;
|
return *feature;
|
||||||
}
|
}
|
||||||
return get_feature (feature_index);
|
return get_feature (feature_index);
|
||||||
}
|
}
|
||||||
|
@ -2758,7 +2758,7 @@ struct GSUBGPOS
|
||||||
|
|
||||||
this->accels = (hb_ot_layout_lookup_accelerator_t *) calloc (this->lookup_count, sizeof (hb_ot_layout_lookup_accelerator_t));
|
this->accels = (hb_ot_layout_lookup_accelerator_t *) calloc (this->lookup_count, sizeof (hb_ot_layout_lookup_accelerator_t));
|
||||||
if (unlikely (!this->accels))
|
if (unlikely (!this->accels))
|
||||||
this->lookup_count = 0;
|
this->lookup_count = 0;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < this->lookup_count; i++)
|
for (unsigned int i = 0; i < this->lookup_count; i++)
|
||||||
this->accels[i].init (table->get_lookup (i));
|
this->accels[i].init (table->get_lookup (i));
|
||||||
|
|
|
@ -74,7 +74,7 @@ struct MathConstants
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return_trace (c->check_struct (this) && sanitize_math_value_records(c));
|
return_trace (c->check_struct (this) && sanitize_math_value_records (c));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline hb_position_t get_value (hb_ot_math_constant_t constant,
|
inline hb_position_t get_value (hb_ot_math_constant_t constant,
|
||||||
|
@ -94,7 +94,7 @@ struct MathConstants
|
||||||
case HB_OT_MATH_CONSTANT_RADICAL_KERN_BEFORE_DEGREE:
|
case HB_OT_MATH_CONSTANT_RADICAL_KERN_BEFORE_DEGREE:
|
||||||
case HB_OT_MATH_CONSTANT_SKEWED_FRACTION_HORIZONTAL_GAP:
|
case HB_OT_MATH_CONSTANT_SKEWED_FRACTION_HORIZONTAL_GAP:
|
||||||
case HB_OT_MATH_CONSTANT_SPACE_AFTER_SCRIPT:
|
case HB_OT_MATH_CONSTANT_SPACE_AFTER_SCRIPT:
|
||||||
return mathValueRecords[constant - HB_OT_MATH_CONSTANT_MATH_LEADING].get_x_value(font, this);
|
return mathValueRecords[constant - HB_OT_MATH_CONSTANT_MATH_LEADING].get_x_value (font, this);
|
||||||
|
|
||||||
case HB_OT_MATH_CONSTANT_ACCENT_BASE_HEIGHT:
|
case HB_OT_MATH_CONSTANT_ACCENT_BASE_HEIGHT:
|
||||||
case HB_OT_MATH_CONSTANT_AXIS_HEIGHT:
|
case HB_OT_MATH_CONSTANT_AXIS_HEIGHT:
|
||||||
|
@ -143,7 +143,7 @@ struct MathConstants
|
||||||
case HB_OT_MATH_CONSTANT_UNDERBAR_VERTICAL_GAP:
|
case HB_OT_MATH_CONSTANT_UNDERBAR_VERTICAL_GAP:
|
||||||
case HB_OT_MATH_CONSTANT_UPPER_LIMIT_BASELINE_RISE_MIN:
|
case HB_OT_MATH_CONSTANT_UPPER_LIMIT_BASELINE_RISE_MIN:
|
||||||
case HB_OT_MATH_CONSTANT_UPPER_LIMIT_GAP_MIN:
|
case HB_OT_MATH_CONSTANT_UPPER_LIMIT_GAP_MIN:
|
||||||
return mathValueRecords[constant - HB_OT_MATH_CONSTANT_MATH_LEADING].get_y_value(font, this);
|
return mathValueRecords[constant - HB_OT_MATH_CONSTANT_MATH_LEADING].get_y_value (font, this);
|
||||||
|
|
||||||
case HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT:
|
case HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT:
|
||||||
return radicalDegreeBottomRaisePercent;
|
return radicalDegreeBottomRaisePercent;
|
||||||
|
@ -210,7 +210,7 @@ struct MathTopAccentAttachment
|
||||||
unsigned int index = (this+topAccentCoverage).get_coverage (glyph);
|
unsigned int index = (this+topAccentCoverage).get_coverage (glyph);
|
||||||
if (index == NOT_COVERED)
|
if (index == NOT_COVERED)
|
||||||
return font->get_glyph_h_advance (glyph) / 2;
|
return font->get_glyph_h_advance (glyph) / 2;
|
||||||
return topAccentAttachment[index].get_x_value(font, this);
|
return topAccentAttachment[index].get_x_value (font, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -265,7 +265,7 @@ struct MathKern
|
||||||
while (count > 0)
|
while (count > 0)
|
||||||
{
|
{
|
||||||
unsigned int half = count / 2;
|
unsigned int half = count / 2;
|
||||||
hb_position_t height = correctionHeight[i + half].get_y_value(font, this);
|
hb_position_t height = correctionHeight[i + half].get_y_value (font, this);
|
||||||
if (sign * height < sign * correction_height)
|
if (sign * height < sign * correction_height)
|
||||||
{
|
{
|
||||||
i += half + 1;
|
i += half + 1;
|
||||||
|
@ -273,7 +273,7 @@ struct MathKern
|
||||||
} else
|
} else
|
||||||
count = half;
|
count = half;
|
||||||
}
|
}
|
||||||
return kernValue[i].get_x_value(font, this);
|
return kernValue[i].get_x_value (font, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -368,7 +368,7 @@ struct MathGlyphInfo
|
||||||
mathItalicsCorrectionInfo.sanitize (c, this) &&
|
mathItalicsCorrectionInfo.sanitize (c, this) &&
|
||||||
mathTopAccentAttachment.sanitize (c, this) &&
|
mathTopAccentAttachment.sanitize (c, this) &&
|
||||||
extendedShapeCoverage.sanitize (c, this) &&
|
extendedShapeCoverage.sanitize (c, this) &&
|
||||||
mathKernInfo.sanitize(c, this));
|
mathKernInfo.sanitize (c, this));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline hb_position_t
|
inline hb_position_t
|
||||||
|
@ -425,8 +425,8 @@ struct MathGlyphVariantRecord
|
||||||
protected:
|
protected:
|
||||||
GlyphID variantGlyph; /* Glyph ID for the variant. */
|
GlyphID variantGlyph; /* Glyph ID for the variant. */
|
||||||
HBUINT16 advanceMeasurement; /* Advance width/height, in design units, of the
|
HBUINT16 advanceMeasurement; /* Advance width/height, in design units, of the
|
||||||
* variant, in the direction of requested
|
* variant, in the direction of requested
|
||||||
* glyph extension. */
|
* glyph extension. */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (4);
|
DEFINE_SIZE_STATIC (4);
|
||||||
|
@ -495,8 +495,8 @@ struct MathGlyphAssembly
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return_trace (c->check_struct (this) &&
|
return_trace (c->check_struct (this) &&
|
||||||
italicsCorrection.sanitize(c, this) &&
|
italicsCorrection.sanitize (c, this) &&
|
||||||
partRecords.sanitize(c));
|
partRecords.sanitize (c));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned int get_parts (hb_direction_t direction,
|
inline unsigned int get_parts (hb_direction_t direction,
|
||||||
|
@ -540,8 +540,8 @@ struct MathGlyphConstruction
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
return_trace (c->check_struct (this) &&
|
return_trace (c->check_struct (this) &&
|
||||||
glyphAssembly.sanitize(c, this) &&
|
glyphAssembly.sanitize (c, this) &&
|
||||||
mathGlyphVariantRecord.sanitize(c));
|
mathGlyphVariantRecord.sanitize (c));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const MathGlyphAssembly &get_assembly (void) const
|
inline const MathGlyphAssembly &get_assembly (void) const
|
||||||
|
@ -639,7 +639,7 @@ struct MathVariants
|
||||||
: horizGlyphCoverage;
|
: horizGlyphCoverage;
|
||||||
|
|
||||||
unsigned int index = (this+coverage).get_coverage (glyph);
|
unsigned int index = (this+coverage).get_coverage (glyph);
|
||||||
if (unlikely (index >= count)) return Null(MathGlyphConstruction);
|
if (unlikely (index >= count)) return Null (MathGlyphConstruction);
|
||||||
|
|
||||||
if (!vertical)
|
if (!vertical)
|
||||||
index += vertGlyphCount;
|
index += vertGlyphCount;
|
||||||
|
|
|
@ -50,7 +50,7 @@ struct OS2
|
||||||
|
|
||||||
inline bool subset (hb_subset_plan_t *plan) const
|
inline bool subset (hb_subset_plan_t *plan) const
|
||||||
{
|
{
|
||||||
hb_blob_t *os2_blob = hb_sanitize_context_t().reference_table<OS2> (plan->source);
|
hb_blob_t *os2_blob = hb_sanitize_context_t ().reference_table<OS2> (plan->source);
|
||||||
hb_blob_t *os2_prime_blob = hb_blob_create_sub_blob (os2_blob, 0, -1);
|
hb_blob_t *os2_prime_blob = hb_blob_create_sub_blob (os2_blob, 0, -1);
|
||||||
// TODO(grieger): move to hb_blob_copy_writable_or_fail
|
// TODO(grieger): move to hb_blob_copy_writable_or_fail
|
||||||
hb_blob_destroy (os2_blob);
|
hb_blob_destroy (os2_blob);
|
||||||
|
@ -74,7 +74,7 @@ struct OS2
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void _update_unicode_ranges (const hb_set_t *codepoints,
|
inline void _update_unicode_ranges (const hb_set_t *codepoints,
|
||||||
HBUINT32 ulUnicodeRange[4]) const
|
HBUINT32 ulUnicodeRange[4]) const
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < 4; i++)
|
for (unsigned int i = 0; i < 4; i++)
|
||||||
ulUnicodeRange[i].set (0);
|
ulUnicodeRange[i].set (0);
|
||||||
|
@ -84,24 +84,24 @@ struct OS2
|
||||||
unsigned int bit = _hb_ot_os2_get_unicode_range_bit (cp);
|
unsigned int bit = _hb_ot_os2_get_unicode_range_bit (cp);
|
||||||
if (bit < 128)
|
if (bit < 128)
|
||||||
{
|
{
|
||||||
unsigned int block = bit / 32;
|
unsigned int block = bit / 32;
|
||||||
unsigned int bit_in_block = bit % 32;
|
unsigned int bit_in_block = bit % 32;
|
||||||
unsigned int mask = 1 << bit_in_block;
|
unsigned int mask = 1 << bit_in_block;
|
||||||
ulUnicodeRange[block].set (ulUnicodeRange[block] | mask);
|
ulUnicodeRange[block].set (ulUnicodeRange[block] | mask);
|
||||||
}
|
}
|
||||||
if (cp >= 0x10000 && cp <= 0x110000)
|
if (cp >= 0x10000 && cp <= 0x110000)
|
||||||
{
|
{
|
||||||
/* the spec says that bit 57 ("Non Plane 0") implies that there's
|
/* the spec says that bit 57 ("Non Plane 0") implies that there's
|
||||||
at least one codepoint beyond the BMP; so I also include all
|
at least one codepoint beyond the BMP; so I also include all
|
||||||
the non-BMP codepoints here */
|
the non-BMP codepoints here */
|
||||||
ulUnicodeRange[1].set (ulUnicodeRange[1] | (1 << 25));
|
ulUnicodeRange[1].set (ulUnicodeRange[1] | (1 << 25));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void find_min_and_max_codepoint (const hb_set_t *codepoints,
|
static inline void find_min_and_max_codepoint (const hb_set_t *codepoints,
|
||||||
uint16_t *min_cp, /* OUT */
|
uint16_t *min_cp, /* OUT */
|
||||||
uint16_t *max_cp /* OUT */)
|
uint16_t *max_cp /* OUT */)
|
||||||
{
|
{
|
||||||
*min_cp = codepoints->get_min ();
|
*min_cp = codepoints->get_min ();
|
||||||
*max_cp = codepoints->get_max ();
|
*max_cp = codepoints->get_max ();
|
||||||
|
|
|
@ -76,7 +76,7 @@ struct post
|
||||||
inline bool subset (hb_subset_plan_t *plan) const
|
inline bool subset (hb_subset_plan_t *plan) const
|
||||||
{
|
{
|
||||||
unsigned int post_prime_length;
|
unsigned int post_prime_length;
|
||||||
hb_blob_t *post_blob = hb_sanitize_context_t().reference_table<post>(plan->source);
|
hb_blob_t *post_blob = hb_sanitize_context_t ().reference_table<post>(plan->source);
|
||||||
hb_blob_t *post_prime_blob = hb_blob_create_sub_blob (post_blob, 0, post::min_size);
|
hb_blob_t *post_prime_blob = hb_blob_create_sub_blob (post_blob, 0, post::min_size);
|
||||||
post *post_prime = (post *) hb_blob_get_data_writable (post_prime_blob, &post_prime_length);
|
post *post_prime = (post *) hb_blob_get_data_writable (post_prime_blob, &post_prime_length);
|
||||||
hb_blob_destroy (post_blob);
|
hb_blob_destroy (post_blob);
|
||||||
|
@ -101,12 +101,11 @@ struct post
|
||||||
{
|
{
|
||||||
index_to_offset.init ();
|
index_to_offset.init ();
|
||||||
|
|
||||||
table = hb_sanitize_context_t().reference_table<post> (face);
|
table = hb_sanitize_context_t ().reference_table<post> (face);
|
||||||
unsigned int table_length = table.get_length ();
|
unsigned int table_length = table.get_length ();
|
||||||
|
|
||||||
version = table->version.to_int ();
|
version = table->version.to_int ();
|
||||||
if (version != 0x00020000)
|
if (version != 0x00020000) return;
|
||||||
return;
|
|
||||||
|
|
||||||
const postV2Tail &v2 = table->v2;
|
const postV2Tail &v2 = table->v2;
|
||||||
|
|
||||||
|
@ -130,10 +129,8 @@ struct post
|
||||||
char *buf, unsigned int buf_len) const
|
char *buf, unsigned int buf_len) const
|
||||||
{
|
{
|
||||||
hb_bytes_t s = find_glyph_name (glyph);
|
hb_bytes_t s = find_glyph_name (glyph);
|
||||||
if (!s.len)
|
if (!s.len) return false;
|
||||||
return false;
|
if (!buf_len) return true;
|
||||||
if (!buf_len)
|
|
||||||
return true;
|
|
||||||
unsigned int len = MIN (buf_len - 1, s.len);
|
unsigned int len = MIN (buf_len - 1, s.len);
|
||||||
strncpy (buf, s.arrayZ, len);
|
strncpy (buf, s.arrayZ, len);
|
||||||
buf[len] = '\0';
|
buf[len] = '\0';
|
||||||
|
@ -144,14 +141,11 @@ struct post
|
||||||
hb_codepoint_t *glyph) const
|
hb_codepoint_t *glyph) const
|
||||||
{
|
{
|
||||||
unsigned int count = get_glyph_count ();
|
unsigned int count = get_glyph_count ();
|
||||||
if (unlikely (!count))
|
if (unlikely (!count)) return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
if (len < 0)
|
if (len < 0) len = strlen (name);
|
||||||
len = strlen (name);
|
|
||||||
|
|
||||||
if (unlikely (!len))
|
if (unlikely (!len)) return false;
|
||||||
return false;
|
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
uint16_t *gids = gids_sorted_by_name.get ();
|
uint16_t *gids = gids_sorted_by_name.get ();
|
||||||
|
@ -189,10 +183,10 @@ struct post
|
||||||
inline unsigned int get_glyph_count (void) const
|
inline unsigned int get_glyph_count (void) const
|
||||||
{
|
{
|
||||||
if (version == 0x00010000)
|
if (version == 0x00010000)
|
||||||
return NUM_FORMAT1_NAMES;
|
return NUM_FORMAT1_NAMES;
|
||||||
|
|
||||||
if (version == 0x00020000)
|
if (version == 0x00020000)
|
||||||
return glyphNameIndex->len;
|
return glyphNameIndex->len;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
* Google Author(s): Behdad Esfahbod
|
* Google Author(s): Behdad Esfahbod
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define HB_SHAPER ot
|
|
||||||
#include "hb-shaper-impl.hh"
|
#include "hb-shaper-impl.hh"
|
||||||
|
|
||||||
#include "hb-ot-shape.hh"
|
#include "hb-ot-shape.hh"
|
||||||
|
@ -320,8 +319,6 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
|
||||||
* shaper face data
|
* shaper face data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
HB_SHAPER_DATA_ENSURE_DEFINE(ot, face);
|
|
||||||
|
|
||||||
struct hb_ot_face_data_t {};
|
struct hb_ot_face_data_t {};
|
||||||
|
|
||||||
hb_ot_face_data_t *
|
hb_ot_face_data_t *
|
||||||
|
@ -340,8 +337,6 @@ _hb_ot_shaper_face_data_destroy (hb_ot_face_data_t *data)
|
||||||
* shaper font data
|
* shaper font data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
HB_SHAPER_DATA_ENSURE_DEFINE(ot, font);
|
|
||||||
|
|
||||||
struct hb_ot_font_data_t {};
|
struct hb_ot_font_data_t {};
|
||||||
|
|
||||||
hb_ot_font_data_t *
|
hb_ot_font_data_t *
|
||||||
|
|
|
@ -87,7 +87,7 @@ hb_shape_plan_key_t::init (bool copy,
|
||||||
|
|
||||||
#define HB_SHAPER_PLAN(shaper) \
|
#define HB_SHAPER_PLAN(shaper) \
|
||||||
HB_STMT_START { \
|
HB_STMT_START { \
|
||||||
if (hb_##shaper##_shaper_face_data_ensure (face)) \
|
if (face->data.shaper) \
|
||||||
{ \
|
{ \
|
||||||
this->shaper_func = _hb_##shaper##_shape; \
|
this->shaper_func = _hb_##shaper##_shape; \
|
||||||
this->shaper_name = #shaper; \
|
this->shaper_name = #shaper; \
|
||||||
|
@ -386,7 +386,7 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
|
||||||
|
|
||||||
#define HB_SHAPER_EXECUTE(shaper) \
|
#define HB_SHAPER_EXECUTE(shaper) \
|
||||||
HB_STMT_START { \
|
HB_STMT_START { \
|
||||||
return hb_##shaper##_shaper_font_data_ensure (font) && \
|
return font->data.shaper && \
|
||||||
_hb_##shaper##_shape (shape_plan, font, buffer, features, num_features); \
|
_hb_##shaper##_shape (shape_plan, font, buffer, features, num_features); \
|
||||||
} HB_STMT_END
|
} HB_STMT_END
|
||||||
|
|
||||||
|
|
|
@ -30,14 +30,9 @@
|
||||||
#include "hb.hh"
|
#include "hb.hh"
|
||||||
|
|
||||||
#include "hb-shaper.hh"
|
#include "hb-shaper.hh"
|
||||||
#include "hb-shape-plan.hh"
|
#include "hb-face.hh"
|
||||||
#include "hb-font.hh"
|
#include "hb-font.hh"
|
||||||
|
#include "hb-shape-plan.hh"
|
||||||
#include "hb-buffer.hh"
|
#include "hb-buffer.hh"
|
||||||
|
|
||||||
|
|
||||||
#ifdef HB_SHAPER
|
|
||||||
#define HB_SHAPER_DATA_GET(object) HB_SHAPER_DATA (HB_SHAPER, object).get ()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* HB_SHAPER_IMPL_HH */
|
#endif /* HB_SHAPER_IMPL_HH */
|
||||||
|
|
141
src/hb-shaper.hh
141
src/hb-shaper.hh
|
@ -28,6 +28,7 @@
|
||||||
#define HB_SHAPER_HH
|
#define HB_SHAPER_HH
|
||||||
|
|
||||||
#include "hb.hh"
|
#include "hb.hh"
|
||||||
|
#include "hb-machinery.hh"
|
||||||
|
|
||||||
typedef hb_bool_t hb_shape_func_t (hb_shape_plan_t *shape_plan,
|
typedef hb_bool_t hb_shape_func_t (hb_shape_plan_t *shape_plan,
|
||||||
hb_font_t *font,
|
hb_font_t *font,
|
||||||
|
@ -49,87 +50,85 @@ HB_INTERNAL const hb_shaper_entry_t *
|
||||||
_hb_shapers_get (void);
|
_hb_shapers_get (void);
|
||||||
|
|
||||||
|
|
||||||
/* Means: succeeded, but don't need to keep any data. */
|
template <typename Data, unsigned int WheresData, typename T>
|
||||||
#define HB_SHAPER_DATA_SUCCEEDED ((void *) +1)
|
struct hb_shaper_lazy_loader_t;
|
||||||
/* Means: tried but failed to create. */
|
|
||||||
#define HB_SHAPER_DATA_INVALID ((void *) -1)
|
|
||||||
|
|
||||||
#define HB_SHAPER_DATA_TYPE_NAME(shaper, object) hb_##shaper##_##object##_data_t
|
#define HB_SHAPER_ORDER(Shaper) \
|
||||||
#define HB_SHAPER_DATA_TYPE(shaper, object) struct HB_SHAPER_DATA_TYPE_NAME(shaper, object)
|
HB_PASTE (HB_SHAPER_ORDER_, Shaper)
|
||||||
#define HB_SHAPER_DATA_INSTANCE(shaper, object, instance) (* reinterpret_cast<hb_atomic_ptr_t<HB_SHAPER_DATA_TYPE(shaper, object) *> *> (&(instance)->shaper_data.shaper))
|
enum hb_shaper_order_t
|
||||||
#define HB_SHAPER_DATA(shaper, object) HB_SHAPER_DATA_INSTANCE(shaper, object, object)
|
{
|
||||||
|
_HB_SHAPER_ORDER_ORDER_ZERO,
|
||||||
|
#define HB_SHAPER_IMPLEMENT(Shaper) \
|
||||||
|
HB_SHAPER_ORDER (Shaper),
|
||||||
|
#include "hb-shaper-list.hh"
|
||||||
|
#undef HB_SHAPER_IMPLEMENT
|
||||||
|
_HB_SHAPERS_COUNT_PLUS_ONE,
|
||||||
|
HB_SHAPERS_COUNT = _HB_SHAPERS_COUNT_PLUS_ONE - 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
template <enum hb_shaper_order_t order, typename Object> struct hb_shaper_object_data_type_t;
|
||||||
|
|
||||||
|
#define HB_SHAPER_DATA_SUCCEEDED ((void *) +1)
|
||||||
|
#define HB_SHAPER_DATA_TYPE(shaper, object) hb_##shaper##_##object##_data_t
|
||||||
#define HB_SHAPER_DATA_CREATE_FUNC(shaper, object) _hb_##shaper##_shaper_##object##_data_create
|
#define HB_SHAPER_DATA_CREATE_FUNC(shaper, object) _hb_##shaper##_shaper_##object##_data_create
|
||||||
#define HB_SHAPER_DATA_DESTROY_FUNC(shaper, object) _hb_##shaper##_shaper_##object##_data_destroy
|
#define HB_SHAPER_DATA_DESTROY_FUNC(shaper, object) _hb_##shaper##_shaper_##object##_data_destroy
|
||||||
#define HB_SHAPER_DATA_ENSURE_FUNC(shaper, object) hb_##shaper##_shaper_##object##_data_ensure
|
|
||||||
|
|
||||||
#define HB_SHAPER_DATA_PROTOTYPE(shaper, object) \
|
#define HB_SHAPER_DATA_INSTANTIATE_SHAPERS(shaper, object) \
|
||||||
HB_SHAPER_DATA_TYPE (shaper, object); /* Type forward declaration. */ \
|
\
|
||||||
|
struct HB_SHAPER_DATA_TYPE (shaper, object); /* Type forward declaration. */ \
|
||||||
extern "C" HB_INTERNAL HB_SHAPER_DATA_TYPE (shaper, object) * \
|
extern "C" HB_INTERNAL HB_SHAPER_DATA_TYPE (shaper, object) * \
|
||||||
HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (hb_##object##_t *object HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS); \
|
HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (hb_##object##_t *object); \
|
||||||
extern "C" HB_INTERNAL void \
|
extern "C" HB_INTERNAL void \
|
||||||
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA_TYPE (shaper, object) *data); \
|
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA_TYPE (shaper, object) *shaper##_##object); \
|
||||||
extern "C" HB_INTERNAL bool \
|
\
|
||||||
HB_SHAPER_DATA_ENSURE_FUNC (shaper, object) (hb_##object##_t *object)
|
template <> \
|
||||||
|
struct hb_shaper_object_data_type_t<HB_SHAPER_ORDER (shaper), hb_##object##_t> \
|
||||||
#define HB_SHAPER_DATA_DESTROY(shaper, object) \
|
{ \
|
||||||
if (HB_SHAPER_DATA_TYPE (shaper, object) *data = HB_SHAPER_DATA (shaper, object).get ()) \
|
typedef HB_SHAPER_DATA_TYPE(shaper, object) value; \
|
||||||
if (data != HB_SHAPER_DATA_INVALID && data != HB_SHAPER_DATA_SUCCEEDED) \
|
}; \
|
||||||
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data);
|
\
|
||||||
|
template <unsigned int WheresData> \
|
||||||
#define HB_SHAPER_DATA_ENSURE_DEFINE(shaper, object) \
|
struct hb_shaper_lazy_loader_t<hb_##object##_t, WheresData, HB_SHAPER_DATA_TYPE(shaper, object)> \
|
||||||
HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(shaper, object, true)
|
: hb_lazy_loader_t<HB_SHAPER_DATA_TYPE(shaper, object), \
|
||||||
|
hb_shaper_lazy_loader_t<hb_##object##_t, \
|
||||||
#define HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(shaper, object, condition) \
|
WheresData, \
|
||||||
bool \
|
HB_SHAPER_DATA_TYPE(shaper, object)>, \
|
||||||
HB_SHAPER_DATA_ENSURE_FUNC(shaper, object) (hb_##object##_t *object) \
|
hb_##object##_t, WheresData> \
|
||||||
{\
|
{ \
|
||||||
retry: \
|
typedef HB_SHAPER_DATA_TYPE(shaper, object) Type; \
|
||||||
HB_SHAPER_DATA_TYPE (shaper, object) *data = HB_SHAPER_DATA (shaper, object).get (); \
|
static inline Type* create (hb_##object##_t *data) \
|
||||||
if (likely (data) && !(condition)) { \
|
{ return HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (data); } \
|
||||||
/* XXX-MT-bug \
|
static inline Type *get_null (void) { return nullptr; } \
|
||||||
* Note that evaluating condition above can be dangerous if another thread \
|
static inline void destroy (Type *p) { HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (p); } \
|
||||||
* got here first and destructed data. That's, as always, bad use pattern. \
|
}; \
|
||||||
* If you modify the font (change font size), other threads must not be \
|
\
|
||||||
* using it at the same time. However, since this check is delayed to \
|
static_assert (true, "") /* Require semicolon. */
|
||||||
* when one actually tries to shape something, this is a XXX race condition \
|
|
||||||
* (and the only know we have that I know of) right now. Ie. you modify the \
|
|
||||||
* font size in one thread, then (supposedly safely) try to use it from two \
|
|
||||||
* or more threads and BOOM! I'm not sure how to fix this. We want RCU. \
|
|
||||||
* Maybe when it doesn't matter when we finally implement AAT shaping, as
|
|
||||||
* this (condition) is currently only used by hb-coretext. */ \
|
|
||||||
/* Drop and recreate. */ \
|
|
||||||
/* If someone dropped it in the mean time, throw it away and don't touch it. \
|
|
||||||
* Otherwise, destruct it. */ \
|
|
||||||
if (likely (HB_SHAPER_DATA (shaper, object).cmpexch (data, nullptr))) \
|
|
||||||
{ \
|
|
||||||
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); \
|
|
||||||
} \
|
|
||||||
goto retry; \
|
|
||||||
} \
|
|
||||||
if (unlikely (!data)) { \
|
|
||||||
data = HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (object); \
|
|
||||||
if (unlikely (!data)) \
|
|
||||||
data = (HB_SHAPER_DATA_TYPE (shaper, object) *) HB_SHAPER_DATA_INVALID; \
|
|
||||||
if (unlikely (!HB_SHAPER_DATA (shaper, object).cmpexch (nullptr, data))) { \
|
|
||||||
if (data && \
|
|
||||||
data != HB_SHAPER_DATA_INVALID && \
|
|
||||||
data != HB_SHAPER_DATA_SUCCEEDED) \
|
|
||||||
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); \
|
|
||||||
goto retry; \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
return data != nullptr && (void *) data != HB_SHAPER_DATA_INVALID; \
|
|
||||||
} \
|
|
||||||
static_assert (true, "") /* Require semicolon. */
|
|
||||||
|
|
||||||
|
|
||||||
/* For embedding in face / font / ... */
|
template <typename Object>
|
||||||
struct hb_shaper_data_t {
|
struct hb_shaper_object_dataset_t
|
||||||
#define HB_SHAPER_IMPLEMENT(shaper) hb_atomic_ptr_t<void *> shaper;
|
{
|
||||||
|
inline void init0 (Object *parent_data)
|
||||||
|
{
|
||||||
|
this->parent_data = parent_data;
|
||||||
|
#define HB_SHAPER_IMPLEMENT(shaper) shaper.init0 ();
|
||||||
|
#include "hb-shaper-list.hh"
|
||||||
|
#undef HB_SHAPER_IMPLEMENT
|
||||||
|
}
|
||||||
|
inline void fini (void)
|
||||||
|
{
|
||||||
|
#define HB_SHAPER_IMPLEMENT(shaper) shaper.fini ();
|
||||||
|
#include "hb-shaper-list.hh"
|
||||||
|
#undef HB_SHAPER_IMPLEMENT
|
||||||
|
}
|
||||||
|
|
||||||
|
Object *parent_data; /* MUST be JUST before the lazy loaders. */
|
||||||
|
#define HB_SHAPER_IMPLEMENT(shaper) \
|
||||||
|
hb_shaper_lazy_loader_t<Object, HB_SHAPER_ORDER(shaper), \
|
||||||
|
typename hb_shaper_object_data_type_t<HB_SHAPER_ORDER(shaper), Object>::value \
|
||||||
|
> shaper;
|
||||||
#include "hb-shaper-list.hh"
|
#include "hb-shaper-list.hh"
|
||||||
#undef HB_SHAPER_IMPLEMENT
|
#undef HB_SHAPER_IMPLEMENT
|
||||||
};
|
};
|
||||||
#define HB_SHAPERS_COUNT (sizeof (hb_shaper_data_t) / sizeof (void *))
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* HB_SHAPER_HH */
|
#endif /* HB_SHAPER_HH */
|
||||||
|
|
|
@ -31,12 +31,12 @@
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
_calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf,
|
_calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf,
|
||||||
hb_vector_t<hb_codepoint_t> &glyph_ids,
|
hb_vector_t<hb_codepoint_t> &glyph_ids,
|
||||||
hb_bool_t drop_hints,
|
hb_bool_t drop_hints,
|
||||||
bool *use_short_loca /* OUT */,
|
bool *use_short_loca /* OUT */,
|
||||||
unsigned int *glyf_size /* OUT */,
|
unsigned int *glyf_size /* OUT */,
|
||||||
unsigned int *loca_size /* OUT */,
|
unsigned int *loca_size /* OUT */,
|
||||||
hb_vector_t<unsigned int> *instruction_ranges /* OUT */)
|
hb_vector_t<unsigned int> *instruction_ranges /* OUT */)
|
||||||
{
|
{
|
||||||
unsigned int total = 0;
|
unsigned int total = 0;
|
||||||
for (unsigned int i = 0; i < glyph_ids.len; i++)
|
for (unsigned int i = 0; i < glyph_ids.len; i++)
|
||||||
|
@ -53,8 +53,8 @@ _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf,
|
||||||
*instruction_end = 0;
|
*instruction_end = 0;
|
||||||
|
|
||||||
unsigned int start_offset, end_offset;
|
unsigned int start_offset, end_offset;
|
||||||
if (unlikely (!(glyf.get_offsets(next_glyph, &start_offset, &end_offset)
|
if (unlikely (!(glyf.get_offsets (next_glyph, &start_offset, &end_offset) &&
|
||||||
&& glyf.remove_padding(start_offset, &end_offset))))
|
glyf.remove_padding (start_offset, &end_offset))))
|
||||||
{
|
{
|
||||||
DEBUG_MSG(SUBSET, nullptr, "Invalid gid %d", next_glyph);
|
DEBUG_MSG(SUBSET, nullptr, "Invalid gid %d", next_glyph);
|
||||||
continue;
|
continue;
|
||||||
|
@ -64,11 +64,11 @@ _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf,
|
||||||
|
|
||||||
if (drop_hints)
|
if (drop_hints)
|
||||||
{
|
{
|
||||||
if (unlikely (!glyf.get_instruction_offsets(start_offset, end_offset,
|
if (unlikely (!glyf.get_instruction_offsets (start_offset, end_offset,
|
||||||
instruction_start, instruction_end)))
|
instruction_start, instruction_end)))
|
||||||
{
|
{
|
||||||
DEBUG_MSG(SUBSET, nullptr, "Unable to get instruction offsets for %d", next_glyph);
|
DEBUG_MSG(SUBSET, nullptr, "Unable to get instruction offsets for %d", next_glyph);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,21 +80,21 @@ _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf,
|
||||||
*glyf_size = total;
|
*glyf_size = total;
|
||||||
*use_short_loca = (total <= 131070);
|
*use_short_loca = (total <= 131070);
|
||||||
*loca_size = (glyph_ids.len + 1)
|
*loca_size = (glyph_ids.len + 1)
|
||||||
* (*use_short_loca ? sizeof(OT::HBUINT16) : sizeof(OT::HBUINT32));
|
* (*use_short_loca ? sizeof (OT::HBUINT16) : sizeof (OT::HBUINT32));
|
||||||
|
|
||||||
DEBUG_MSG(SUBSET, nullptr, "preparing to subset glyf: final size %d, loca size %d, using %s loca",
|
DEBUG_MSG(SUBSET, nullptr, "preparing to subset glyf: final size %d, loca size %d, using %s loca",
|
||||||
total,
|
total,
|
||||||
*loca_size,
|
*loca_size,
|
||||||
*use_short_loca ? "short" : "long");
|
*use_short_loca ? "short" : "long");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
_write_loca_entry (unsigned int id,
|
_write_loca_entry (unsigned int id,
|
||||||
unsigned int offset,
|
unsigned int offset,
|
||||||
bool is_short,
|
bool is_short,
|
||||||
void *loca_prime,
|
void *loca_prime,
|
||||||
unsigned int loca_size)
|
unsigned int loca_size)
|
||||||
{
|
{
|
||||||
unsigned int entry_size = is_short ? sizeof (OT::HBUINT16) : sizeof (OT::HBUINT32);
|
unsigned int entry_size = is_short ? sizeof (OT::HBUINT16) : sizeof (OT::HBUINT32);
|
||||||
if ((id + 1) * entry_size <= loca_size)
|
if ((id + 1) * entry_size <= loca_size)
|
||||||
|
@ -108,11 +108,11 @@ _write_loca_entry (unsigned int id,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Offset was not written because the write is out of bounds.
|
// Offset was not written because the write is out of bounds.
|
||||||
DEBUG_MSG (SUBSET,
|
DEBUG_MSG(SUBSET,
|
||||||
nullptr,
|
nullptr,
|
||||||
"WARNING: Attempted to write an out of bounds loca entry at index %d. Loca size is %d.",
|
"WARNING: Attempted to write an out of bounds loca entry at index %d. Loca size is %d.",
|
||||||
id,
|
id,
|
||||||
loca_size);
|
loca_size);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,15 +130,15 @@ _update_components (hb_subset_plan_t * plan,
|
||||||
{
|
{
|
||||||
hb_codepoint_t new_gid;
|
hb_codepoint_t new_gid;
|
||||||
if (!plan->new_gid_for_old_gid (iterator.current->glyphIndex,
|
if (!plan->new_gid_for_old_gid (iterator.current->glyphIndex,
|
||||||
&new_gid))
|
&new_gid))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
((OT::glyf::CompositeGlyphHeader *) iterator.current)->glyphIndex.set (new_gid);
|
((OT::glyf::CompositeGlyphHeader *) iterator.current)->glyphIndex.set (new_gid);
|
||||||
} while (iterator.move_to_next());
|
} while (iterator.move_to_next ());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool _remove_composite_instruction_flag(char *glyf_prime, unsigned int length)
|
static bool _remove_composite_instruction_flag (char *glyf_prime, unsigned int length)
|
||||||
{
|
{
|
||||||
/* remove WE_HAVE_INSTRUCTIONS from flags in dest */
|
/* remove WE_HAVE_INSTRUCTIONS from flags in dest */
|
||||||
OT::glyf::CompositeGlyphHeader::Iterator composite_it;
|
OT::glyf::CompositeGlyphHeader::Iterator composite_it;
|
||||||
|
@ -148,20 +148,20 @@ static bool _remove_composite_instruction_flag(char *glyf_prime, unsigned int le
|
||||||
glyph = composite_it.current;
|
glyph = composite_it.current;
|
||||||
OT::HBUINT16 *flags = const_cast<OT::HBUINT16 *> (&glyph->flags);
|
OT::HBUINT16 *flags = const_cast<OT::HBUINT16 *> (&glyph->flags);
|
||||||
flags->set ( (uint16_t) *flags & ~OT::glyf::CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS);
|
flags->set ( (uint16_t) *flags & ~OT::glyf::CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS);
|
||||||
} while (composite_it.move_to_next());
|
} while (composite_it.move_to_next ());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
_write_glyf_and_loca_prime (hb_subset_plan_t *plan,
|
_write_glyf_and_loca_prime (hb_subset_plan_t *plan,
|
||||||
const OT::glyf::accelerator_t &glyf,
|
const OT::glyf::accelerator_t &glyf,
|
||||||
const char *glyf_data,
|
const char *glyf_data,
|
||||||
bool use_short_loca,
|
bool use_short_loca,
|
||||||
hb_vector_t<unsigned int> &instruction_ranges,
|
hb_vector_t<unsigned int> &instruction_ranges,
|
||||||
unsigned int glyf_prime_size,
|
unsigned int glyf_prime_size,
|
||||||
char *glyf_prime_data /* OUT */,
|
char *glyf_prime_data /* OUT */,
|
||||||
unsigned int loca_prime_size,
|
unsigned int loca_prime_size,
|
||||||
char *loca_prime_data /* OUT */)
|
char *loca_prime_data /* OUT */)
|
||||||
{
|
{
|
||||||
hb_vector_t<hb_codepoint_t> &glyph_ids = plan->glyphs;
|
hb_vector_t<hb_codepoint_t> &glyph_ids = plan->glyphs;
|
||||||
char *glyf_prime_data_next = glyf_prime_data;
|
char *glyf_prime_data_next = glyf_prime_data;
|
||||||
|
@ -170,8 +170,8 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan,
|
||||||
for (unsigned int i = 0; i < glyph_ids.len; i++)
|
for (unsigned int i = 0; i < glyph_ids.len; i++)
|
||||||
{
|
{
|
||||||
unsigned int start_offset, end_offset;
|
unsigned int start_offset, end_offset;
|
||||||
if (unlikely (!(glyf.get_offsets (glyph_ids[i], &start_offset, &end_offset)
|
if (unlikely (!(glyf.get_offsets (glyph_ids[i], &start_offset, &end_offset) &&
|
||||||
&& glyf.remove_padding(start_offset, &end_offset))))
|
glyf.remove_padding (start_offset, &end_offset))))
|
||||||
end_offset = start_offset = 0;
|
end_offset = start_offset = 0;
|
||||||
|
|
||||||
unsigned int instruction_start = instruction_ranges[i * 2];
|
unsigned int instruction_start = instruction_ranges[i * 2];
|
||||||
|
@ -181,10 +181,10 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan,
|
||||||
|
|
||||||
if (glyf_prime_data_next + length > glyf_prime_data + glyf_prime_size)
|
if (glyf_prime_data_next + length > glyf_prime_data + glyf_prime_size)
|
||||||
{
|
{
|
||||||
DEBUG_MSG (SUBSET,
|
DEBUG_MSG(SUBSET,
|
||||||
nullptr,
|
nullptr,
|
||||||
"WARNING: Attempted to write an out of bounds glyph entry for gid %d (length %d)",
|
"WARNING: Attempted to write an out of bounds glyph entry for gid %d (length %d)",
|
||||||
i, length);
|
i, length);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,18 +197,18 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan,
|
||||||
/* if the instructions end at the end this was a composite glyph, else simple */
|
/* if the instructions end at the end this was a composite glyph, else simple */
|
||||||
if (instruction_end == end_offset)
|
if (instruction_end == end_offset)
|
||||||
{
|
{
|
||||||
if (unlikely (!_remove_composite_instruction_flag (glyf_prime_data_next, length))) return false;
|
if (unlikely (!_remove_composite_instruction_flag (glyf_prime_data_next, length))) return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
/* zero instruction length, which is just before instruction_start */
|
/* zero instruction length, which is just before instruction_start */
|
||||||
memset (glyf_prime_data_next + instruction_start - start_offset - 2, 0, 2);
|
memset (glyf_prime_data_next + instruction_start - start_offset - 2, 0, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
success = success && _write_loca_entry (i,
|
success = success && _write_loca_entry (i,
|
||||||
glyf_prime_data_next - glyf_prime_data,
|
glyf_prime_data_next - glyf_prime_data,
|
||||||
use_short_loca,
|
use_short_loca,
|
||||||
loca_prime_data,
|
loca_prime_data,
|
||||||
loca_prime_size);
|
loca_prime_size);
|
||||||
_update_components (plan, glyf_prime_data_next, length);
|
_update_components (plan, glyf_prime_data_next, length);
|
||||||
|
|
||||||
// TODO: don't align to two bytes if using long loca.
|
// TODO: don't align to two bytes if using long loca.
|
||||||
|
@ -216,20 +216,20 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan,
|
||||||
}
|
}
|
||||||
|
|
||||||
success = success && _write_loca_entry (glyph_ids.len,
|
success = success && _write_loca_entry (glyph_ids.len,
|
||||||
glyf_prime_data_next - glyf_prime_data,
|
glyf_prime_data_next - glyf_prime_data,
|
||||||
use_short_loca,
|
use_short_loca,
|
||||||
loca_prime_data,
|
loca_prime_data,
|
||||||
loca_prime_size);
|
loca_prime_size);
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
_hb_subset_glyf_and_loca (const OT::glyf::accelerator_t &glyf,
|
_hb_subset_glyf_and_loca (const OT::glyf::accelerator_t &glyf,
|
||||||
const char *glyf_data,
|
const char *glyf_data,
|
||||||
hb_subset_plan_t *plan,
|
hb_subset_plan_t *plan,
|
||||||
bool *use_short_loca,
|
bool *use_short_loca,
|
||||||
hb_blob_t **glyf_prime /* OUT */,
|
hb_blob_t **glyf_prime /* OUT */,
|
||||||
hb_blob_t **loca_prime /* OUT */)
|
hb_blob_t **loca_prime /* OUT */)
|
||||||
{
|
{
|
||||||
// TODO(grieger): Sanity check allocation size for the new table.
|
// TODO(grieger): Sanity check allocation size for the new table.
|
||||||
hb_vector_t<hb_codepoint_t> &glyphs_to_retain = plan->glyphs;
|
hb_vector_t<hb_codepoint_t> &glyphs_to_retain = plan->glyphs;
|
||||||
|
@ -237,43 +237,43 @@ _hb_subset_glyf_and_loca (const OT::glyf::accelerator_t &glyf,
|
||||||
unsigned int glyf_prime_size;
|
unsigned int glyf_prime_size;
|
||||||
unsigned int loca_prime_size;
|
unsigned int loca_prime_size;
|
||||||
hb_vector_t<unsigned int> instruction_ranges;
|
hb_vector_t<unsigned int> instruction_ranges;
|
||||||
instruction_ranges.init();
|
instruction_ranges.init ();
|
||||||
|
|
||||||
if (unlikely (!_calculate_glyf_and_loca_prime_size (glyf,
|
if (unlikely (!_calculate_glyf_and_loca_prime_size (glyf,
|
||||||
glyphs_to_retain,
|
glyphs_to_retain,
|
||||||
plan->drop_hints,
|
plan->drop_hints,
|
||||||
use_short_loca,
|
use_short_loca,
|
||||||
&glyf_prime_size,
|
&glyf_prime_size,
|
||||||
&loca_prime_size,
|
&loca_prime_size,
|
||||||
&instruction_ranges))) {
|
&instruction_ranges))) {
|
||||||
instruction_ranges.fini();
|
instruction_ranges.fini ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *glyf_prime_data = (char *) calloc (1, glyf_prime_size);
|
char *glyf_prime_data = (char *) calloc (1, glyf_prime_size);
|
||||||
char *loca_prime_data = (char *) calloc (1, loca_prime_size);
|
char *loca_prime_data = (char *) calloc (1, loca_prime_size);
|
||||||
if (unlikely (!_write_glyf_and_loca_prime (plan, glyf, glyf_data,
|
if (unlikely (!_write_glyf_and_loca_prime (plan, glyf, glyf_data,
|
||||||
*use_short_loca,
|
*use_short_loca,
|
||||||
instruction_ranges,
|
instruction_ranges,
|
||||||
glyf_prime_size, glyf_prime_data,
|
glyf_prime_size, glyf_prime_data,
|
||||||
loca_prime_size, loca_prime_data))) {
|
loca_prime_size, loca_prime_data))) {
|
||||||
free (glyf_prime_data);
|
free (glyf_prime_data);
|
||||||
free (loca_prime_data);
|
free (loca_prime_data);
|
||||||
instruction_ranges.fini();
|
instruction_ranges.fini ();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
instruction_ranges.fini();
|
instruction_ranges.fini ();
|
||||||
|
|
||||||
*glyf_prime = hb_blob_create (glyf_prime_data,
|
*glyf_prime = hb_blob_create (glyf_prime_data,
|
||||||
glyf_prime_size,
|
glyf_prime_size,
|
||||||
HB_MEMORY_MODE_READONLY,
|
HB_MEMORY_MODE_READONLY,
|
||||||
glyf_prime_data,
|
glyf_prime_data,
|
||||||
free);
|
free);
|
||||||
*loca_prime = hb_blob_create (loca_prime_data,
|
*loca_prime = hb_blob_create (loca_prime_data,
|
||||||
loca_prime_size,
|
loca_prime_size,
|
||||||
HB_MEMORY_MODE_READONLY,
|
HB_MEMORY_MODE_READONLY,
|
||||||
loca_prime_data,
|
loca_prime_data,
|
||||||
free);
|
free);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,24 +287,24 @@ _hb_subset_glyf_and_loca (const OT::glyf::accelerator_t &glyf,
|
||||||
**/
|
**/
|
||||||
bool
|
bool
|
||||||
hb_subset_glyf_and_loca (hb_subset_plan_t *plan,
|
hb_subset_glyf_and_loca (hb_subset_plan_t *plan,
|
||||||
bool *use_short_loca, /* OUT */
|
bool *use_short_loca, /* OUT */
|
||||||
hb_blob_t **glyf_prime, /* OUT */
|
hb_blob_t **glyf_prime, /* OUT */
|
||||||
hb_blob_t **loca_prime /* OUT */)
|
hb_blob_t **loca_prime /* OUT */)
|
||||||
{
|
{
|
||||||
hb_blob_t *glyf_blob = hb_sanitize_context_t ().reference_table<OT::glyf> (plan->source);
|
hb_blob_t *glyf_blob = hb_sanitize_context_t ().reference_table<OT::glyf> (plan->source);
|
||||||
const char *glyf_data = hb_blob_get_data(glyf_blob, nullptr);
|
const char *glyf_data = hb_blob_get_data (glyf_blob, nullptr);
|
||||||
|
|
||||||
OT::glyf::accelerator_t glyf;
|
OT::glyf::accelerator_t glyf;
|
||||||
glyf.init(plan->source);
|
glyf.init (plan->source);
|
||||||
bool result = _hb_subset_glyf_and_loca (glyf,
|
bool result = _hb_subset_glyf_and_loca (glyf,
|
||||||
glyf_data,
|
glyf_data,
|
||||||
plan,
|
plan,
|
||||||
use_short_loca,
|
use_short_loca,
|
||||||
glyf_prime,
|
glyf_prime,
|
||||||
loca_prime);
|
loca_prime);
|
||||||
|
|
||||||
hb_blob_destroy (glyf_blob);
|
hb_blob_destroy (glyf_blob);
|
||||||
glyf.fini();
|
glyf.fini ();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,8 +33,8 @@
|
||||||
|
|
||||||
HB_INTERNAL bool
|
HB_INTERNAL bool
|
||||||
hb_subset_glyf_and_loca (hb_subset_plan_t *plan,
|
hb_subset_glyf_and_loca (hb_subset_plan_t *plan,
|
||||||
bool *use_short_loca, /* OUT */
|
bool *use_short_loca, /* OUT */
|
||||||
hb_blob_t **glyf_prime /* OUT */,
|
hb_blob_t **glyf_prime /* OUT */,
|
||||||
hb_blob_t **loca_prime /* OUT */);
|
hb_blob_t **loca_prime /* OUT */);
|
||||||
|
|
||||||
#endif /* HB_SUBSET_GLYF_HH */
|
#endif /* HB_SUBSET_GLYF_HH */
|
||||||
|
|
|
@ -72,7 +72,7 @@ hb_subset_input_reference (hb_subset_input_t *subset_input)
|
||||||
* Since: 1.8.0
|
* Since: 1.8.0
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
hb_subset_input_destroy(hb_subset_input_t *subset_input)
|
hb_subset_input_destroy (hb_subset_input_t *subset_input)
|
||||||
{
|
{
|
||||||
if (!hb_object_destroy (subset_input)) return;
|
if (!hb_object_destroy (subset_input)) return;
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ hb_subset_input_get_drop_hints (hb_subset_input_t *subset_input)
|
||||||
|
|
||||||
HB_EXTERN void
|
HB_EXTERN void
|
||||||
hb_subset_input_set_drop_layout (hb_subset_input_t *subset_input,
|
hb_subset_input_set_drop_layout (hb_subset_input_t *subset_input,
|
||||||
hb_bool_t drop_layout)
|
hb_bool_t drop_layout)
|
||||||
{
|
{
|
||||||
subset_input->drop_layout = drop_layout;
|
subset_input->drop_layout = drop_layout;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,24 +71,35 @@ _gsub_closure (hb_face_t *face, hb_set_t *gids_to_retain)
|
||||||
{
|
{
|
||||||
hb_set_t lookup_indices;
|
hb_set_t lookup_indices;
|
||||||
hb_ot_layout_collect_lookups (face,
|
hb_ot_layout_collect_lookups (face,
|
||||||
HB_OT_TAG_GSUB,
|
HB_OT_TAG_GSUB,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
&lookup_indices);
|
&lookup_indices);
|
||||||
hb_ot_layout_lookups_substitute_closure (face,
|
hb_ot_layout_lookups_substitute_closure (face,
|
||||||
&lookup_indices,
|
&lookup_indices,
|
||||||
gids_to_retain);
|
gids_to_retain);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_remove_invalid_gids (hb_set_t *glyphs,
|
||||||
|
unsigned int num_glyphs)
|
||||||
|
{
|
||||||
|
hb_codepoint_t gid = HB_SET_VALUE_INVALID;
|
||||||
|
while (glyphs->next (&gid))
|
||||||
|
{
|
||||||
|
if (gid >= num_glyphs)
|
||||||
|
glyphs->del (gid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static hb_set_t *
|
static hb_set_t *
|
||||||
_populate_gids_to_retain (hb_face_t *face,
|
_populate_gids_to_retain (hb_face_t *face,
|
||||||
const hb_set_t *unicodes,
|
const hb_set_t *unicodes,
|
||||||
bool close_over_gsub,
|
bool close_over_gsub,
|
||||||
hb_set_t *unicodes_to_retain,
|
hb_set_t *unicodes_to_retain,
|
||||||
hb_map_t *codepoint_to_glyph,
|
hb_map_t *codepoint_to_glyph,
|
||||||
hb_vector_t<hb_codepoint_t> *glyphs)
|
hb_vector_t<hb_codepoint_t> *glyphs)
|
||||||
{
|
{
|
||||||
OT::cmap::accelerator_t cmap;
|
OT::cmap::accelerator_t cmap;
|
||||||
OT::glyf::accelerator_t glyf;
|
OT::glyf::accelerator_t glyf;
|
||||||
|
@ -130,6 +141,8 @@ _populate_gids_to_retain (hb_face_t *face,
|
||||||
}
|
}
|
||||||
hb_set_destroy (initial_gids_to_retain);
|
hb_set_destroy (initial_gids_to_retain);
|
||||||
|
|
||||||
|
_remove_invalid_gids (all_gids_to_retain, face->get_num_glyphs ());
|
||||||
|
|
||||||
glyphs->alloc (all_gids_to_retain->get_population ());
|
glyphs->alloc (all_gids_to_retain->get_population ());
|
||||||
gid = HB_SET_VALUE_INVALID;
|
gid = HB_SET_VALUE_INVALID;
|
||||||
while (all_gids_to_retain->next (&gid))
|
while (all_gids_to_retain->next (&gid))
|
||||||
|
@ -144,7 +157,7 @@ _populate_gids_to_retain (hb_face_t *face,
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_create_old_gid_to_new_gid_map (const hb_vector_t<hb_codepoint_t> &glyphs,
|
_create_old_gid_to_new_gid_map (const hb_vector_t<hb_codepoint_t> &glyphs,
|
||||||
hb_map_t *glyph_map)
|
hb_map_t *glyph_map)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < glyphs.len; i++) {
|
for (unsigned int i = 0; i < glyphs.len; i++) {
|
||||||
glyph_map->set (glyphs[i], i);
|
glyph_map->set (glyphs[i], i);
|
||||||
|
@ -163,7 +176,7 @@ _create_old_gid_to_new_gid_map (const hb_vector_t<hb_codepoint_t> &glyphs,
|
||||||
**/
|
**/
|
||||||
hb_subset_plan_t *
|
hb_subset_plan_t *
|
||||||
hb_subset_plan_create (hb_face_t *face,
|
hb_subset_plan_create (hb_face_t *face,
|
||||||
hb_subset_input_t *input)
|
hb_subset_input_t *input)
|
||||||
{
|
{
|
||||||
hb_subset_plan_t *plan = hb_object_create<hb_subset_plan_t> ();
|
hb_subset_plan_t *plan = hb_object_create<hb_subset_plan_t> ();
|
||||||
|
|
||||||
|
@ -183,7 +196,7 @@ hb_subset_plan_create (hb_face_t *face,
|
||||||
plan->codepoint_to_glyph,
|
plan->codepoint_to_glyph,
|
||||||
&plan->glyphs);
|
&plan->glyphs);
|
||||||
_create_old_gid_to_new_gid_map (plan->glyphs,
|
_create_old_gid_to_new_gid_map (plan->glyphs,
|
||||||
plan->glyph_map);
|
plan->glyph_map);
|
||||||
|
|
||||||
return plan;
|
return plan;
|
||||||
}
|
}
|
||||||
|
@ -199,7 +212,7 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan)
|
||||||
if (!hb_object_destroy (plan)) return;
|
if (!hb_object_destroy (plan)) return;
|
||||||
|
|
||||||
hb_set_destroy (plan->unicodes);
|
hb_set_destroy (plan->unicodes);
|
||||||
plan->glyphs.fini();
|
plan->glyphs.fini ();
|
||||||
hb_face_destroy (plan->source);
|
hb_face_destroy (plan->source);
|
||||||
hb_face_destroy (plan->dest);
|
hb_face_destroy (plan->dest);
|
||||||
hb_map_destroy (plan->codepoint_to_glyph);
|
hb_map_destroy (plan->codepoint_to_glyph);
|
||||||
|
|
|
@ -57,7 +57,7 @@ struct hb_subset_plan_t
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
new_gid_for_codepoint (hb_codepoint_t codepoint,
|
new_gid_for_codepoint (hb_codepoint_t codepoint,
|
||||||
hb_codepoint_t *new_gid) const
|
hb_codepoint_t *new_gid) const
|
||||||
{
|
{
|
||||||
hb_codepoint_t old_gid = codepoint_to_glyph->get (codepoint);
|
hb_codepoint_t old_gid = codepoint_to_glyph->get (codepoint);
|
||||||
if (old_gid == HB_MAP_VALUE_INVALID)
|
if (old_gid == HB_MAP_VALUE_INVALID)
|
||||||
|
@ -68,7 +68,7 @@ struct hb_subset_plan_t
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
new_gid_for_old_gid (hb_codepoint_t old_gid,
|
new_gid_for_old_gid (hb_codepoint_t old_gid,
|
||||||
hb_codepoint_t *new_gid) const
|
hb_codepoint_t *new_gid) const
|
||||||
{
|
{
|
||||||
hb_codepoint_t gid = glyph_map->get (old_gid);
|
hb_codepoint_t gid = glyph_map->get (old_gid);
|
||||||
if (gid == HB_MAP_VALUE_INVALID)
|
if (gid == HB_MAP_VALUE_INVALID)
|
||||||
|
@ -80,13 +80,13 @@ struct hb_subset_plan_t
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
add_table (hb_tag_t tag,
|
add_table (hb_tag_t tag,
|
||||||
hb_blob_t *contents)
|
hb_blob_t *contents)
|
||||||
{
|
{
|
||||||
hb_blob_t *source_blob = source->reference_table (tag);
|
hb_blob_t *source_blob = source->reference_table (tag);
|
||||||
DEBUG_MSG(SUBSET, nullptr, "add table %c%c%c%c, dest %d bytes, source %d bytes",
|
DEBUG_MSG(SUBSET, nullptr, "add table %c%c%c%c, dest %d bytes, source %d bytes",
|
||||||
HB_UNTAG(tag),
|
HB_UNTAG(tag),
|
||||||
hb_blob_get_length (contents),
|
hb_blob_get_length (contents),
|
||||||
hb_blob_get_length (source_blob));
|
hb_blob_get_length (source_blob));
|
||||||
hb_blob_destroy (source_blob);
|
hb_blob_destroy (source_blob);
|
||||||
return hb_face_builder_add_table (dest, tag, contents);
|
return hb_face_builder_add_table (dest, tag, contents);
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,10 +73,10 @@ _subset2 (hb_subset_plan_t *plan)
|
||||||
{
|
{
|
||||||
hb_vector_t<char> buf;
|
hb_vector_t<char> buf;
|
||||||
unsigned int buf_size = _plan_estimate_subset_table_size (plan, source_blob->length);
|
unsigned int buf_size = _plan_estimate_subset_table_size (plan, source_blob->length);
|
||||||
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG(tag), buf_size);
|
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c initial estimated table size: %u bytes.", HB_UNTAG (tag), buf_size);
|
||||||
if (unlikely (!buf.alloc (buf_size)))
|
if (unlikely (!buf.alloc (buf_size)))
|
||||||
{
|
{
|
||||||
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG(tag), buf_size);
|
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to allocate %u bytes.", HB_UNTAG (tag), buf_size);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
retry:
|
retry:
|
||||||
|
@ -86,10 +86,10 @@ _subset2 (hb_subset_plan_t *plan)
|
||||||
if (serializer.ran_out_of_room)
|
if (serializer.ran_out_of_room)
|
||||||
{
|
{
|
||||||
buf_size += (buf_size >> 1) + 32;
|
buf_size += (buf_size >> 1) + 32;
|
||||||
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", HB_UNTAG(tag), buf_size);
|
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c ran out of room; reallocating to %u bytes.", HB_UNTAG (tag), buf_size);
|
||||||
if (unlikely (!buf.alloc (buf_size)))
|
if (unlikely (!buf.alloc (buf_size)))
|
||||||
{
|
{
|
||||||
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", HB_UNTAG(tag), buf_size);
|
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c failed to reallocate %u bytes.", HB_UNTAG (tag), buf_size);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
goto retry;
|
goto retry;
|
||||||
|
@ -97,21 +97,21 @@ _subset2 (hb_subset_plan_t *plan)
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
hb_blob_t *dest_blob = serializer.copy_blob ();
|
hb_blob_t *dest_blob = serializer.copy_blob ();
|
||||||
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG(tag), dest_blob->length);
|
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c final subset table size: %u bytes.", HB_UNTAG (tag), dest_blob->length);
|
||||||
result = c.plan->add_table (tag, dest_blob);
|
result = c.plan->add_table (tag, dest_blob);
|
||||||
hb_blob_destroy (dest_blob);
|
hb_blob_destroy (dest_blob);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG(tag));
|
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset table subsetted to empty.", HB_UNTAG (tag));
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG(tag));
|
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag));
|
||||||
|
|
||||||
hb_blob_destroy (source_blob);
|
hb_blob_destroy (source_blob);
|
||||||
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG(tag), result ? "success" : "FAILED!");
|
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG (tag), result ? "success" : "FAILED!");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,19 +127,19 @@ _subset (hb_subset_plan_t *plan)
|
||||||
if (source_blob->data)
|
if (source_blob->data)
|
||||||
result = table->subset (plan);
|
result = table->subset (plan);
|
||||||
else
|
else
|
||||||
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG(tag));
|
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset sanitize failed on source table.", HB_UNTAG (tag));
|
||||||
|
|
||||||
hb_blob_destroy (source_blob);
|
hb_blob_destroy (source_blob);
|
||||||
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG(tag), result ? "success" : "FAILED!");
|
DEBUG_MSG(SUBSET, nullptr, "OT::%c%c%c%c::subset %s", HB_UNTAG (tag), result ? "success" : "FAILED!");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
_subset_table (hb_subset_plan_t *plan,
|
_subset_table (hb_subset_plan_t *plan,
|
||||||
hb_tag_t tag)
|
hb_tag_t tag)
|
||||||
{
|
{
|
||||||
DEBUG_MSG(SUBSET, nullptr, "begin subset %c%c%c%c", HB_UNTAG(tag));
|
DEBUG_MSG(SUBSET, nullptr, "begin subset %c%c%c%c", HB_UNTAG (tag));
|
||||||
bool result = true;
|
bool result = true;
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case HB_OT_TAG_glyf:
|
case HB_OT_TAG_glyf:
|
||||||
|
@ -197,20 +197,20 @@ _subset_table (hb_subset_plan_t *plan,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
hb_blob_t *source_table = hb_face_reference_table(plan->source, tag);
|
hb_blob_t *source_table = hb_face_reference_table (plan->source, tag);
|
||||||
if (likely (source_table))
|
if (likely (source_table))
|
||||||
result = plan->add_table(tag, source_table);
|
result = plan->add_table (tag, source_table);
|
||||||
else
|
else
|
||||||
result = false;
|
result = false;
|
||||||
hb_blob_destroy (source_table);
|
hb_blob_destroy (source_table);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
DEBUG_MSG(SUBSET, nullptr, "subset %c%c%c%c %s", HB_UNTAG(tag), result ? "ok" : "FAILED");
|
DEBUG_MSG(SUBSET, nullptr, "subset %c%c%c%c %s", HB_UNTAG (tag), result ? "ok" : "FAILED");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
_should_drop_table(hb_subset_plan_t *plan, hb_tag_t tag)
|
_should_drop_table (hb_subset_plan_t *plan, hb_tag_t tag)
|
||||||
{
|
{
|
||||||
switch (tag) {
|
switch (tag) {
|
||||||
case HB_TAG ('c', 'v', 'a', 'r'): /* hint table, fallthrough */
|
case HB_TAG ('c', 'v', 'a', 'r'): /* hint table, fallthrough */
|
||||||
|
@ -259,9 +259,9 @@ _should_drop_table(hb_subset_plan_t *plan, hb_tag_t tag)
|
||||||
**/
|
**/
|
||||||
hb_face_t *
|
hb_face_t *
|
||||||
hb_subset (hb_face_t *source,
|
hb_subset (hb_face_t *source,
|
||||||
hb_subset_input_t *input)
|
hb_subset_input_t *input)
|
||||||
{
|
{
|
||||||
if (unlikely (!input || !source)) return hb_face_get_empty();
|
if (unlikely (!input || !source)) return hb_face_get_empty ();
|
||||||
|
|
||||||
hb_subset_plan_t *plan = hb_subset_plan_create (source, input);
|
hb_subset_plan_t *plan = hb_subset_plan_create (source, input);
|
||||||
|
|
||||||
|
@ -274,17 +274,17 @@ hb_subset (hb_face_t *source,
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
{
|
{
|
||||||
hb_tag_t tag = table_tags[i];
|
hb_tag_t tag = table_tags[i];
|
||||||
if (_should_drop_table(plan, tag))
|
if (_should_drop_table (plan, tag))
|
||||||
{
|
{
|
||||||
DEBUG_MSG(SUBSET, nullptr, "drop %c%c%c%c", HB_UNTAG(tag));
|
DEBUG_MSG(SUBSET, nullptr, "drop %c%c%c%c", HB_UNTAG (tag));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
success = success && _subset_table (plan, tag);
|
success = success && _subset_table (plan, tag);
|
||||||
}
|
}
|
||||||
offset += count;
|
offset += count;
|
||||||
} while (success && count == ARRAY_LENGTH (table_tags));
|
} while (success && count == ARRAY_LENGTH (table_tags));
|
||||||
|
|
||||||
hb_face_t *result = success ? hb_face_reference(plan->dest) : hb_face_get_empty();
|
hb_face_t *result = success ? hb_face_reference (plan->dest) : hb_face_get_empty ();
|
||||||
hb_subset_plan_destroy (plan);
|
hb_subset_plan_destroy (plan);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,7 @@ hb_subset_input_get_drop_hints (hb_subset_input_t *subset_input);
|
||||||
|
|
||||||
HB_EXTERN void
|
HB_EXTERN void
|
||||||
hb_subset_input_set_drop_layout (hb_subset_input_t *subset_input,
|
hb_subset_input_set_drop_layout (hb_subset_input_t *subset_input,
|
||||||
hb_bool_t drop_layout);
|
hb_bool_t drop_layout);
|
||||||
HB_EXTERN hb_bool_t
|
HB_EXTERN hb_bool_t
|
||||||
hb_subset_input_get_drop_layout (hb_subset_input_t *subset_input);
|
hb_subset_input_get_drop_layout (hb_subset_input_t *subset_input);
|
||||||
|
|
||||||
|
@ -72,10 +72,9 @@ hb_subset_input_set_desubroutinize (hb_subset_input_t *subset_input,
|
||||||
HB_EXTERN hb_bool_t
|
HB_EXTERN hb_bool_t
|
||||||
hb_subset_input_get_desubroutinize (hb_subset_input_t *subset_input);
|
hb_subset_input_get_desubroutinize (hb_subset_input_t *subset_input);
|
||||||
|
|
||||||
/* hb_subset() */
|
/* hb_subset () */
|
||||||
HB_EXTERN hb_face_t *
|
HB_EXTERN hb_face_t *
|
||||||
hb_subset (hb_face_t *source,
|
hb_subset (hb_face_t *source, hb_subset_input_t *input);
|
||||||
hb_subset_input_t *input);
|
|
||||||
|
|
||||||
|
|
||||||
HB_END_DECLS
|
HB_END_DECLS
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "hb.hh"
|
#include "hb.hh"
|
||||||
#define HB_SHAPER uniscribe
|
|
||||||
#include "hb-shaper-impl.hh"
|
#include "hb-shaper-impl.hh"
|
||||||
|
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -314,9 +313,6 @@ struct range_record_t {
|
||||||
unsigned int index_last; /* == end - 1 */
|
unsigned int index_last; /* == end - 1 */
|
||||||
};
|
};
|
||||||
|
|
||||||
HB_SHAPER_DATA_ENSURE_DEFINE(uniscribe, face);
|
|
||||||
HB_SHAPER_DATA_ENSURE_DEFINE(uniscribe, font);
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* shaper face data
|
* shaper face data
|
||||||
|
@ -503,11 +499,12 @@ _hb_uniscribe_shaper_face_data_destroy (hb_uniscribe_face_data_t *data)
|
||||||
* shaper font data
|
* shaper font data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct hb_uniscribe_font_data_t {
|
struct hb_uniscribe_font_data_t
|
||||||
|
{
|
||||||
HDC hdc;
|
HDC hdc;
|
||||||
LOGFONTW log_font;
|
mutable LOGFONTW log_font;
|
||||||
HFONT hfont;
|
HFONT hfont;
|
||||||
SCRIPT_CACHE script_cache;
|
mutable SCRIPT_CACHE script_cache;
|
||||||
double x_mult, y_mult; /* From LOGFONT space to HB space. */
|
double x_mult, y_mult; /* From LOGFONT space to HB space. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -520,10 +517,7 @@ populate_log_font (LOGFONTW *lf,
|
||||||
lf->lfHeight = - (int) font_size;
|
lf->lfHeight = - (int) font_size;
|
||||||
lf->lfCharSet = DEFAULT_CHARSET;
|
lf->lfCharSet = DEFAULT_CHARSET;
|
||||||
|
|
||||||
hb_face_t *face = font->face;
|
memcpy (lf->lfFaceName, font->face->data.uniscribe->face_name, sizeof (lf->lfFaceName));
|
||||||
hb_uniscribe_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
|
|
||||||
|
|
||||||
memcpy (lf->lfFaceName, face_data->face_name, sizeof (lf->lfFaceName));
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -531,8 +525,6 @@ populate_log_font (LOGFONTW *lf,
|
||||||
hb_uniscribe_font_data_t *
|
hb_uniscribe_font_data_t *
|
||||||
_hb_uniscribe_shaper_font_data_create (hb_font_t *font)
|
_hb_uniscribe_shaper_font_data_create (hb_font_t *font)
|
||||||
{
|
{
|
||||||
if (unlikely (!hb_uniscribe_shaper_face_data_ensure (font->face))) return nullptr;
|
|
||||||
|
|
||||||
hb_uniscribe_font_data_t *data = (hb_uniscribe_font_data_t *) calloc (1, sizeof (hb_uniscribe_font_data_t));
|
hb_uniscribe_font_data_t *data = (hb_uniscribe_font_data_t *) calloc (1, sizeof (hb_uniscribe_font_data_t));
|
||||||
if (unlikely (!data))
|
if (unlikely (!data))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -586,17 +578,15 @@ _hb_uniscribe_shaper_font_data_destroy (hb_uniscribe_font_data_t *data)
|
||||||
LOGFONTW *
|
LOGFONTW *
|
||||||
hb_uniscribe_font_get_logfontw (hb_font_t *font)
|
hb_uniscribe_font_get_logfontw (hb_font_t *font)
|
||||||
{
|
{
|
||||||
if (unlikely (!hb_uniscribe_shaper_font_data_ensure (font))) return nullptr;
|
const hb_uniscribe_font_data_t *data = font->data.uniscribe;
|
||||||
hb_uniscribe_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
|
return data ? &data->log_font : nullptr;
|
||||||
return &font_data->log_font;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HFONT
|
HFONT
|
||||||
hb_uniscribe_font_get_hfont (hb_font_t *font)
|
hb_uniscribe_font_get_hfont (hb_font_t *font)
|
||||||
{
|
{
|
||||||
if (unlikely (!hb_uniscribe_shaper_font_data_ensure (font))) return nullptr;
|
const hb_uniscribe_font_data_t *data = font->data.uniscribe;
|
||||||
hb_uniscribe_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
|
return data ? data->hfont : nullptr;
|
||||||
return font_data->hfont;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -613,8 +603,8 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan,
|
||||||
unsigned int num_features)
|
unsigned int num_features)
|
||||||
{
|
{
|
||||||
hb_face_t *face = font->face;
|
hb_face_t *face = font->face;
|
||||||
hb_uniscribe_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
|
const hb_uniscribe_face_data_t *face_data = face->data.uniscribe;
|
||||||
hb_uniscribe_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
|
const hb_uniscribe_font_data_t *font_data = font->data.uniscribe;
|
||||||
hb_uniscribe_shaper_funcs_t *funcs = face_data->funcs;
|
hb_uniscribe_shaper_funcs_t *funcs = face_data->funcs;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -94,7 +94,7 @@ struct subset_consumer_t
|
||||||
|
|
||||||
hb_face_t *face = hb_font_get_face (font);
|
hb_face_t *face = hb_font_get_face (font);
|
||||||
|
|
||||||
hb_face_t *new_face = hb_subset(face, input);
|
hb_face_t *new_face = hb_subset (face, input);
|
||||||
hb_blob_t *result = hb_face_reference_blob (new_face);
|
hb_blob_t *result = hb_face_reference_blob (new_face);
|
||||||
|
|
||||||
failed = !hb_blob_get_length (result);
|
failed = !hb_blob_get_length (result);
|
||||||
|
|
Loading…
Reference in New Issue