[shaper] Rewrite shaper data code to be more template-driven than macro-driven

This commit is contained in:
Behdad Esfahbod 2018-11-16 02:29:13 -05:00
parent cb4bf85b14
commit ce5da0f36a
14 changed files with 128 additions and 148 deletions

View File

@ -26,8 +26,6 @@
* Google Author(s): Behdad Esfahbod
*/
#define HB_SHAPER coretext
#include "hb.hh"
#include "hb-shaper-impl.hh"
@ -101,8 +99,8 @@ _hb_cg_font_release (void *data)
}
HB_SHAPER_DATA_ENSURE_DEFINE(coretext, face);
HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(coretext, font,
/* XXX TODO */
//HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(coretext, font,
fabs (CTFontGetSize((CTFontRef) data) - coretext_font_size_from_ptem (font->ptem)) <= .5
);
@ -312,8 +310,7 @@ hb_coretext_face_create (CGFontRef cg_font)
CGFontRef
hb_coretext_face_get_cg_font (hb_face_t *face)
{
if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return nullptr;
return (CGFontRef) HB_SHAPER_DATA_GET (face);
return (CGFontRef) (const void *) face->data.coretext;
}
@ -322,7 +319,7 @@ _hb_coretext_shaper_font_data_create (hb_font_t *font)
{
hb_face_t *face = font->face;
if (unlikely (!hb_coretext_shaper_face_data_ensure (face))) return nullptr;
CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face);
CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext;
CTFontRef ct_font = create_ct_font (cg_font, coretext_font_size_from_ptem (font->ptem));
@ -368,7 +365,7 @@ CTFontRef
hb_coretext_font_get_ct_font (hb_font_t *font)
{
if (unlikely (!hb_coretext_shaper_font_data_ensure (font))) return nullptr;
return (CTFontRef) HB_SHAPER_DATA_GET (font);
return (CTFontRef) (const void *) font->data.coretext;
}
@ -427,8 +424,8 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
unsigned int num_features)
{
hb_face_t *face = font->face;
CGFontRef cg_font = (CGFontRef) HB_SHAPER_DATA_GET (face);
CTFontRef ct_font = (CTFontRef) HB_SHAPER_DATA_GET (font);
CGFontRef cg_font = (CGFontRef) (const void *) face->data.coretext;
CTFontRef ct_font = (CTFontRef) (const void *) font->data.coretext;
CGFloat ct_font_size = CTFontGetSize (ct_font);
CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size;

View File

@ -23,7 +23,6 @@
*/
#include "hb.hh"
#define HB_SHAPER directwrite
#include "hb-shaper-impl.hh"
#include <DWrite_1.h>
@ -31,10 +30,6 @@
#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
* to override malloc/free, we will redefine new/delete so users
@ -534,8 +529,8 @@ _hb_directwrite_shape_full (hb_shape_plan_t *shape_plan,
float lineWidth)
{
hb_face_t *face = font->face;
hb_directwrite_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
hb_directwrite_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
const hb_directwrite_face_data_t *face_data = face->data.directwrite;
const hb_directwrite_font_data_t *font_data = font->data.directwrite;
IDWriteFactory *dwriteFactory = face_data->dwriteFactory;
IDWriteFontFace *fontFace = face_data->fontFace;

View File

@ -90,12 +90,6 @@ DEFINE_NULL_INSTANCE (hb_face_t) =
HB_ATOMIC_INT_INIT (1000), /* upem */
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. */
};
@ -131,6 +125,7 @@ hb_face_create_for_tables (hb_reference_table_func_t reference_table_func,
face->num_glyphs.set_relaxed (-1);
face->data.init0 (face);
face->table.init0 (face);
return face;
@ -272,10 +267,7 @@ hb_face_destroy (hb_face_t *face)
node = next;
}
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, face);
#include "hb-shaper-list.hh"
#undef HB_SHAPER_IMPLEMENT
face->data.fini ();
face->table.fini ();
if (face->destroy)

View File

@ -40,6 +40,10 @@
* 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
{
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 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. */
/* Cache */
@ -102,11 +105,5 @@ struct 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 */

View File

@ -24,14 +24,9 @@
* Google Author(s): Behdad Esfahbod
*/
#define HB_SHAPER fallback
#include "hb-shaper-impl.hh"
HB_SHAPER_DATA_ENSURE_DEFINE(fallback, face);
HB_SHAPER_DATA_ENSURE_DEFINE(fallback, font);
/*
* shaper face data
*/

View File

@ -1307,14 +1307,8 @@ DEFINE_NULL_INSTANCE (hb_font_t) =
nullptr, /* coords */
const_cast<hb_font_funcs_t *> (&_hb_Null_hb_font_funcs_t),
nullptr, /* user_data */
nullptr, /* destroy */
{
#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. */
};
@ -1332,7 +1326,7 @@ _hb_font_create (hb_face_t *face)
font->parent = hb_font_get_empty ();
font->face = hb_face_reference (face);
font->klass = hb_font_funcs_get_empty ();
font->data.init0 (font);
font->x_scale = font->y_scale = hb_face_get_upem (face);
return font;
@ -1448,9 +1442,7 @@ hb_font_destroy (hb_font_t *font)
{
if (!hb_object_destroy (font)) return;
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, font);
#include "hb-shaper-list.hh"
#undef HB_SHAPER_IMPLEMENT
font->data.fini ();
if (font->destroy)
font->destroy (font->user_data);

View File

@ -96,6 +96,10 @@ DECLARE_NULL_INSTANCE (hb_font_funcs_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
{
hb_object_header_t header;
@ -119,7 +123,7 @@ struct hb_font_t
void *user_data;
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 */
@ -609,11 +613,5 @@ struct 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 */

View File

@ -26,7 +26,6 @@
* Google Author(s): Behdad Esfahbod
*/
#define HB_SHAPER graphite2
#include "hb-shaper-impl.hh"
#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
*/
@ -185,8 +180,8 @@ _hb_graphite2_shaper_face_data_destroy (hb_graphite2_face_data_t *data)
gr_face *
hb_graphite2_face_get_gr_face (hb_face_t *face)
{
if (unlikely (!hb_graphite2_shaper_face_data_ensure (face))) return nullptr;
return HB_SHAPER_DATA_GET (face)->grface;
const hb_graphite2_face_data_t *data = face->data.graphite2;
return data ? data->grface : nullptr;
}
@ -241,7 +236,7 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
unsigned int num_features)
{
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_end = lang ? strchr (lang, '-') : nullptr;

View File

@ -755,10 +755,7 @@ struct hb_data_wrapper_t
inline bool is_inert (void) const { return !get_data (); }
template <typename Stored, typename Subclass>
inline Stored * call_create (void) const
{
return Subclass::create (this->get_data ());
}
inline Stored * call_create (void) const { return Subclass::create (get_data ()); }
};
template <>
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; }
template <typename Stored, typename Funcs>
inline Stored * call_create (void) const
{
return Funcs::create ();
}
inline Stored * call_create (void) const { return Funcs::create (); }
};
template <typename T1, typename T2> struct hb_non_void_t { typedef T1 value; };
@ -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 (); }
explicit_operator inline operator bool (void) const
{ return get_stored () != Funcs::get_null (); }
template <typename C> inline operator const C * (void) const { return get (); }
inline Stored * get_stored (void) const
@ -877,7 +873,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
free (p);
}
private:
// private:
/* Must only have one pointer. */
hb_atomic_ptr_t<Stored *> instance;
};

View File

@ -26,7 +26,6 @@
* Google Author(s): Behdad Esfahbod
*/
#define HB_SHAPER ot
#include "hb-shaper-impl.hh"
#include "hb-ot-shape.hh"
@ -320,8 +319,6 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
* shaper face data
*/
HB_SHAPER_DATA_ENSURE_DEFINE(ot, face);
struct 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
*/
HB_SHAPER_DATA_ENSURE_DEFINE(ot, font);
struct hb_ot_font_data_t {};
hb_ot_font_data_t *

View File

@ -87,7 +87,7 @@ hb_shape_plan_key_t::init (bool copy,
#define HB_SHAPER_PLAN(shaper) \
HB_STMT_START { \
if (hb_##shaper##_shaper_face_data_ensure (face)) \
if (face->data.shaper) \
{ \
this->shaper_func = _hb_##shaper##_shape; \
this->shaper_name = #shaper; \
@ -386,7 +386,7 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
#define HB_SHAPER_EXECUTE(shaper) \
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_STMT_END

View File

@ -30,14 +30,9 @@
#include "hb.hh"
#include "hb-shaper.hh"
#include "hb-shape-plan.hh"
#include "hb-face.hh"
#include "hb-font.hh"
#include "hb-shape-plan.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 */

View File

@ -28,6 +28,7 @@
#define HB_SHAPER_HH
#include "hb.hh"
#include "hb-machinery.hh"
typedef hb_bool_t hb_shape_func_t (hb_shape_plan_t *shape_plan,
hb_font_t *font,
@ -49,36 +50,7 @@ HB_INTERNAL const hb_shaper_entry_t *
_hb_shapers_get (void);
/* Means: succeeded, but don't need to keep any data. */
#define HB_SHAPER_DATA_SUCCEEDED ((void *) +1)
/* 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_DATA_TYPE(shaper, object) struct HB_SHAPER_DATA_TYPE_NAME(shaper, object)
#define HB_SHAPER_DATA_INSTANCE(shaper, object, instance) (* reinterpret_cast<hb_atomic_ptr_t<HB_SHAPER_DATA_TYPE(shaper, object) *> *> (&(instance)->shaper_data.shaper))
#define HB_SHAPER_DATA(shaper, object) HB_SHAPER_DATA_INSTANCE(shaper, object, object)
#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_ENSURE_FUNC(shaper, object) hb_##shaper##_shaper_##object##_data_ensure
#define HB_SHAPER_DATA_PROTOTYPE(shaper, object) \
HB_SHAPER_DATA_TYPE (shaper, object); /* Type forward declaration. */ \
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); \
extern "C" HB_INTERNAL void \
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA_TYPE (shaper, object) *data); \
extern "C" HB_INTERNAL bool \
HB_SHAPER_DATA_ENSURE_FUNC (shaper, object) (hb_##object##_t *object)
#define HB_SHAPER_DATA_DESTROY(shaper, object) \
if (HB_SHAPER_DATA_TYPE (shaper, object) *data = HB_SHAPER_DATA (shaper, object).get ()) \
if (data != HB_SHAPER_DATA_INVALID && data != HB_SHAPER_DATA_SUCCEEDED) \
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data);
#define HB_SHAPER_DATA_ENSURE_DEFINE(shaper, object) \
HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(shaper, object, true)
#if 0
#define HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(shaper, object, condition) \
bool \
HB_SHAPER_DATA_ENSURE_FUNC(shaper, object) (hb_##object##_t *object) \
@ -111,9 +83,7 @@ HB_SHAPER_DATA_ENSURE_FUNC(shaper, object) (hb_##object##_t *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) \
if (data) \
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); \
goto retry; \
} \
@ -121,15 +91,88 @@ HB_SHAPER_DATA_ENSURE_FUNC(shaper, object) (hb_##object##_t *object) \
return data != nullptr && (void *) data != HB_SHAPER_DATA_INVALID; \
} \
static_assert (true, "") /* Require semicolon. */
#endif
/* For embedding in face / font / ... */
struct hb_shaper_data_t {
#define HB_SHAPER_IMPLEMENT(shaper) hb_atomic_ptr_t<void *> shaper;
template <typename Data, unsigned int WheresData, typename T>
struct hb_shaper_lazy_loader_t;
#define HB_SHAPER_ORDER(Shaper) \
HB_PASTE (HB_SHAPER_ORDER_, Shaper)
enum hb_shaper_order_t
{
_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_DESTROY_FUNC(shaper, object) _hb_##shaper##_shaper_##object##_data_destroy
#define HB_SHAPER_DATA_INSTANTIATE_SHAPERS(shaper, object) \
\
struct HB_SHAPER_DATA_TYPE (shaper, object); /* Type forward declaration. */ \
extern "C" HB_INTERNAL HB_SHAPER_DATA_TYPE (shaper, object) * \
HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (hb_##object##_t *object); \
extern "C" HB_INTERNAL void \
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA_TYPE (shaper, object) *shaper##_##object); \
\
template <> \
struct hb_shaper_object_data_type_t<HB_SHAPER_ORDER (shaper), hb_##object##_t> \
{ \
typedef HB_SHAPER_DATA_TYPE(shaper, object) value; \
}; \
\
template <unsigned int WheresData> \
struct hb_shaper_lazy_loader_t<hb_##object##_t, WheresData, HB_SHAPER_DATA_TYPE(shaper, object)> \
: hb_lazy_loader_t<HB_SHAPER_DATA_TYPE(shaper, object), \
hb_shaper_lazy_loader_t<hb_##object##_t, \
WheresData, \
HB_SHAPER_DATA_TYPE(shaper, object)>, \
hb_##object##_t, WheresData> \
{ \
typedef HB_SHAPER_DATA_TYPE(shaper, object) Type; \
static inline Type* create (hb_##object##_t *data) \
{ return HB_SHAPER_DATA_CREATE_FUNC (shaper, object) (data); } \
static inline Type *get_null (void) { return nullptr; } \
static inline void destroy (Type *p) { HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (p); } \
}; \
\
static_assert (true, "") /* Require semicolon. */
template <typename Object>
struct hb_shaper_object_dataset_t
{
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"
#undef HB_SHAPER_IMPLEMENT
};
#define HB_SHAPERS_COUNT (sizeof (hb_shaper_data_t) / sizeof (void *))
#endif /* HB_SHAPER_HH */

View File

@ -25,7 +25,6 @@
*/
#include "hb.hh"
#define HB_SHAPER uniscribe
#include "hb-shaper-impl.hh"
#include <windows.h>
@ -314,9 +313,6 @@ struct range_record_t {
unsigned int index_last; /* == end - 1 */
};
HB_SHAPER_DATA_ENSURE_DEFINE(uniscribe, face);
HB_SHAPER_DATA_ENSURE_DEFINE(uniscribe, font);
/*
* shaper face data
@ -503,11 +499,12 @@ _hb_uniscribe_shaper_face_data_destroy (hb_uniscribe_face_data_t *data)
* shaper font data
*/
struct hb_uniscribe_font_data_t {
struct hb_uniscribe_font_data_t
{
HDC hdc;
LOGFONTW log_font;
mutable LOGFONTW log_font;
HFONT hfont;
SCRIPT_CACHE script_cache;
mutable SCRIPT_CACHE script_cache;
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->lfCharSet = DEFAULT_CHARSET;
hb_face_t *face = font->face;
hb_uniscribe_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
memcpy (lf->lfFaceName, face_data->face_name, sizeof (lf->lfFaceName));
memcpy (lf->lfFaceName, font->face->data.uniscribe->face_name, sizeof (lf->lfFaceName));
return true;
}
@ -531,8 +525,6 @@ populate_log_font (LOGFONTW *lf,
hb_uniscribe_font_data_t *
_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));
if (unlikely (!data))
return nullptr;
@ -586,17 +578,15 @@ _hb_uniscribe_shaper_font_data_destroy (hb_uniscribe_font_data_t *data)
LOGFONTW *
hb_uniscribe_font_get_logfontw (hb_font_t *font)
{
if (unlikely (!hb_uniscribe_shaper_font_data_ensure (font))) return nullptr;
hb_uniscribe_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
return &font_data->log_font;
const hb_uniscribe_font_data_t *data = font->data.uniscribe;
return data ? &data->log_font : nullptr;
}
HFONT
hb_uniscribe_font_get_hfont (hb_font_t *font)
{
if (unlikely (!hb_uniscribe_shaper_font_data_ensure (font))) return nullptr;
hb_uniscribe_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
return font_data->hfont;
const hb_uniscribe_font_data_t *data = font->data.uniscribe;
return data ? data->hfont : nullptr;
}
@ -613,8 +603,8 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan,
unsigned int num_features)
{
hb_face_t *face = font->face;
hb_uniscribe_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
hb_uniscribe_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
const hb_uniscribe_face_data_t *face_data = face->data.uniscribe;
const hb_uniscribe_font_data_t *font_data = font->data.uniscribe;
hb_uniscribe_shaper_funcs_t *funcs = face_data->funcs;
/*