Merge branch 'master' into cff-subset
This commit is contained in:
commit
b403be8ad9
|
@ -26,8 +26,6 @@
|
|||
* Google Author(s): Behdad Esfahbod
|
||||
*/
|
||||
|
||||
#define HB_SHAPER coretext
|
||||
|
||||
#include "hb.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
|
||||
get_last_resort_font_desc (void)
|
||||
{
|
||||
|
@ -312,8 +305,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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -321,8 +313,9 @@ hb_coretext_font_data_t *
|
|||
_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);
|
||||
const hb_coretext_face_data_t *face_data = face->data.coretext;
|
||||
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));
|
||||
|
||||
|
@ -341,6 +334,38 @@ _hb_coretext_shaper_font_data_destroy (hb_coretext_font_data_t *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
|
||||
*/
|
||||
|
@ -359,7 +384,7 @@ hb_coretext_font_create (CTFontRef ct_font)
|
|||
hb_font_set_ptem (font, coretext_font_size_to_ptem (CTFontGetSize(ct_font)));
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
@ -367,8 +392,8 @@ hb_coretext_font_create (CTFontRef ct_font)
|
|||
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);
|
||||
const hb_coretext_font_data_t *data = hb_coretext_font_data_sync (font);
|
||||
return data ? (CTFontRef) data : nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
@ -427,8 +452,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) hb_coretext_font_data_sync (font);
|
||||
|
||||
CGFloat ct_font_size = CTFontGetSize (ct_font);
|
||||
CGFloat x_mult = (CGFloat) font->x_scale / ct_font_size;
|
||||
|
@ -1129,9 +1154,6 @@ fail:
|
|||
* AAT shaper
|
||||
*/
|
||||
|
||||
HB_SHAPER_DATA_ENSURE_DEFINE(coretext_aat, face);
|
||||
HB_SHAPER_DATA_ENSURE_DEFINE(coretext_aat, font);
|
||||
|
||||
/*
|
||||
* shaper face data
|
||||
*/
|
||||
|
@ -1149,7 +1171,7 @@ _hb_coretext_aat_shaper_face_data_create (hb_face_t *face)
|
|||
if (hb_blob_get_length (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);
|
||||
}
|
||||
|
@ -1172,7 +1194,7 @@ struct hb_coretext_aat_font_data_t {};
|
|||
hb_coretext_aat_font_data_t *
|
||||
_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
|
||||
|
|
|
@ -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
|
||||
|
@ -240,8 +235,6 @@ struct hb_directwrite_font_data_t
|
|||
hb_directwrite_font_data_t *
|
||||
_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;
|
||||
if (unlikely (!data))
|
||||
return nullptr;
|
||||
|
@ -534,8 +527,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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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; };
|
||||
|
@ -796,7 +790,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
|
|||
{
|
||||
retry:
|
||||
Stored *p = instance.get ();
|
||||
if (unlikely (p && !this->instance.cmpexch (p, nullptr)))
|
||||
if (unlikely (p && !cmpexch (p, nullptr)))
|
||||
goto retry;
|
||||
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 (); }
|
||||
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
|
||||
|
@ -824,7 +820,7 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
|
|||
if (unlikely (!p))
|
||||
p = const_cast<Stored *> (Funcs::get_null ());
|
||||
|
||||
if (unlikely (!this->instance.cmpexch (nullptr, p)))
|
||||
if (unlikely (!cmpexch (nullptr, p)))
|
||||
{
|
||||
do_destroy (p);
|
||||
goto retry;
|
||||
|
@ -837,15 +833,10 @@ struct hb_lazy_loader_t : hb_data_wrapper_t<Data, WheresData>
|
|||
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.
|
||||
* However, to make TSan, etc, happy, we using cmpexch. */
|
||||
retry:
|
||||
Stored *p = this->instance.get ();
|
||||
if (unlikely (!this->instance.cmpexch (p, instance_)))
|
||||
goto retry;
|
||||
do_destroy (p);
|
||||
/* This *must* be called when there are no other threads accessing. */
|
||||
return this->instance.cmpexch (current, value);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
private:
|
||||
// private:
|
||||
/* Must only have one pointer. */
|
||||
hb_atomic_ptr_t<Stored *> instance;
|
||||
};
|
||||
|
|
|
@ -731,12 +731,9 @@ struct SortedArrayOf : ArrayOf<Type, LenType>
|
|||
{
|
||||
int mid = ((unsigned int) min + (unsigned int) max) / 2;
|
||||
int c = arr[mid].cmp (x);
|
||||
if (c < 0)
|
||||
max = mid - 1;
|
||||
else if (c > 0)
|
||||
min = mid + 1;
|
||||
else
|
||||
return mid;
|
||||
if (c < 0) max = mid - 1;
|
||||
else if (c > 0) min = mid + 1;
|
||||
else return mid;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -871,12 +868,9 @@ struct VarSizedBinSearchArrayOf
|
|||
int mid = ((unsigned int) min + (unsigned int) max) / 2;
|
||||
const Type *p = (const Type *) (((const char *) &bytesZ) + (mid * size));
|
||||
int c = p->cmp (key);
|
||||
if (c < 0)
|
||||
max = mid - 1;
|
||||
else if (c > 0)
|
||||
min = mid + 1;
|
||||
else
|
||||
return p;
|
||||
if (c < 0) max = mid - 1;
|
||||
else if (c > 0) min = mid + 1;
|
||||
else return p;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -191,13 +191,11 @@ struct CmapSubtableFormat4
|
|||
return false;
|
||||
}
|
||||
|
||||
if (cp > 0xFFFF) {
|
||||
// We are now outside of unicode BMP, stop adding to this cmap.
|
||||
break;
|
||||
}
|
||||
/* Stop adding to cmap if we are now outside of unicode BMP. */
|
||||
if (cp > 0xFFFF) break;
|
||||
|
||||
if (!segment
|
||||
|| cp != segment->end_code + 1u)
|
||||
if (!segment ||
|
||||
cp != segment->end_code + 1u)
|
||||
{
|
||||
segment = segments->push ();
|
||||
segment->start_code.set (cp);
|
||||
|
@ -559,10 +557,8 @@ struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
|
|||
group->startCharCode.set (cp);
|
||||
group->endCharCode.set (cp);
|
||||
group->glyphID.set (new_gid);
|
||||
} else
|
||||
{
|
||||
group->endCharCode.set (cp);
|
||||
}
|
||||
else group->endCharCode.set (cp);
|
||||
}
|
||||
|
||||
DEBUG_MSG(SUBSET, nullptr, "cmap");
|
||||
|
|
|
@ -154,23 +154,18 @@ struct glyf
|
|||
inline unsigned int get_size (void) const
|
||||
{
|
||||
unsigned int size = min_size;
|
||||
if (flags & ARG_1_AND_2_ARE_WORDS) {
|
||||
// arg1 and 2 are int16
|
||||
size += 4;
|
||||
} else {
|
||||
if (flags & ARG_1_AND_2_ARE_WORDS) size += 4;
|
||||
// arg1 and 2 are int8
|
||||
size += 2;
|
||||
}
|
||||
if (flags & WE_HAVE_A_SCALE) {
|
||||
else size += 2;
|
||||
|
||||
// One x 16 bit (scale)
|
||||
size += 2;
|
||||
} else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) {
|
||||
if (flags & WE_HAVE_A_SCALE) size += 2;
|
||||
// Two x 16 bit (xscale, yscale)
|
||||
size += 4;
|
||||
} else if (flags & WE_HAVE_A_TWO_BY_TWO) {
|
||||
else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) size += 4;
|
||||
// Four x 16 bit (xscale, scale01, scale10, yscale)
|
||||
size += 8;
|
||||
}
|
||||
else if (flags & WE_HAVE_A_TWO_BY_TWO) size += 8;
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
@ -285,8 +280,7 @@ struct glyf
|
|||
inline bool remove_padding (unsigned int start_offset,
|
||||
unsigned int *end_offset) const
|
||||
{
|
||||
if (*end_offset - start_offset < GlyphHeader::static_size)
|
||||
return true;
|
||||
if (*end_offset - start_offset < GlyphHeader::static_size) return true;
|
||||
|
||||
const char *glyph = ((const char *) glyf_table) + start_offset;
|
||||
const char * const glyph_end = glyph + (*end_offset - start_offset);
|
||||
|
@ -330,15 +324,11 @@ struct glyf
|
|||
|
||||
unsigned int xBytes, yBytes;
|
||||
xBytes = yBytes = 0;
|
||||
if (flag & FLAG_X_SHORT)
|
||||
xBytes = 1;
|
||||
else if ((flag & FLAG_X_SAME) == 0)
|
||||
xBytes = 2;
|
||||
if (flag & FLAG_X_SHORT) xBytes = 1;
|
||||
else if ((flag & FLAG_X_SAME) == 0) xBytes = 2;
|
||||
|
||||
if (flag & FLAG_Y_SHORT)
|
||||
yBytes = 1;
|
||||
else if ((flag & FLAG_Y_SAME) == 0)
|
||||
yBytes = 2;
|
||||
if (flag & FLAG_Y_SHORT) yBytes = 1;
|
||||
else if ((flag & FLAG_Y_SAME) == 0) yBytes = 2;
|
||||
|
||||
coordBytes += (xBytes + yBytes) * repeat;
|
||||
coordsWithFlags += repeat;
|
||||
|
|
|
@ -66,12 +66,9 @@ struct DeviceRecord
|
|||
if (unlikely (i >= len ())) return nullptr;
|
||||
hb_codepoint_t gid = this->subset_plan->glyphs [i];
|
||||
|
||||
const HBUINT8* width = &(this->source_device_record->widthsZ[gid]);
|
||||
|
||||
if (width < ((const HBUINT8 *) this->source_device_record) + sizeDeviceRecord)
|
||||
return width;
|
||||
else
|
||||
if (gid >= sizeDeviceRecord - DeviceRecord::min_size)
|
||||
return nullptr;
|
||||
return &(this->source_device_record->widthsZ[gid]);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -135,8 +132,10 @@ struct hdmx
|
|||
|
||||
inline const DeviceRecord& operator [] (unsigned int i) const
|
||||
{
|
||||
/* XXX Null(DeviceRecord) is NOT safe as it's num-glyphs lengthed.
|
||||
* https://github.com/harfbuzz/harfbuzz/issues/1300 */
|
||||
if (unlikely (i >= numRecords)) return Null (DeviceRecord);
|
||||
return StructAtOffset<DeviceRecord> (&this->dataZ, i * sizeDeviceRecord);
|
||||
return StructAtOffset<DeviceRecord> (&this->firstDeviceRecord, i * sizeDeviceRecord);
|
||||
}
|
||||
|
||||
inline bool serialize (hb_serialize_context_t *c, const hdmx *source_hdmx, hb_subset_plan_t *plan)
|
||||
|
@ -200,7 +199,7 @@ struct hdmx
|
|||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) && version == 0 &&
|
||||
return_trace (c->check_struct (this) &&
|
||||
!hb_unsigned_mul_overflows (numRecords, sizeDeviceRecord) &&
|
||||
sizeDeviceRecord >= DeviceRecord::min_size &&
|
||||
c->check_range (this, get_size ()));
|
||||
|
@ -210,9 +209,9 @@ struct hdmx
|
|||
HBUINT16 version; /* Table version number (0) */
|
||||
HBUINT16 numRecords; /* Number of device records. */
|
||||
HBUINT32 sizeDeviceRecord; /* Size of a device record, 32-bit aligned. */
|
||||
UnsizedArrayOf<HBUINT8> dataZ; /* Array of device records. */
|
||||
DeviceRecord firstDeviceRecord; /* Array of device records. */
|
||||
public:
|
||||
DEFINE_SIZE_ARRAY (8, dataZ);
|
||||
DEFINE_SIZE_MIN (8);
|
||||
};
|
||||
|
||||
} /* namespace OT */
|
||||
|
|
|
@ -96,8 +96,8 @@ struct hmtxvmtx
|
|||
hb_vector_t<hb_codepoint_t> &gids = plan->glyphs;
|
||||
unsigned int num_advances = gids.len;
|
||||
unsigned int last_advance = _mtx.get_advance (gids[num_advances - 1]);
|
||||
while (num_advances > 1
|
||||
&& last_advance == _mtx.get_advance (gids[num_advances - 2]))
|
||||
while (num_advances > 1 &&
|
||||
last_advance == _mtx.get_advance (gids[num_advances - 2]))
|
||||
{
|
||||
num_advances--;
|
||||
}
|
||||
|
|
|
@ -1232,10 +1232,7 @@ struct ClassDefFormat1
|
|||
inline bool add_class (set_t *glyphs, unsigned int klass) const {
|
||||
unsigned int count = classValue.len;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1246,8 +1243,7 @@ struct ClassDefFormat1
|
|||
hb_codepoint_t end = startGlyph + classValue.len;
|
||||
for (hb_codepoint_t iter = startGlyph - 1;
|
||||
hb_set_next (glyphs, &iter) && iter < end;)
|
||||
if (classValue[iter - start])
|
||||
return true;
|
||||
if (classValue[iter - start]) return true;
|
||||
return false;
|
||||
}
|
||||
inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const {
|
||||
|
@ -1256,13 +1252,10 @@ struct ClassDefFormat1
|
|||
{
|
||||
/* Match if there's any glyph that is not listed! */
|
||||
hb_codepoint_t g = HB_SET_VALUE_INVALID;
|
||||
if (!hb_set_next (glyphs, &g))
|
||||
return false;
|
||||
if (g < startGlyph)
|
||||
return true;
|
||||
if (!hb_set_next (glyphs, &g)) return false;
|
||||
if (g < startGlyph) return true;
|
||||
g = startGlyph + count - 1;
|
||||
if (hb_set_next (glyphs, &g))
|
||||
return true;
|
||||
if (hb_set_next (glyphs, &g)) return true;
|
||||
/* Fall through. */
|
||||
}
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
|
|
|
@ -105,8 +105,7 @@ struct post
|
|||
unsigned int table_length = table.get_length ();
|
||||
|
||||
version = table->version.to_int ();
|
||||
if (version != 0x00020000)
|
||||
return;
|
||||
if (version != 0x00020000) return;
|
||||
|
||||
const postV2Tail &v2 = table->v2;
|
||||
|
||||
|
@ -130,10 +129,8 @@ struct post
|
|||
char *buf, unsigned int buf_len) const
|
||||
{
|
||||
hb_bytes_t s = find_glyph_name (glyph);
|
||||
if (!s.len)
|
||||
return false;
|
||||
if (!buf_len)
|
||||
return true;
|
||||
if (!s.len) return false;
|
||||
if (!buf_len) return true;
|
||||
unsigned int len = MIN (buf_len - 1, s.len);
|
||||
strncpy (buf, s.arrayZ, len);
|
||||
buf[len] = '\0';
|
||||
|
@ -144,14 +141,11 @@ struct post
|
|||
hb_codepoint_t *glyph) const
|
||||
{
|
||||
unsigned int count = get_glyph_count ();
|
||||
if (unlikely (!count))
|
||||
return false;
|
||||
if (unlikely (!count)) return false;
|
||||
|
||||
if (len < 0)
|
||||
len = strlen (name);
|
||||
if (len < 0) len = strlen (name);
|
||||
|
||||
if (unlikely (!len))
|
||||
return false;
|
||||
if (unlikely (!len)) return false;
|
||||
|
||||
retry:
|
||||
uint16_t *gids = gids_sorted_by_name.get ();
|
||||
|
|
|
@ -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 *
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
135
src/hb-shaper.hh
135
src/hb-shaper.hh
|
@ -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,87 +50,85 @@ 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)
|
||||
template <typename Data, unsigned int WheresData, typename T>
|
||||
struct hb_shaper_lazy_loader_t;
|
||||
|
||||
#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_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_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. */ \
|
||||
#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 HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS); \
|
||||
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) *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)
|
||||
|
||||
#define HB_SHAPER_DATA_ENSURE_DEFINE_WITH_CONDITION(shaper, object, condition) \
|
||||
bool \
|
||||
HB_SHAPER_DATA_ENSURE_FUNC(shaper, object) (hb_##object##_t *object) \
|
||||
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> \
|
||||
{ \
|
||||
retry: \
|
||||
HB_SHAPER_DATA_TYPE (shaper, object) *data = HB_SHAPER_DATA (shaper, object).get (); \
|
||||
if (likely (data) && !(condition)) { \
|
||||
/* 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 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))) \
|
||||
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> \
|
||||
{ \
|
||||
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; \
|
||||
} \
|
||||
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. */
|
||||
|
||||
|
||||
/* For embedding in face / font / ... */
|
||||
struct hb_shaper_data_t {
|
||||
#define HB_SHAPER_IMPLEMENT(shaper) hb_atomic_ptr_t<void *> shaper;
|
||||
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 */
|
||||
|
|
|
@ -53,8 +53,8 @@ _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf,
|
|||
*instruction_end = 0;
|
||||
|
||||
unsigned int start_offset, end_offset;
|
||||
if (unlikely (!(glyf.get_offsets(next_glyph, &start_offset, &end_offset)
|
||||
&& glyf.remove_padding(start_offset, &end_offset))))
|
||||
if (unlikely (!(glyf.get_offsets (next_glyph, &start_offset, &end_offset) &&
|
||||
glyf.remove_padding (start_offset, &end_offset))))
|
||||
{
|
||||
DEBUG_MSG(SUBSET, nullptr, "Invalid gid %d", next_glyph);
|
||||
continue;
|
||||
|
@ -170,8 +170,8 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan,
|
|||
for (unsigned int i = 0; i < glyph_ids.len; i++)
|
||||
{
|
||||
unsigned int start_offset, end_offset;
|
||||
if (unlikely (!(glyf.get_offsets (glyph_ids[i], &start_offset, &end_offset)
|
||||
&& glyf.remove_padding(start_offset, &end_offset))))
|
||||
if (unlikely (!(glyf.get_offsets (glyph_ids[i], &start_offset, &end_offset) &&
|
||||
glyf.remove_padding (start_offset, &end_offset))))
|
||||
end_offset = start_offset = 0;
|
||||
|
||||
unsigned int instruction_start = instruction_ranges[i * 2];
|
||||
|
|
|
@ -81,6 +81,17 @@ _gsub_closure (hb_face_t *face, hb_set_t *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 *
|
||||
_populate_gids_to_retain (hb_face_t *face,
|
||||
|
@ -130,6 +141,8 @@ _populate_gids_to_retain (hb_face_t *face,
|
|||
}
|
||||
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 ());
|
||||
gid = HB_SET_VALUE_INVALID;
|
||||
while (all_gids_to_retain->next (&gid))
|
||||
|
|
|
@ -74,8 +74,7 @@ hb_subset_input_get_desubroutinize (hb_subset_input_t *subset_input);
|
|||
|
||||
/* hb_subset () */
|
||||
HB_EXTERN hb_face_t *
|
||||
hb_subset (hb_face_t *source,
|
||||
hb_subset_input_t *input);
|
||||
hb_subset (hb_face_t *source, hb_subset_input_t *input);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
|
|
@ -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;
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue