From 5b95c148cc485f79fd7018bc4520b4cb5f728a18 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 26 Jul 2012 23:46:53 -0400 Subject: [PATCH] Start implementing shape_plan --- src/hb-fallback-shape.cc | 4 +- src/hb-font-private.hh | 4 ++ src/hb-old.cc | 4 +- src/hb-ot-shape.cc | 4 +- src/hb-shape-plan-private.hh | 7 ++++ src/hb-shape-plan.cc | 76 +++++++++++++++++++++++++++++++++++- src/hb-shape.cc | 4 ++ src/hb-shaper-private.hh | 4 +- src/hb-uniscribe.cc | 4 +- 9 files changed, 103 insertions(+), 8 deletions(-) diff --git a/src/hb-fallback-shape.cc b/src/hb-fallback-shape.cc index 48aba7312..52b46b1d5 100644 --- a/src/hb-fallback-shape.cc +++ b/src/hb-fallback-shape.cc @@ -71,7 +71,9 @@ _hb_fallback_shaper_font_data_destroy (hb_fallback_shaper_font_data_t *data) struct hb_fallback_shaper_shape_plan_data_t {}; hb_fallback_shaper_shape_plan_data_t * -_hb_fallback_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan) +_hb_fallback_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan, + const hb_feature_t *user_features, + unsigned int num_user_features) { return (hb_fallback_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; } diff --git a/src/hb-font-private.hh b/src/hb-font-private.hh index 97a86d500..2540dd67c 100644 --- a/src/hb-font-private.hh +++ b/src/hb-font-private.hh @@ -105,9 +105,11 @@ struct hb_face_t { struct hb_shaper_data_t shaper_data; }; +#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 /* @@ -172,9 +174,11 @@ struct hb_font_t { inline hb_position_t em_scale (int16_t v, int scale) { return v * (int64_t) scale / hb_face_get_upem (this->face); } }; +#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_PRIVATE_HH */ diff --git a/src/hb-old.cc b/src/hb-old.cc index 879ee70b1..77761e8ff 100644 --- a/src/hb-old.cc +++ b/src/hb-old.cc @@ -231,7 +231,9 @@ _hb_old_shaper_font_data_destroy (hb_old_shaper_font_data_t *data) struct hb_old_shaper_shape_plan_data_t {}; hb_old_shaper_shape_plan_data_t * -_hb_old_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan) +_hb_old_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan, + const hb_feature_t *user_features, + unsigned int num_user_features) { return (hb_old_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; } diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc index a3c4153d2..639748e10 100644 --- a/src/hb-ot-shape.cc +++ b/src/hb-ot-shape.cc @@ -78,7 +78,9 @@ _hb_ot_shaper_font_data_destroy (hb_ot_shaper_font_data_t *data) struct hb_ot_shaper_shape_plan_data_t {}; hb_ot_shaper_shape_plan_data_t * -_hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan) +_hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan, + const hb_feature_t *user_features, + unsigned int num_user_features) { return (hb_ot_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; } diff --git a/src/hb-shape-plan-private.hh b/src/hb-shape-plan-private.hh index 68246f47b..c292f146e 100644 --- a/src/hb-shape-plan-private.hh +++ b/src/hb-shape-plan-private.hh @@ -39,14 +39,21 @@ struct hb_shape_plan_t hb_object_header_t header; ASSERT_POD (); + hb_face_t *face; + hb_segment_properties_t props; + hb_shape_func_t *shapers[HB_SHAPERS_COUNT]; struct hb_shaper_data_t shaper_data; }; +#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS \ + , const hb_feature_t *user_features \ + , unsigned int num_user_features #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, shape_plan); #include "hb-shaper-list.hh" #undef HB_SHAPER_IMPLEMENT +#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS #endif /* HB_SHAPE_PLAN_PRIVATE_HH */ diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc index e76847d71..372543b84 100644 --- a/src/hb-shape-plan.cc +++ b/src/hb-shape-plan.cc @@ -27,9 +27,79 @@ #include "hb-private.hh" #include "hb-shape-plan-private.hh" - +#include "hb-shaper-private.hh" #include "hb-font-private.hh" +#define HB_SHAPER_DATA_ENSURE_DECLARE(shaper, object) \ +static inline bool \ +hb_##shaper##_##object##_data_ensure (hb_##object##_t *object) \ +{\ + retry: \ + HB_SHAPER_DATA_TYPE (shaper, object) *data = (HB_SHAPER_DATA_TYPE (shaper, object) *) hb_atomic_ptr_get (&HB_SHAPER_DATA (shaper, object)); \ + 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 (!hb_atomic_ptr_cmpexch (&HB_SHAPER_DATA (shaper, object), NULL, data)) { \ + HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (data); \ + goto retry; \ + } \ + } \ + return data != NULL && !HB_SHAPER_DATA_IS_INVALID (data); \ +} + +#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_ENSURE_DECLARE(shaper, face) +#include "hb-shaper-list.hh" +#undef HB_SHAPER_IMPLEMENT + + +void +hb_shape_plan_plan (hb_shape_plan_t *shape_plan, + const hb_feature_t *user_features, + unsigned int num_user_features, + const char * const *shaper_list) +{ + const hb_shaper_pair_t *shapers = _hb_shapers_get (); + unsigned num_shapers = 0; + +#define HB_SHAPER_PLAN(shaper) \ + HB_STMT_START { \ + if (hb_##shaper##_face_data_ensure (shape_plan->face)) { \ + /* TODO Ensure face shaper data. */ \ + HB_SHAPER_DATA_TYPE (shaper, shape_plan) *data= \ + HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, user_features, num_user_features); \ + if (data) { \ + HB_SHAPER_DATA (shaper, shape_plan) = data; \ + shape_plan->shapers[num_shapers++] = _hb_##shaper##_shape; \ + } \ + if (false /* shaper never fails */) \ + return; \ + } \ + } HB_STMT_END + + if (likely (!shaper_list)) { + for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++) + if (0) + ; +#define HB_SHAPER_IMPLEMENT(shaper) \ + else if (shapers[i].func == _hb_##shaper##_shape) \ + HB_SHAPER_PLAN (shaper); +#include "hb-shaper-list.hh" +#undef HB_SHAPER_IMPLEMENT + } else { + for (; *shaper_list; shaper_list++) + if (0) + ; +#define HB_SHAPER_IMPLEMENT(shaper) \ + else if (0 == strcmp (*shaper_list, #shaper)) \ + HB_SHAPER_PLAN (shaper); +#include "hb-shaper-list.hh" +#undef HB_SHAPER_IMPLEMENT + } + +#undef HB_SHAPER_PLAN +} + /* * hb_shape_plan_t @@ -52,8 +122,10 @@ hb_shape_plan_create (hb_face_t *face, return hb_shape_plan_get_empty (); hb_face_make_immutable (face); + shape_plan->face = hb_face_reference (face); + shape_plan->props = *props; - /* Plan! */ + hb_shape_plan_plan (shape_plan, user_features, num_user_features, shaper_list); return shape_plan; } diff --git a/src/hb-shape.cc b/src/hb-shape.cc index 3915de786..d017425d2 100644 --- a/src/hb-shape.cc +++ b/src/hb-shape.cc @@ -27,7 +27,9 @@ #include "hb-private.hh" #include "hb-shaper-private.hh" +#include "hb-shape-plan-private.hh" #include "hb-buffer-private.hh" +#include "hb-font-private.hh" @@ -81,6 +83,8 @@ hb_shape_full (hb_font_t *font, unsigned int num_features, const char * const *shaper_list) { +// hb_shape_plan_t *shape_plan = hb_shape_plan_create (font->face, &buffer->props, features, num_features, shaper_list); + const hb_shaper_pair_t *shapers = _hb_shapers_get (); hb_font_make_immutable (font); /* So we can safely cache stuff on it */ diff --git a/src/hb-shaper-private.hh b/src/hb-shaper-private.hh index fa279bc0e..9e35ef8c5 100644 --- a/src/hb-shaper-private.hh +++ b/src/hb-shaper-private.hh @@ -68,7 +68,7 @@ struct hb_shaper_data_t { #define HB_SHAPER_DATA_IS_INVALID(data) ((void *) (data) == HB_SHAPER_DATA_INVALID) #define HB_SHAPER_DATA_TYPE(shaper, object) struct hb_##shaper##_shaper_##object##_data_t -#define HB_SHAPER_DATA(shaper, object) ((HB_SHAPER_DATA_TYPE(shaper, object) *) (object)->shaper_data.shaper) +#define HB_SHAPER_DATA(shaper, object) (* (HB_SHAPER_DATA_TYPE(shaper, object) **) &(object)->shaper_data.shaper) #define HB_SHAPER_DATA_GET_FUNC(shaper, object) _hb_##shaper##_shaper_get_##object##_data #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 @@ -79,7 +79,7 @@ struct hb_shaper_data_t { HB_SHAPER_DATA_GET_FUNC (shaper, object) (hb_##object##_t *object) \ { return HB_SHAPER_DATA (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 (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) diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc index faba5870c..a7aa163ea 100644 --- a/src/hb-uniscribe.cc +++ b/src/hb-uniscribe.cc @@ -192,7 +192,9 @@ _hb_uniscribe_shaper_font_data_destroy (hb_uniscribe_shaper_font_data_t *data) struct hb_uniscribe_shaper_shape_plan_data_t {}; hb_uniscribe_shaper_shape_plan_data_t * -_hb_uniscribe_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan) +_hb_uniscribe_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan, + const hb_feature_t *user_features, + unsigned int num_user_features) { return (hb_uniscribe_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED; }