[HarfBuzz] harfbuzz-ng: Branch 'master' - 12 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Fri Jul 27 09:56:02 PDT 2012
TODO | 4
src/Makefile.am | 16 +-
src/hb-buffer-private.hh | 31 ++++
src/hb-buffer.cc | 1
src/hb-coretext-private.hh | 42 -----
src/hb-coretext.cc | 6
src/hb-fallback-shape-private.hh | 41 -----
src/hb-fallback-shape.cc | 67 ++++++++-
src/hb-font-private.hh | 24 +++
src/hb-font.cc | 48 +++++-
src/hb-graphite2-private.hh | 42 -----
src/hb-old-private.hh | 40 -----
src/hb-old.cc | 128 ++++++++---------
src/hb-ot-layout-gpos-table.hh | 2
src/hb-ot-layout-gsub-table.hh | 4
src/hb-ot-layout-private.hh | 1
src/hb-ot-layout.cc | 16 +-
src/hb-ot-layout.h | 6
src/hb-ot-shape-private.hh | 14 -
src/hb-ot-shape.cc | 131 ++++++++++++------
src/hb-shape-plan-private.hh | 60 ++++++++
src/hb-shape-plan.cc | 281 +++++++++++++++++++++++++++++++++++++++
src/hb-shape-plan.h | 75 ++++++++++
src/hb-shape.cc | 156 ++-------------------
src/hb-shaper-impl-private.hh | 43 +++++
src/hb-shaper-list.hh | 50 ++++++
src/hb-shaper-private.hh | 108 ++++++++++++++
src/hb-shaper.cc | 109 +++++++++++++++
src/hb-uniscribe-private.hh | 42 -----
src/hb-uniscribe.cc | 224 +++++++++++++++----------------
src/hb-uniscribe.h | 4
31 files changed, 1206 insertions(+), 610 deletions(-)
New commits:
commit 2f87cebe1062c7007021ebd05c1664e60da80825
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Jul 27 04:02:38 2012 -0400
Implement shape_plan caching
Should give us some performance boost.
diff --git a/TODO b/TODO
index 0521b85..be381e3 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,10 @@
General fixes:
=============
+- mask propagation (when ligation, "or" the masks).
+
+- fail_shaper that always fails.
+
- Make map in setup_masks() const, etc.
- Warn at compile time (and runtime with HB_DEBUG?) if no Unicode / font
diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index b800aeb..d6189d2 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -40,14 +40,44 @@
ASSERT_STATIC (sizeof (hb_glyph_info_t) == 20);
ASSERT_STATIC (sizeof (hb_glyph_info_t) == sizeof (hb_glyph_position_t));
+
+/*
+ * hb_segment_properties_t
+ */
+
typedef struct hb_segment_properties_t {
hb_direction_t direction;
hb_script_t script;
hb_language_t language;
ASSERT_POD ();
} hb_segment_properties_t;
+
#define _HB_BUFFER_PROPS_DEFAULT { HB_DIRECTION_INVALID, HB_SCRIPT_INVALID, HB_LANGUAGE_INVALID }
+static inline hb_bool_t
+hb_segment_properties_equal (const hb_segment_properties_t *a,
+ const hb_segment_properties_t *b)
+{
+ return a->direction == b->direction &&
+ a->script == b->script &&
+ a->language == b->language;
+}
+
+
+static inline long
+hb_segment_properties_hash (const hb_segment_properties_t *p)
+{
+ /* TODO improve */
+ return (long) p->direction +
+ (long) p->script +
+ (long) p->language;
+}
+
+
+
+/*
+ * hb_buffer_t
+ */
struct hb_buffer_t {
hb_object_header_t header;
diff --git a/src/hb-font-private.hh b/src/hb-font-private.hh
index f1b43c0..892fd7c 100644
--- a/src/hb-font-private.hh
+++ b/src/hb-font-private.hh
@@ -34,6 +34,7 @@
#include "hb-font.h"
#include "hb-object-private.hh"
#include "hb-shaper-private.hh"
+#include "hb-shape-plan-private.hh"
@@ -101,6 +102,11 @@ struct hb_face_t {
unsigned int upem;
struct hb_shaper_data_t shaper_data;
+
+ struct plan_node_t {
+ hb_shape_plan_t *shape_plan;
+ plan_node_t *next;
+ } *shape_plans;
};
#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS
diff --git a/src/hb-font.cc b/src/hb-font.cc
index 5a3219a..83c349e 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -596,7 +596,9 @@ static const hb_face_t _hb_face_nil = {
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
#include "hb-shaper-list.hh"
#undef HB_SHAPER_IMPLEMENT
- }
+ },
+
+ NULL, /* shape_plans */
};
@@ -709,6 +711,17 @@ hb_face_destroy (hb_face_t *face)
{
if (!hb_object_destroy (face)) return;
+ /* The cached shape_plans think they have a reference on us, and
+ * try to release it. Make sure that doesn't mess up. */
+ face->header.ref_count.ref_count = HB_REFERENCE_COUNT_INVALID_VALUE;
+ for (hb_face_t::plan_node_t *node = face->shape_plans; node; )
+ {
+ hb_face_t::plan_node_t *next = node->next;
+ hb_shape_plan_destroy (node->shape_plan);
+ free (node);
+ node = next;
+ }
+
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, face);
#include "hb-shaper-list.hh"
#undef HB_SHAPER_IMPLEMENT
diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc
index 663cb34..af3c18d 100644
--- a/src/hb-shape-plan.cc
+++ b/src/hb-shape-plan.cc
@@ -179,3 +179,103 @@ hb_shape_plan_execute (hb_shape_plan *shape_plan,
return false;
}
+
+
+/*
+ * caching
+ */
+
+#if 0
+static long
+hb_shape_plan_hash (const hb_shape_plan_t *shape_plan)
+{
+ return hb_segment_properties_hash (&shape_plan->props) +
+ shape_plan->default_shaper_list ? 0 : (long) shape_plan->shaper_func;
+}
+#endif
+
+/* TODO no user-feature caching for now. */
+struct hb_shape_plan_proposal_t
+{
+ const hb_segment_properties_t props;
+ const char * const *shaper_list;
+ hb_shape_func_t *shaper_func;
+};
+
+static hb_bool_t
+hb_shape_plan_matches (const hb_shape_plan_t *shape_plan,
+ const hb_shape_plan_proposal_t *proposal)
+{
+ return hb_segment_properties_equal (&shape_plan->props, &proposal->props) &&
+ ((shape_plan->default_shaper_list && proposal->shaper_list == NULL) ||
+ (shape_plan->shaper_func == proposal->shaper_func));
+}
+
+hb_shape_plan_t *
+hb_shape_plan_create_cached (hb_face_t *face,
+ const hb_segment_properties_t *props,
+ const hb_feature_t *user_features,
+ unsigned int num_user_features,
+ const char * const *shaper_list)
+{
+ if (num_user_features)
+ return hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list);
+
+ hb_shape_plan_proposal_t proposal = {
+ *props,
+ shaper_list,
+ NULL
+ };
+
+ if (shaper_list) {
+ /* Choose shaper. Adapted from hb_shape_plan_plan(). */
+#define HB_SHAPER_PLAN(shaper) \
+ HB_STMT_START { \
+ if (hb_##shaper##_shaper_face_data_ensure (face)) \
+ proposal.shaper_func = _hb_##shaper##_shape; \
+ } HB_STMT_END
+
+ for (const char * const *shaper_item = shaper_list; *shaper_item; shaper_item++)
+ if (0)
+ ;
+#define HB_SHAPER_IMPLEMENT(shaper) \
+ else if (0 == strcmp (*shaper_item, #shaper)) \
+ HB_SHAPER_PLAN (shaper);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+#undef HB_SHAPER_PLAN
+
+ if (unlikely (!proposal.shaper_list))
+ return hb_shape_plan_get_empty ();
+ }
+
+
+retry:
+ hb_face_t::plan_node_t *cached_plan_nodes = (hb_face_t::plan_node_t *) hb_atomic_ptr_get (&face->shape_plans);
+ for (hb_face_t::plan_node_t *node = cached_plan_nodes; node; node = node->next)
+ if (hb_shape_plan_matches (node->shape_plan, &proposal))
+ return hb_shape_plan_reference (node->shape_plan);
+
+ /* Not found. */
+
+ hb_shape_plan_t *shape_plan = hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list);
+
+ hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (hb_face_t::plan_node_t));
+ if (unlikely (!node))
+ return shape_plan;
+
+ node->shape_plan = shape_plan;
+ node->next = cached_plan_nodes;
+
+ if (!hb_atomic_ptr_cmpexch (&face->shape_plans, cached_plan_nodes, node)) {
+ hb_shape_plan_destroy (shape_plan);
+ free (node);
+ goto retry;
+ }
+
+ /* Release our reference on face. */
+ hb_face_destroy (face);
+
+ return hb_shape_plan_reference (shape_plan);
+}
diff --git a/src/hb-shape-plan.h b/src/hb-shape-plan.h
index a4786a8..fbce5dd 100644
--- a/src/hb-shape-plan.h
+++ b/src/hb-shape-plan.h
@@ -47,6 +47,13 @@ hb_shape_plan_create (hb_face_t *face,
unsigned int num_user_features,
const char * const *shaper_list);
+hb_shape_plan_t *
+hb_shape_plan_create_cached (hb_face_t *face,
+ const hb_segment_properties_t *props,
+ const hb_feature_t *user_features,
+ unsigned int num_user_features,
+ const char * const *shaper_list);
+
HB_INTERNAL hb_shape_plan_t *
hb_shape_plan_get_empty (void);
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index fde9cf2..5aa587b 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -87,7 +87,7 @@ hb_shape_full (hb_font_t *font,
buffer->guess_properties ();
- hb_shape_plan_t *shape_plan = hb_shape_plan_create (font->face, &buffer->props, features, num_features, shaper_list);
+ hb_shape_plan_t *shape_plan = hb_shape_plan_create_cached (font->face, &buffer->props, features, num_features, shaper_list);
hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features);
hb_shape_plan_destroy (shape_plan);
return res;
commit e9eb9503e97044222f843daacfa47e26e51312b7
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Jul 27 03:16:22 2012 -0400
Add default_shaper_list to shape_plan
diff --git a/src/hb-shape-plan-private.hh b/src/hb-shape-plan-private.hh
index 1b3c3b2..d6a57d6 100644
--- a/src/hb-shape-plan-private.hh
+++ b/src/hb-shape-plan-private.hh
@@ -39,6 +39,7 @@ struct hb_shape_plan_t
hb_object_header_t header;
ASSERT_POD ();
+ hb_bool_t default_shaper_list;
hb_face_t *face;
hb_segment_properties_t props;
diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc
index 83de1f6..663cb34 100644
--- a/src/hb-shape-plan.cc
+++ b/src/hb-shape-plan.cc
@@ -100,6 +100,7 @@ hb_shape_plan_create (hb_face_t *face,
return hb_shape_plan_get_empty ();
hb_face_make_immutable (face);
+ shape_plan->default_shaper_list = shaper_list == NULL;
shape_plan->face = hb_face_reference (face);
shape_plan->props = *props;
@@ -114,6 +115,7 @@ hb_shape_plan_get_empty (void)
static const hb_shape_plan_t _hb_shape_plan_nil = {
HB_OBJECT_HEADER_STATIC,
+ TRUE, /* default_shaper_list */
NULL, /* face */
_HB_BUFFER_PROPS_DEFAULT, /* props */
commit 3b7c4e270694ed962e2a2839e44f2a59c26b326c
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Jul 27 03:12:23 2012 -0400
Don't fail choosing shaper on planning failure
Shapers have a chance to reject a font in face shaper_data creation.
No need to allow failing during planning.
diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc
index b0a8937..83de1f6 100644
--- a/src/hb-shape-plan.cc
+++ b/src/hb-shape-plan.cc
@@ -48,13 +48,10 @@ hb_shape_plan_plan (hb_shape_plan_t *shape_plan,
#define HB_SHAPER_PLAN(shaper) \
HB_STMT_START { \
if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face)) { \
- HB_SHAPER_DATA_TYPE (shaper, shape_plan) *data= \
+ HB_SHAPER_DATA (shaper, shape_plan) = \
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->shaper_func = _hb_##shaper##_shape; \
- return; \
- } \
+ shape_plan->shaper_func = _hb_##shaper##_shape; \
+ return; \
} \
} HB_STMT_END
@@ -163,11 +160,9 @@ hb_shape_plan_execute (hb_shape_plan *shape_plan,
#define HB_SHAPER_EXECUTE(shaper) \
HB_STMT_START { \
- if (hb_##shaper##_shaper_font_data_ensure (font) && \
- _hb_##shaper##_shape (shape_plan, font, buffer, features, num_features)) \
- return true; \
- else \
- return false; \
+ return HB_SHAPER_DATA (shaper, shape_plan) && \
+ hb_##shaper##_shaper_font_data_ensure (font) && \
+ _hb_##shaper##_shape (shape_plan, font, buffer, features, num_features); \
} HB_STMT_END
if (0)
commit cfe9882610489e1b917e09a74dfbf6bbba2e4a57
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Jul 27 03:06:30 2012 -0400
Add hb_ot_layout_ensure() and hb_uniscribe_font_ensure()
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index dff3673..eb39c65 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -38,6 +38,13 @@
#include <string.h>
+HB_SHAPER_DATA_ENSURE_DECLARE(ot, face)
+hb_bool_t
+hb_ot_layout_ensure (hb_face_t *face)
+{
+ return hb_ot_shaper_face_data_ensure (face);
+}
+
hb_ot_layout_t *
_hb_ot_layout_create (hb_face_t *face)
diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h
index cf178b7..af23478 100644
--- a/src/hb-ot-layout.h
+++ b/src/hb-ot-layout.h
@@ -42,6 +42,12 @@ HB_BEGIN_DECLS
#define HB_OT_TAG_GSUB HB_TAG('G','S','U','B')
#define HB_OT_TAG_GPOS HB_TAG('G','P','O','S')
+
+/* Must call before all other funtions in this file. Idempotent. */
+hb_bool_t
+hb_ot_layout_ensure (hb_face_t *face);
+
+
/*
* GDEF
*/
diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc
index 1820f61..b0a8937 100644
--- a/src/hb-shape-plan.cc
+++ b/src/hb-shape-plan.cc
@@ -30,24 +30,6 @@
#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) \
HB_SHAPER_DATA_ENSURE_DECLARE(shaper, font)
@@ -65,7 +47,7 @@ hb_shape_plan_plan (hb_shape_plan_t *shape_plan,
#define HB_SHAPER_PLAN(shaper) \
HB_STMT_START { \
- if (hb_##shaper##_face_data_ensure (shape_plan->face)) { \
+ if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face)) { \
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) { \
@@ -181,7 +163,7 @@ hb_shape_plan_execute (hb_shape_plan *shape_plan,
#define HB_SHAPER_EXECUTE(shaper) \
HB_STMT_START { \
- if (hb_##shaper##_font_data_ensure (font) && \
+ if (hb_##shaper##_shaper_font_data_ensure (font) && \
_hb_##shaper##_shape (shape_plan, font, buffer, features, num_features)) \
return true; \
else \
diff --git a/src/hb-shaper-private.hh b/src/hb-shaper-private.hh
index e50d869..186318d 100644
--- a/src/hb-shaper-private.hh
+++ b/src/hb-shaper-private.hh
@@ -86,5 +86,23 @@ struct hb_shaper_data_t {
object->shaper_data.shaper != HB_SHAPER_DATA_SUCCEEDED) \
HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA (shaper, object));
+#define HB_SHAPER_DATA_ENSURE_DECLARE(shaper, object) \
+static inline bool \
+hb_##shaper##_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); \
+}
+
#endif /* HB_SHAPER_PRIVATE_HH */
diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc
index 4368f68..7d06a6b 100644
--- a/src/hb-uniscribe.cc
+++ b/src/hb-uniscribe.cc
@@ -56,6 +56,17 @@ DWORD GetFontData(
*/
+HB_SHAPER_DATA_ENSURE_DECLARE(uniscribe, face)
+HB_SHAPER_DATA_ENSURE_DECLARE(uniscribe, font)
+hb_bool_t
+hb_uniscribe_font_ensure (hb_font_t *font)
+{
+ hb_face_t *face = font->face;
+ return hb_uniscribe_shaper_face_data_ensure (face) &&
+ hb_uniscribe_shaper_font_data_ensure (font);
+}
+
+
/*
* shaper face data
*/
diff --git a/src/hb-uniscribe.h b/src/hb-uniscribe.h
index bb99f39..2758dab 100644
--- a/src/hb-uniscribe.h
+++ b/src/hb-uniscribe.h
@@ -34,6 +34,10 @@
HB_BEGIN_DECLS
+/* Must call before all other funtions in this file. Idempotent. */
+hb_bool_t
+hb_uniscribe_font_ensure (hb_font_t *font);
+
LOGFONTW *
hb_uniscribe_font_get_logfontw (hb_font_t *font);
commit c5b668fb9239c912d2448280a7176e331ebc9181
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Jul 27 02:49:39 2012 -0400
Choose one shaper per plan
diff --git a/src/hb-shape-plan-private.hh b/src/hb-shape-plan-private.hh
index c292f14..1b3c3b2 100644
--- a/src/hb-shape-plan-private.hh
+++ b/src/hb-shape-plan-private.hh
@@ -42,7 +42,7 @@ struct hb_shape_plan_t
hb_face_t *face;
hb_segment_properties_t props;
- hb_shape_func_t *shapers[HB_SHAPERS_COUNT];
+ hb_shape_func_t *shaper_func;
struct hb_shaper_data_t shaper_data;
};
diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc
index 099d09c..1820f61 100644
--- a/src/hb-shape-plan.cc
+++ b/src/hb-shape-plan.cc
@@ -62,7 +62,6 @@ hb_shape_plan_plan (hb_shape_plan_t *shape_plan,
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 { \
@@ -71,10 +70,9 @@ hb_shape_plan_plan (hb_shape_plan_t *shape_plan,
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 */) \
+ shape_plan->shaper_func = _hb_##shaper##_shape; \
return; \
+ } \
} \
} HB_STMT_END
@@ -140,7 +138,7 @@ hb_shape_plan_get_empty (void)
NULL, /* face */
_HB_BUFFER_PROPS_DEFAULT, /* props */
- {NULL}, /* shapers */
+ NULL, /* shaper_func */
{
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
@@ -186,14 +184,15 @@ hb_shape_plan_execute (hb_shape_plan *shape_plan,
if (hb_##shaper##_font_data_ensure (font) && \
_hb_##shaper##_shape (shape_plan, font, buffer, features, num_features)) \
return true; \
+ else \
+ return false; \
} HB_STMT_END
- for (hb_shape_func_t **shaper_func = shape_plan->shapers; *shaper_func; shaper_func++)
- if (0)
- ;
+ if (0)
+ ;
#define HB_SHAPER_IMPLEMENT(shaper) \
- else if (*shaper_func == _hb_##shaper##_shape) \
- HB_SHAPER_EXECUTE (shaper);
+ else if (shape_plan->shaper_func == _hb_##shaper##_shape) \
+ HB_SHAPER_EXECUTE (shaper);
#include "hb-shaper-list.hh"
#undef HB_SHAPER_IMPLEMENT
commit e82061e8db922f0ddbefd5a184ee2f9f967b9a05
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Jul 27 02:29:32 2012 -0400
Move ot shaper completely to shape_plan
diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh
index 8c8876a..e1f6a69 100644
--- a/src/hb-ot-shape-private.hh
+++ b/src/hb-ot-shape-private.hh
@@ -37,12 +37,6 @@ struct hb_ot_shape_plan_t
{
hb_ot_map_t map;
hb_ot_complex_shaper_t shaper;
-
- hb_ot_shape_plan_t (void) : map () {}
- ~hb_ot_shape_plan_t (void) { map.finish (); }
-
- private:
- NO_COPY (hb_ot_shape_plan_t);
};
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 22dea07..e04e700 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -28,6 +28,7 @@
#define HB_SHAPER ot
#define hb_ot_shaper_face_data_t hb_ot_layout_t
+#define hb_ot_shaper_shape_plan_data_t hb_ot_shape_plan_t
#include "hb-shaper-impl-private.hh"
#include "hb-ot-shape-private.hh"
@@ -37,65 +38,6 @@
#include "hb-set-private.hh"
-/*
- * shaper face data
- */
-
-hb_ot_shaper_face_data_t *
-_hb_ot_shaper_face_data_create (hb_face_t *face)
-{
- return _hb_ot_layout_create (face);
-}
-
-void
-_hb_ot_shaper_face_data_destroy (hb_ot_shaper_face_data_t *data)
-{
- _hb_ot_layout_destroy (data);
-}
-
-
-/*
- * shaper font data
- */
-
-struct hb_ot_shaper_font_data_t {};
-
-hb_ot_shaper_font_data_t *
-_hb_ot_shaper_font_data_create (hb_font_t *font)
-{
- return (hb_ot_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
-}
-
-void
-_hb_ot_shaper_font_data_destroy (hb_ot_shaper_font_data_t *data)
-{
-}
-
-
-/*
- * shaper shape_plan 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,
- const hb_feature_t *user_features,
- unsigned int num_user_features)
-{
- return (hb_ot_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
-}
-
-void
-_hb_ot_shaper_shape_plan_data_destroy (hb_ot_shaper_shape_plan_data_t *data)
-{
-}
-
-
-/*
- * shaper
- */
-
hb_tag_t common_features[] = {
HB_TAG('c','c','m','p'),
HB_TAG('l','i','g','a'),
@@ -138,7 +80,7 @@ struct hb_ot_shape_planner_t
inline void compile (hb_face_t *face,
const hb_segment_properties_t *props,
- struct hb_ot_shape_plan_t &plan)
+ hb_ot_shape_plan_t &plan)
{
plan.shaper = shaper;
map.compile (face, props, plan.map);
@@ -196,9 +138,81 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
}
+/*
+ * shaper face data
+ */
+
+hb_ot_shaper_face_data_t *
+_hb_ot_shaper_face_data_create (hb_face_t *face)
+{
+ return _hb_ot_layout_create (face);
+}
+
+void
+_hb_ot_shaper_face_data_destroy (hb_ot_shaper_face_data_t *data)
+{
+ _hb_ot_layout_destroy (data);
+}
+
+
+/*
+ * shaper font data
+ */
+
+struct hb_ot_shaper_font_data_t {};
+
+hb_ot_shaper_font_data_t *
+_hb_ot_shaper_font_data_create (hb_font_t *font)
+{
+ return (hb_ot_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_ot_shaper_font_data_destroy (hb_ot_shaper_font_data_t *data)
+{
+}
+
+
+/*
+ * shaper shape_plan data
+ */
+
+hb_ot_shaper_shape_plan_data_t *
+_hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
+ const hb_feature_t *user_features,
+ unsigned int num_user_features)
+{
+ hb_ot_shape_plan_t *data = (hb_ot_shape_plan_t *) calloc (1, sizeof (hb_ot_shape_plan_t));
+ if (unlikely (!data))
+ return NULL;
+
+ hb_ot_shape_planner_t planner;
+
+ assert (HB_DIRECTION_IS_VALID (shape_plan->props.direction));
+
+ planner.shaper = hb_ot_shape_complex_categorize (&shape_plan->props);
+
+ hb_ot_shape_collect_features (&planner, &shape_plan->props, user_features, num_user_features);
+
+ planner.compile (shape_plan->face, &shape_plan->props, *data);
+
+ return data;
+}
+
+void
+_hb_ot_shaper_shape_plan_data_destroy (hb_ot_shaper_shape_plan_data_t *data)
+{
+ data->map.finish ();
+}
+
+
+/*
+ * shaper
+ */
+
struct hb_ot_shape_context_t
{
- /* Input to hb_ot_shape_execute() */
+ /* Input to hb_ot_shape_internal() */
hb_ot_shape_plan_t *plan;
hb_font_t *font;
hb_face_t *face;
@@ -458,7 +472,7 @@ hb_hide_zerowidth (hb_ot_shape_context_t *c)
/* Do it! */
static void
-hb_ot_shape_execute_internal (hb_ot_shape_context_t *c)
+hb_ot_shape_internal (hb_ot_shape_context_t *c)
{
c->buffer->deallocate_var_all ();
@@ -514,34 +528,6 @@ hb_ot_shape_execute_internal (hb_ot_shape_context_t *c)
c->buffer->deallocate_var_all ();
}
-static void
-hb_ot_shape_plan_internal (hb_ot_shape_plan_t *plan,
- hb_face_t *face,
- const hb_segment_properties_t *props,
- const hb_feature_t *user_features,
- unsigned int num_user_features)
-{
- hb_ot_shape_planner_t planner;
-
- assert (HB_DIRECTION_IS_VALID (props->direction));
-
- planner.shaper = hb_ot_shape_complex_categorize (props);
-
- hb_ot_shape_collect_features (&planner, props, user_features, num_user_features);
-
- planner.compile (face, props, *plan);
-}
-
-static void
-hb_ot_shape_execute (hb_ot_shape_plan_t *plan,
- hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *user_features,
- unsigned int num_user_features)
-{
- hb_ot_shape_context_t c = {plan, font, font->face, buffer, user_features, num_user_features};
- hb_ot_shape_execute_internal (&c);
-}
hb_bool_t
_hb_ot_shape (hb_shape_plan_t *shape_plan,
@@ -550,12 +536,8 @@ _hb_ot_shape (hb_shape_plan_t *shape_plan,
const hb_feature_t *features,
unsigned int num_features)
{
- hb_ot_shape_plan_t plan;
-
- buffer->guess_properties ();
-
- hb_ot_shape_plan_internal (&plan, font->face, &buffer->props, features, num_features);
- hb_ot_shape_execute (&plan, font, buffer, features, num_features);
+ hb_ot_shape_context_t c = {HB_SHAPER_DATA_GET (shape_plan), font, font->face, buffer, features, num_features};
+ hb_ot_shape_internal (&c);
return true;
}
@@ -572,7 +554,8 @@ hb_ot_shape_glyphs_closure (hb_font_t *font,
buffer->guess_properties ();
- hb_ot_shape_plan_internal (&plan, font->face, &buffer->props, features, num_features);
+ /* TODO cache / ensure correct backend, etc. */
+ hb_shape_plan_t *shape_plan = hb_shape_plan_create (font->face, &buffer->props, features, num_features, NULL);
/* TODO: normalization? have shapers do closure()? */
/* TODO: Deal with mirrored chars? */
@@ -590,6 +573,8 @@ hb_ot_shape_glyphs_closure (hb_font_t *font,
do {
copy.set (glyphs);
- plan.map.substitute_closure (font->face, glyphs);
+ HB_SHAPER_DATA_GET (shape_plan)->map.substitute_closure (font->face, glyphs);
} while (!copy.equal (glyphs));
+
+ hb_shape_plan_destroy (shape_plan);
}
diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc
index 67e245c..4368f68 100644
--- a/src/hb-uniscribe.cc
+++ b/src/hb-uniscribe.cc
@@ -144,7 +144,7 @@ populate_log_font (LOGFONTW *lf,
hb_uniscribe_shaper_font_data_t *
_hb_uniscribe_shaper_font_data_create (hb_font_t *font)
{
- hb_uniscribe_shaper_font_data_t * data = (hb_uniscribe_shaper_font_data_t *) calloc (1, sizeof (hb_uniscribe_shaper_font_data_t));
+ hb_uniscribe_shaper_font_data_t *data = (hb_uniscribe_shaper_font_data_t *) calloc (1, sizeof (hb_uniscribe_shaper_font_data_t));
if (unlikely (!data))
return NULL;
commit ea278d3895fe0c92801d692cd71d8d9f1de7c048
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Jul 27 02:12:28 2012 -0400
Partially switch ot shaper to shape_plan
diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index e06a7fa..b800aeb 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -46,6 +46,7 @@ typedef struct hb_segment_properties_t {
hb_language_t language;
ASSERT_POD ();
} hb_segment_properties_t;
+#define _HB_BUFFER_PROPS_DEFAULT { HB_DIRECTION_INVALID, HB_SCRIPT_INVALID, HB_LANGUAGE_INVALID }
struct hb_buffer_t {
diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc
index 2b4acff..f8c62ac 100644
--- a/src/hb-buffer.cc
+++ b/src/hb-buffer.cc
@@ -38,7 +38,6 @@
#endif
#define _HB_BUFFER_UNICODE_FUNCS_DEFAULT (const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_default))
-#define _HB_BUFFER_PROPS_DEFAULT { HB_DIRECTION_INVALID, HB_SCRIPT_INVALID, HB_LANGUAGE_INVALID }
/* Here is how the buffer works internally:
*
diff --git a/src/hb-font-private.hh b/src/hb-font-private.hh
index 2540dd6..f1b43c0 100644
--- a/src/hb-font-private.hh
+++ b/src/hb-font-private.hh
@@ -97,8 +97,6 @@ struct hb_face_t {
void *user_data;
hb_destroy_func_t destroy;
- struct hb_ot_layout_t *ot_layout;
-
unsigned int index;
unsigned int upem;
diff --git a/src/hb-font.cc b/src/hb-font.cc
index 1261077..5a3219a 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -589,10 +589,14 @@ static const hb_face_t _hb_face_nil = {
NULL, /* user_data */
NULL, /* destroy */
- NULL, /* ot_layout */
-
0, /* index */
- 1000 /* upem */
+ 1000, /* upem */
+
+ {
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+ }
};
@@ -613,8 +617,6 @@ hb_face_create_for_tables (hb_reference_table_func_t reference_table,
face->user_data = user_data;
face->destroy = destroy;
- face->ot_layout = _hb_ot_layout_create (face);
-
face->upem = 0;
return face;
@@ -707,8 +709,6 @@ hb_face_destroy (hb_face_t *face)
{
if (!hb_object_destroy (face)) return;
- _hb_ot_layout_destroy (face->ot_layout);
-
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, face);
#include "hb-shaper-list.hh"
#undef HB_SHAPER_IMPLEMENT
@@ -877,7 +877,13 @@ hb_font_get_empty (void)
const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */
NULL, /* user_data */
- NULL /* destroy */
+ NULL, /* destroy */
+
+ {
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+ }
};
return const_cast<hb_font_t *> (&_hb_font_nil);
diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 5b71407..a35f633 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -1553,7 +1553,7 @@ inline bool ExtensionPos::sanitize (hb_sanitize_context_t *c)
static inline bool position_lookup (hb_apply_context_t *c, unsigned int lookup_index)
{
- const GPOS &gpos = *(c->face->ot_layout->gpos);
+ const GPOS &gpos = *(hb_ot_layout_from_face (c->face)->gpos);
const PosLookup &l = gpos.get_lookup (lookup_index);
if (unlikely (c->nesting_level_left == 0))
diff --git a/src/hb-ot-layout-gsub-table.hh b/src/hb-ot-layout-gsub-table.hh
index 600a92a..038cb93 100644
--- a/src/hb-ot-layout-gsub-table.hh
+++ b/src/hb-ot-layout-gsub-table.hh
@@ -1241,7 +1241,7 @@ inline bool ExtensionSubst::is_reverse (void) const
static inline void closure_lookup (hb_closure_context_t *c, unsigned int lookup_index)
{
- const GSUB &gsub = *(c->face->ot_layout->gsub);
+ const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub);
const SubstLookup &l = gsub.get_lookup (lookup_index);
if (unlikely (c->nesting_level_left == 0))
@@ -1254,7 +1254,7 @@ static inline void closure_lookup (hb_closure_context_t *c, unsigned int lookup_
static inline bool substitute_lookup (hb_apply_context_t *c, unsigned int lookup_index)
{
- const GSUB &gsub = *(c->face->ot_layout->gsub);
+ const GSUB &gsub = *(hb_ot_layout_from_face (c->face)->gsub);
const SubstLookup &l = gsub.get_lookup (lookup_index);
if (unlikely (c->nesting_level_left == 0))
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index ba375aa..294c359 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -36,6 +36,7 @@
#include "hb-ot-shape-complex-private.hh"
+#define hb_ot_layout_from_face(face) ((hb_ot_layout_t *) face->shaper_data.ot)
/*
* GDEF
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index c6de75c..dff3673 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -70,17 +70,20 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout)
static inline const GDEF&
_get_gdef (hb_face_t *face)
{
- return likely (face->ot_layout && face->ot_layout->gdef) ? *face->ot_layout->gdef : Null(GDEF);
+ /* XXX ensure ot_layout, and speed up */
+ return *hb_ot_layout_from_face (face)->gdef;
}
static inline const GSUB&
_get_gsub (hb_face_t *face)
{
- return likely (face->ot_layout && face->ot_layout->gsub) ? *face->ot_layout->gsub : Null(GSUB);
+ /* XXX ensure ot_layout, and speed up */
+ return *hb_ot_layout_from_face (face)->gsub;
}
static inline const GPOS&
_get_gpos (hb_face_t *face)
{
- return likely (face->ot_layout && face->ot_layout->gpos) ? *face->ot_layout->gpos : Null(GPOS);
+ /* XXX ensure ot_layout, and speed up */
+ return *hb_ot_layout_from_face (face)->gpos;
}
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 639748e..22dea07 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -44,12 +44,13 @@
hb_ot_shaper_face_data_t *
_hb_ot_shaper_face_data_create (hb_face_t *face)
{
- return (hb_ot_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+ return _hb_ot_layout_create (face);
}
void
_hb_ot_shaper_face_data_destroy (hb_ot_shaper_face_data_t *data)
{
+ _hb_ot_layout_destroy (data);
}
diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc
index db21e88..099d09c 100644
--- a/src/hb-shape-plan.cc
+++ b/src/hb-shape-plan.cc
@@ -136,6 +136,17 @@ hb_shape_plan_get_empty (void)
{
static const hb_shape_plan_t _hb_shape_plan_nil = {
HB_OBJECT_HEADER_STATIC,
+
+ NULL, /* face */
+ _HB_BUFFER_PROPS_DEFAULT, /* props */
+
+ {NULL}, /* shapers */
+
+ {
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+ }
};
return const_cast<hb_shape_plan_t *> (&_hb_shape_plan_nil);
diff --git a/src/hb-shaper-private.hh b/src/hb-shaper-private.hh
index 1cf7c5b..e50d869 100644
--- a/src/hb-shaper-private.hh
+++ b/src/hb-shaper-private.hh
@@ -68,7 +68,8 @@ 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_INSTANCE(shaper, object, instance) (* (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
commit b6b7ba1313bf686e6ed567183466104c90504a67
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Jul 27 01:26:11 2012 -0400
Switch old and uniscribe backends to shape_plan
diff --git a/src/hb-old.cc b/src/hb-old.cc
index 77761e8..f938a9b 100644
--- a/src/hb-old.cc
+++ b/src/hb-old.cc
@@ -248,61 +248,6 @@ _hb_old_shaper_shape_plan_data_destroy (hb_old_shaper_shape_plan_data_t *data)
* shaper
*/
-
-static hb_user_data_key_t hb_old_data_key;
-
-static HB_Face
-_hb_old_face_get (hb_face_t *face)
-{
- HB_Face data = (HB_Face) hb_face_get_user_data (face, &hb_old_data_key);
- if (likely (data)) return data;
-
- data = _hb_old_shaper_face_data_create (face);
-
- if (unlikely (!data)) {
- DEBUG_MSG (OLD, face, "HB_NewFace failed");
- return NULL;
- }
-
- if (unlikely (!hb_face_set_user_data (face, &hb_old_data_key, data,
- (hb_destroy_func_t) _hb_old_shaper_face_data_destroy,
- false)))
- {
- _hb_old_shaper_face_data_destroy (data);
- data = (HB_Face) hb_face_get_user_data (face, &hb_old_data_key);
- if (data)
- return data;
- else
- return NULL;
- }
-
- return data;
-}
-
-
-static HB_Font
-_hb_old_font_get (hb_font_t *font)
-{
- /* Ouch, check user_data! */
- HB_Font data = _hb_old_shaper_font_data_create (font);
- if (!data)
- return NULL;
-
- if (unlikely (!hb_font_set_user_data (font, &hb_old_data_key, data,
- (hb_destroy_func_t) _hb_old_shaper_font_data_destroy,
- false)))
- {
- _hb_old_shaper_font_data_destroy (data);
- data = (HB_Font) hb_font_get_user_data (font, &hb_old_data_key);
- if (data)
- return data;
- else
- return NULL;
- }
-
- return data;
-}
-
hb_bool_t
_hb_old_shape (hb_shape_plan_t *shape_plan,
hb_font_t *font,
@@ -310,27 +255,12 @@ _hb_old_shape (hb_shape_plan_t *shape_plan,
const hb_feature_t *features,
unsigned int num_features)
{
- if (unlikely (!buffer->len))
- return true;
-
- buffer->guess_properties ();
+ hb_face_t *face = font->face;
+ HB_Face old_face = HB_SHAPER_DATA_GET (face);
+ HB_Font old_font = HB_SHAPER_DATA_GET (font);
bool backward = HB_DIRECTION_IS_BACKWARD (buffer->props.direction);
-#define FAIL(...) \
- HB_STMT_START { \
- DEBUG_MSG (OLD, NULL, __VA_ARGS__); \
- return false; \
- } HB_STMT_END;
-
- HB_Face old_face = _hb_old_face_get (font->face);
- if (unlikely (!old_face))
- FAIL ("Couldn't get old face");
-
- HB_Font old_font = _hb_old_font_get (font);
- if (unlikely (!old_font))
- FAIL ("Couldn't get old font");
-
retry:
unsigned int scratch_size;
@@ -398,7 +328,7 @@ retry:
{
buffer->ensure (buffer->allocated * 2);
if (buffer->in_error)
- FAIL ("Buffer resize failed");
+ return false;
goto retry;
}
return false;
@@ -429,7 +359,7 @@ retry:
buffer->ensure (num_glyphs);
if (buffer->in_error)
- FAIL ("Buffer in error");
+ return false;
buffer->len = num_glyphs;
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index 0087618..fde9cf2 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -82,6 +82,11 @@ hb_shape_full (hb_font_t *font,
unsigned int num_features,
const char * const *shaper_list)
{
+ if (unlikely (!buffer->len))
+ return true;
+
+ buffer->guess_properties ();
+
hb_shape_plan_t *shape_plan = hb_shape_plan_create (font->face, &buffer->props, features, num_features, shaper_list);
hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features);
hb_shape_plan_destroy (shape_plan);
diff --git a/src/hb-shaper-impl-private.hh b/src/hb-shaper-impl-private.hh
index 91ee14f..7844081 100644
--- a/src/hb-shaper-impl-private.hh
+++ b/src/hb-shaper-impl-private.hh
@@ -36,8 +36,7 @@
#ifdef HB_SHAPER
-/* For use in things like font->shaper_data() in the shaper implementations. */
-#define shaper_data() shaper_data.HB_SHAPER
+#define HB_SHAPER_DATA_GET(object) HB_SHAPER_DATA (HB_SHAPER, object)
#endif
diff --git a/src/hb-shaper-private.hh b/src/hb-shaper-private.hh
index 9e35ef8..1cf7c5b 100644
--- a/src/hb-shaper-private.hh
+++ b/src/hb-shaper-private.hh
@@ -69,15 +69,11 @@ struct hb_shaper_data_t {
#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_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
#define HB_SHAPER_DATA_PROTOTYPE(shaper, object) \
HB_SHAPER_DATA_TYPE (shaper, object); /* Type forward declaration. */ \
- static inline HB_SHAPER_DATA_TYPE (shaper, object) * \
- 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_EXTRA_ARGS); \
extern "C" HB_INTERNAL void \
diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc
index a7aa163..67e245c 100644
--- a/src/hb-uniscribe.cc
+++ b/src/hb-uniscribe.cc
@@ -55,38 +55,6 @@ DWORD GetFontData(
);
*/
-static bool
-populate_log_font (LOGFONTW *lf,
- hb_font_t *font)
-{
- memset (lf, 0, sizeof (*lf));
- lf->lfHeight = -font->y_scale;
- lf->lfCharSet = DEFAULT_CHARSET;
-
- hb_blob_t *blob = Sanitizer<name>::sanitize (hb_face_reference_table (font->face, HB_TAG ('n','a','m','e')));
- const name *name_table = Sanitizer<name>::lock_instance (blob);
- unsigned int len = name_table->get_name (3, 1, 0x409, 4,
- lf->lfFaceName,
- sizeof (lf->lfFaceName[0]) * LF_FACESIZE)
- / sizeof (lf->lfFaceName[0]);
- hb_blob_destroy (blob);
-
- if (unlikely (!len)) {
- DEBUG_MSG (UNISCRIBE, NULL, "Didn't find English name table entry");
- return false;
- }
- if (unlikely (len >= LF_FACESIZE)) {
- DEBUG_MSG (UNISCRIBE, NULL, "Font name too long");
- return false;
- }
-
- for (unsigned int i = 0; i < len; i++)
- lf->lfFaceName[i] = hb_be_uint16 (lf->lfFaceName[i]);
- lf->lfFaceName[len] = 0;
-
- return true;
-}
-
/*
* shaper face data
@@ -141,6 +109,38 @@ struct hb_uniscribe_shaper_font_data_t {
SCRIPT_CACHE script_cache;
};
+static bool
+populate_log_font (LOGFONTW *lf,
+ hb_font_t *font)
+{
+ memset (lf, 0, sizeof (*lf));
+ lf->lfHeight = -font->y_scale;
+ lf->lfCharSet = DEFAULT_CHARSET;
+
+ hb_blob_t *blob = Sanitizer<name>::sanitize (hb_face_reference_table (font->face, HB_TAG ('n','a','m','e')));
+ const name *name_table = Sanitizer<name>::lock_instance (blob);
+ unsigned int len = name_table->get_name (3, 1, 0x409, 4,
+ lf->lfFaceName,
+ sizeof (lf->lfFaceName[0]) * LF_FACESIZE)
+ / sizeof (lf->lfFaceName[0]);
+ hb_blob_destroy (blob);
+
+ if (unlikely (!len)) {
+ DEBUG_MSG (UNISCRIBE, NULL, "Didn't find English name table entry");
+ return false;
+ }
+ if (unlikely (len >= LF_FACESIZE)) {
+ DEBUG_MSG (UNISCRIBE, NULL, "Font name too long");
+ return false;
+ }
+
+ for (unsigned int i = 0; i < len; i++)
+ lf->lfFaceName[i] = hb_be_uint16 (lf->lfFaceName[i]);
+ lf->lfFaceName[len] = 0;
+
+ return true;
+}
+
hb_uniscribe_shaper_font_data_t *
_hb_uniscribe_shaper_font_data_create (hb_font_t *font)
{
@@ -208,65 +208,18 @@ _hb_uniscribe_shaper_shape_plan_data_destroy (hb_uniscribe_shaper_shape_plan_dat
/*
* shaper
*/
-static hb_user_data_key_t hb_uniscribe_data_key;
-
-static hb_uniscribe_shaper_face_data_t *
-_hb_uniscribe_face_get_data (hb_face_t *face)
-{
- hb_uniscribe_shaper_face_data_t *data = (hb_uniscribe_shaper_face_data_t *) hb_face_get_user_data (face, &hb_uniscribe_data_key);
- if (likely (data)) return data;
-
- data = _hb_uniscribe_shaper_face_data_create (face);
- if (!data) return NULL;
-
- if (unlikely (!hb_face_set_user_data (face, &hb_uniscribe_data_key, data,
- (hb_destroy_func_t) _hb_uniscribe_shaper_face_data_destroy,
- false)))
- {
- _hb_uniscribe_shaper_face_data_destroy (data);
- data = (hb_uniscribe_shaper_face_data_t *) hb_face_get_user_data (face, &hb_uniscribe_data_key);
- }
-
- return data;
-}
-
-
-static hb_uniscribe_shaper_font_data_t *
-_hb_uniscribe_font_get_data (hb_font_t *font)
-{
- hb_uniscribe_shaper_font_data_t *data = (hb_uniscribe_shaper_font_data_t *) hb_font_get_user_data (font, &hb_uniscribe_data_key);
- if (likely (data)) return data;
-
- data = _hb_uniscribe_shaper_font_data_create (font);
- if (unlikely (!data))
- return NULL;
-
- if (unlikely (!hb_font_set_user_data (font, &hb_uniscribe_data_key, data,
- (hb_destroy_func_t) _hb_uniscribe_shaper_font_data_destroy,
- false)))
- {
- _hb_uniscribe_shaper_font_data_destroy (data);
- data = (hb_uniscribe_shaper_font_data_t *) hb_font_get_user_data (font, &hb_uniscribe_data_key);
- }
-
- return data;
-}
LOGFONTW *
hb_uniscribe_font_get_logfontw (hb_font_t *font)
{
- hb_uniscribe_shaper_font_data_t *font_data = _hb_uniscribe_font_get_data (font);
- if (unlikely (!font_data))
- return NULL;
+ hb_uniscribe_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
return &font_data->log_font;
}
HFONT
hb_uniscribe_font_get_hfont (hb_font_t *font)
{
- hb_uniscribe_shaper_font_data_t *font_data = _hb_uniscribe_font_get_data (font);
- if (unlikely (!font_data))
- return 0;
+ hb_uniscribe_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
return font_data->hfont;
}
@@ -278,7 +231,9 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan,
const hb_feature_t *features,
unsigned int num_features)
{
- buffer->guess_properties ();
+ hb_face_t *face = font->face;
+ hb_uniscribe_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
+ hb_uniscribe_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
#define FAIL(...) \
HB_STMT_START { \
@@ -286,17 +241,6 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan,
return false; \
} HB_STMT_END;
- hb_uniscribe_shaper_face_data_t *face_data = _hb_uniscribe_face_get_data (font->face);
- if (unlikely (!face_data->fh))
- FAIL ("Couldn't get face data");
-
- hb_uniscribe_shaper_font_data_t *font_data = _hb_uniscribe_font_get_data (font);
- if (unlikely (!font_data->hfont))
- FAIL ("Couldn't get font font");
-
- if (unlikely (!buffer->len))
- return true;
-
HRESULT hr;
retry:
commit c32c096a429da3e64896cf42ff5ab8c775d3c2ec
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Fri Jul 27 01:13:53 2012 -0400
Switch to shape_plan
Not optimized yet. Eats babies. And no shaper uses the shape_plan.
diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc
index 372543b..db21e88 100644
--- a/src/hb-shape-plan.cc
+++ b/src/hb-shape-plan.cc
@@ -48,7 +48,9 @@ hb_##shaper##_##object##_data_ensure (hb_##object##_t *object) \
return data != NULL && !HB_SHAPER_DATA_IS_INVALID (data); \
}
-#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_ENSURE_DECLARE(shaper, face)
+#define HB_SHAPER_IMPLEMENT(shaper) \
+ HB_SHAPER_DATA_ENSURE_DECLARE(shaper, face) \
+ HB_SHAPER_DATA_ENSURE_DECLARE(shaper, font)
#include "hb-shaper-list.hh"
#undef HB_SHAPER_IMPLEMENT
@@ -65,7 +67,6 @@ hb_shape_plan_plan (hb_shape_plan_t *shape_plan,
#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) { \
@@ -157,3 +158,35 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
free (shape_plan);
}
+
+
+hb_bool_t
+hb_shape_plan_execute (hb_shape_plan *shape_plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features)
+{
+ if (unlikely (shape_plan->face != font->face))
+ return false;
+
+#define HB_SHAPER_EXECUTE(shaper) \
+ HB_STMT_START { \
+ if (hb_##shaper##_font_data_ensure (font) && \
+ _hb_##shaper##_shape (shape_plan, font, buffer, features, num_features)) \
+ return true; \
+ } HB_STMT_END
+
+ for (hb_shape_func_t **shaper_func = shape_plan->shapers; *shaper_func; shaper_func++)
+ if (0)
+ ;
+#define HB_SHAPER_IMPLEMENT(shaper) \
+ else if (*shaper_func == _hb_##shaper##_shape) \
+ HB_SHAPER_EXECUTE (shaper);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+#undef HB_SHAPER_EXECUTE
+
+ return false;
+}
diff --git a/src/hb-shape-plan.h b/src/hb-shape-plan.h
index 5160b95..a4786a8 100644
--- a/src/hb-shape-plan.h
+++ b/src/hb-shape-plan.h
@@ -57,4 +57,12 @@ HB_INTERNAL void
hb_shape_plan_destroy (hb_shape_plan_t *shape_plan);
+HB_INTERNAL hb_bool_t
+hb_shape_plan_execute (hb_shape_plan *shape_plan,
+ hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features);
+
+
#endif /* HB_SHAPE_PLAN_H */
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index d017425..0087618 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -32,7 +32,6 @@
#include "hb-font-private.hh"
-
static const char **static_shaper_list;
static
@@ -83,28 +82,10 @@ 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 */
-
- if (likely (!shaper_list)) {
- for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++)
- if (likely (shapers[i].func (NULL, font, buffer, features, num_features)))
- return true;
- } else {
- while (*shaper_list) {
- for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++)
- if (0 == strcmp (*shaper_list, shapers[i].name)) {
- if (likely (shapers[i].func (NULL, font, buffer, features, num_features)))
- return true;
- break;
- }
- shaper_list++;
- }
- }
- return false;
+ hb_shape_plan_t *shape_plan = hb_shape_plan_create (font->face, &buffer->props, features, num_features, shaper_list);
+ hb_bool_t res = hb_shape_plan_execute (shape_plan, font, buffer, features, num_features);
+ hb_shape_plan_destroy (shape_plan);
+ return res;
}
void
commit 5b95c148cc485f79fd7018bc4520b4cb5f728a18
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Jul 26 23:46:53 2012 -0400
Start implementing shape_plan
diff --git a/src/hb-fallback-shape.cc b/src/hb-fallback-shape.cc
index 48aba73..52b46b1 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 97a86d5..2540dd6 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 879ee70..77761e8 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 a3c4153..639748e 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 68246f4..c292f14 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 e76847d..372543b 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 3915de7..d017425 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 fa279bc..9e35ef8 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 faba587..a7aa163 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;
}
commit bd26b4d21f59312805d294f46f15182adbcc47da
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Jul 26 22:05:39 2012 -0400
Minor
diff --git a/src/Makefile.am b/src/Makefile.am
index 847c9e7..9b583fd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -47,6 +47,7 @@ HBSOURCES = \
hb-shaper-list.hh \
hb-shaper-impl-private.hh \
hb-shaper-private.hh \
+ hb-shaper.cc \
hb-tt-font.cc \
hb-unicode-private.hh \
hb-unicode.cc \
diff --git a/src/hb-fallback-shape.cc b/src/hb-fallback-shape.cc
index 4c9a3b3..48aba73 100644
--- a/src/hb-fallback-shape.cc
+++ b/src/hb-fallback-shape.cc
@@ -87,7 +87,8 @@ _hb_fallback_shaper_shape_plan_data_destroy (hb_fallback_shaper_shape_plan_data_
*/
hb_bool_t
-_hb_fallback_shape (hb_font_t *font,
+_hb_fallback_shape (hb_shape_plan_t *shape_plan,
+ hb_font_t *font,
hb_buffer_t *buffer,
const hb_feature_t *features HB_UNUSED,
unsigned int num_features HB_UNUSED)
diff --git a/src/hb-old.cc b/src/hb-old.cc
index b898b3f..879ee70 100644
--- a/src/hb-old.cc
+++ b/src/hb-old.cc
@@ -302,7 +302,8 @@ _hb_old_font_get (hb_font_t *font)
}
hb_bool_t
-_hb_old_shape (hb_font_t *font,
+_hb_old_shape (hb_shape_plan_t *shape_plan,
+ hb_font_t *font,
hb_buffer_t *buffer,
const hb_feature_t *features,
unsigned int num_features)
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 512ffa5..a3c4153 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -541,7 +541,8 @@ hb_ot_shape_execute (hb_ot_shape_plan_t *plan,
}
hb_bool_t
-_hb_ot_shape (hb_font_t *font,
+_hb_ot_shape (hb_shape_plan_t *shape_plan,
+ hb_font_t *font,
hb_buffer_t *buffer,
const hb_feature_t *features,
unsigned int num_features)
diff --git a/src/hb-shape-plan-private.hh b/src/hb-shape-plan-private.hh
index 1f54608..68246f4 100644
--- a/src/hb-shape-plan-private.hh
+++ b/src/hb-shape-plan-private.hh
@@ -39,7 +39,7 @@ struct hb_shape_plan_t
hb_object_header_t header;
ASSERT_POD ();
- hb_shape_func_t *shapers[HB_NUM_SHAPERS];
+ hb_shape_func_t *shapers[HB_SHAPERS_COUNT];
struct hb_shaper_data_t shaper_data;
};
diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc
index b96d5f2..e76847d 100644
--- a/src/hb-shape-plan.cc
+++ b/src/hb-shape-plan.cc
@@ -53,6 +53,8 @@ hb_shape_plan_create (hb_face_t *face,
hb_face_make_immutable (face);
+ /* Plan! */
+
return shape_plan;
}
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index a1f3402..3915de7 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -30,85 +30,6 @@
#include "hb-buffer-private.hh"
-static const struct hb_shaper_pair_t {
- char name[16];
- hb_shape_func_t *func;
-} all_shapers[] = {
-#define HB_SHAPER_IMPLEMENT(name) {#name, _hb_##name##_shape},
-#include "hb-shaper-list.hh"
-#undef HB_SHAPER_IMPLEMENT
-};
-
-
-/* Thread-safe, lock-free, shapers */
-
-static const hb_shaper_pair_t *static_shapers;
-
-static
-void free_static_shapers (void)
-{
- if (unlikely (static_shapers != all_shapers))
- free ((void *) static_shapers);
-}
-
-static const hb_shaper_pair_t *
-get_shapers (void)
-{
-retry:
- hb_shaper_pair_t *shapers = (hb_shaper_pair_t *) hb_atomic_ptr_get (&static_shapers);
-
- if (unlikely (!shapers))
- {
- char *env = getenv ("HB_SHAPER_LIST");
- if (!env || !*env) {
- (void) hb_atomic_ptr_cmpexch (&static_shapers, NULL, &all_shapers[0]);
- return (const hb_shaper_pair_t *) all_shapers;
- }
-
- /* Not found; allocate one. */
- shapers = (hb_shaper_pair_t *) malloc (sizeof (all_shapers));
- if (unlikely (!shapers))
- return (const hb_shaper_pair_t *) all_shapers;
- memcpy (shapers, all_shapers, sizeof (all_shapers));
-
- /* Reorder shaper list to prefer requested shapers. */
- unsigned int i = 0;
- char *end, *p = env;
- for (;;) {
- end = strchr (p, ',');
- if (!end)
- end = p + strlen (p);
-
- for (unsigned int j = i; j < ARRAY_LENGTH (all_shapers); j++)
- if (end - p == (int) strlen (shapers[j].name) &&
- 0 == strncmp (shapers[j].name, p, end - p))
- {
- /* Reorder this shaper to position i */
- struct hb_shaper_pair_t t = shapers[j];
- memmove (&shapers[i + 1], &shapers[i], sizeof (shapers[i]) * (j - i));
- shapers[i] = t;
- i++;
- }
-
- if (!*end)
- break;
- else
- p = end + 1;
- }
-
- if (!hb_atomic_ptr_cmpexch (&static_shapers, NULL, shapers)) {
- free (shapers);
- goto retry;
- }
-
-#ifdef HAVE_ATEXIT
- atexit (free_static_shapers); /* First person registers atexit() callback. */
-#endif
- }
-
- return shapers;
-}
-
static const char **static_shaper_list;
@@ -127,15 +48,15 @@ retry:
if (unlikely (!shaper_list))
{
/* Not found; allocate one. */
- shaper_list = (const char **) calloc (1 + ARRAY_LENGTH (all_shapers), sizeof (const char *));
+ shaper_list = (const char **) calloc (1 + HB_SHAPERS_COUNT, sizeof (const char *));
if (unlikely (!shaper_list)) {
static const char *nil_shaper_list[] = {NULL};
return nil_shaper_list;
}
- const hb_shaper_pair_t *shapers = get_shapers ();
+ const hb_shaper_pair_t *shapers = _hb_shapers_get ();
unsigned int i;
- for (i = 0; i < ARRAY_LENGTH (all_shapers); i++)
+ for (i = 0; i < HB_SHAPERS_COUNT; i++)
shaper_list[i] = shapers[i].name;
shaper_list[i] = NULL;
@@ -160,18 +81,19 @@ hb_shape_full (hb_font_t *font,
unsigned int num_features,
const char * const *shaper_list)
{
+ const hb_shaper_pair_t *shapers = _hb_shapers_get ();
+
hb_font_make_immutable (font); /* So we can safely cache stuff on it */
if (likely (!shaper_list)) {
- const hb_shaper_pair_t *shapers = get_shapers ();
- for (unsigned int i = 0; i < ARRAY_LENGTH (all_shapers); i++)
- if (likely (shapers[i].func (font, buffer, features, num_features)))
+ for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++)
+ if (likely (shapers[i].func (NULL, font, buffer, features, num_features)))
return true;
} else {
while (*shaper_list) {
- for (unsigned int i = 0; i < ARRAY_LENGTH (all_shapers); i++)
- if (0 == strcmp (*shaper_list, all_shapers[i].name)) {
- if (likely (all_shapers[i].func (font, buffer, features, num_features)))
+ for (unsigned int i = 0; i < HB_SHAPERS_COUNT; i++)
+ if (0 == strcmp (*shaper_list, shapers[i].name)) {
+ if (likely (shapers[i].func (NULL, font, buffer, features, num_features)))
return true;
break;
}
diff --git a/src/hb-shaper-private.hh b/src/hb-shaper-private.hh
index 88be96c..fa279bc 100644
--- a/src/hb-shaper-private.hh
+++ b/src/hb-shaper-private.hh
@@ -29,7 +29,10 @@
#include "hb-private.hh"
-typedef hb_bool_t hb_shape_func_t (hb_font_t *font,
+#include "hb-shape-plan.h" /* TODO remove */
+
+typedef hb_bool_t hb_shape_func_t (hb_shape_plan_t *shape_plan,
+ hb_font_t *font,
hb_buffer_t *buffer,
const hb_feature_t *features,
unsigned int num_features);
@@ -39,6 +42,15 @@ typedef hb_bool_t hb_shape_func_t (hb_font_t *font,
#include "hb-shaper-list.hh"
#undef HB_SHAPER_IMPLEMENT
+struct hb_shaper_pair_t {
+ char name[16];
+ hb_shape_func_t *func;
+};
+
+HB_INTERNAL const hb_shaper_pair_t *
+_hb_shapers_get (void);
+
+
/* For embedding in face / font / ... */
struct hb_shaper_data_t {
#define HB_SHAPER_IMPLEMENT(shaper) void *shaper;
@@ -46,7 +58,7 @@ struct hb_shaper_data_t {
#undef HB_SHAPER_IMPLEMENT
};
-#define HB_NUM_SHAPERS (sizeof (hb_shaper_data_t) / sizeof (void *))
+#define HB_SHAPERS_COUNT (sizeof (hb_shaper_data_t) / sizeof (void *))
/* Means: succeeded, but don't need to keep any data. */
#define HB_SHAPER_DATA_SUCCEEDED ((void *) +1)
diff --git a/src/hb-shaper.cc b/src/hb-shaper.cc
new file mode 100644
index 0000000..a16ffc8
--- /dev/null
+++ b/src/hb-shaper.cc
@@ -0,0 +1,109 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-private.hh"
+
+#include "hb-shaper-private.hh"
+
+
+static const hb_shaper_pair_t all_shapers[] = {
+#define HB_SHAPER_IMPLEMENT(name) {#name, _hb_##name##_shape},
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+};
+
+
+/* Thread-safe, lock-free, shapers */
+
+static const hb_shaper_pair_t *static_shapers;
+
+static
+void free_static_shapers (void)
+{
+ if (unlikely (static_shapers != all_shapers))
+ free ((void *) static_shapers);
+}
+
+const hb_shaper_pair_t *
+_hb_shapers_get (void)
+{
+retry:
+ hb_shaper_pair_t *shapers = (hb_shaper_pair_t *) hb_atomic_ptr_get (&static_shapers);
+
+ if (unlikely (!shapers))
+ {
+ char *env = getenv ("HB_SHAPER_LIST");
+ if (!env || !*env) {
+ (void) hb_atomic_ptr_cmpexch (&static_shapers, NULL, &all_shapers[0]);
+ return (const hb_shaper_pair_t *) all_shapers;
+ }
+
+ /* Not found; allocate one. */
+ shapers = (hb_shaper_pair_t *) malloc (sizeof (all_shapers));
+ if (unlikely (!shapers)) {
+ (void) hb_atomic_ptr_cmpexch (&static_shapers, NULL, &all_shapers[0]);
+ return (const hb_shaper_pair_t *) all_shapers;
+ }
+
+ memcpy (shapers, all_shapers, sizeof (all_shapers));
+
+ /* Reorder shaper list to prefer requested shapers. */
+ unsigned int i = 0;
+ char *end, *p = env;
+ for (;;) {
+ end = strchr (p, ',');
+ if (!end)
+ end = p + strlen (p);
+
+ for (unsigned int j = i; j < ARRAY_LENGTH (all_shapers); j++)
+ if (end - p == (int) strlen (shapers[j].name) &&
+ 0 == strncmp (shapers[j].name, p, end - p))
+ {
+ /* Reorder this shaper to position i */
+ struct hb_shaper_pair_t t = shapers[j];
+ memmove (&shapers[i + 1], &shapers[i], sizeof (shapers[i]) * (j - i));
+ shapers[i] = t;
+ i++;
+ }
+
+ if (!*end)
+ break;
+ else
+ p = end + 1;
+ }
+
+ if (!hb_atomic_ptr_cmpexch (&static_shapers, NULL, shapers)) {
+ free (shapers);
+ goto retry;
+ }
+
+#ifdef HAVE_ATEXIT
+ atexit (free_static_shapers); /* First person registers atexit() callback. */
+#endif
+ }
+
+ return shapers;
+}
diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc
index fe7be70..faba587 100644
--- a/src/hb-uniscribe.cc
+++ b/src/hb-uniscribe.cc
@@ -270,7 +270,8 @@ hb_uniscribe_font_get_hfont (hb_font_t *font)
hb_bool_t
-_hb_uniscribe_shape (hb_font_t *font,
+_hb_uniscribe_shape (hb_shape_plan_t *shape_plan,
+ hb_font_t *font,
hb_buffer_t *buffer,
const hb_feature_t *features,
unsigned int num_features)
commit 027857d0412477fb4427dcb8a8c45287c272e143
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Jul 26 17:34:25 2012 -0400
Start adding a unified shaper access infrastructure
Add global shape_plan. Unused so far.
diff --git a/src/Makefile.am b/src/Makefile.am
index b1255fa..847c9e7 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -24,7 +24,6 @@ HBSOURCES = \
hb-buffer.cc \
hb-cache-private.hh \
hb-common.cc \
- hb-fallback-shape-private.hh \
hb-fallback-shape.cc \
hb-font-private.hh \
hb-font.cc \
@@ -42,6 +41,12 @@ HBSOURCES = \
hb-set-private.hh \
hb-set.cc \
hb-shape.cc \
+ hb-shape-plan-private.hh \
+ hb-shape-plan.cc \
+ hb-shape-plan.h \
+ hb-shaper-list.hh \
+ hb-shaper-impl-private.hh \
+ hb-shaper-private.hh \
hb-tt-font.cc \
hb-unicode-private.hh \
hb-unicode.cc \
@@ -129,21 +134,21 @@ endif
if HAVE_GRAPHITE2
HBCFLAGS += $(GRAPHITE2_CFLAGS)
HBLIBS += $(GRAPHITE2_LIBS)
-HBSOURCES += hb-graphite2.cc hb-graphite2-private.hh
+HBSOURCES += hb-graphite2.cc
HBHEADERS += hb-graphite2.h
endif
if HAVE_UNISCRIBE
HBCFLAGS += $(UNISCRIBE_CFLAGS)
HBLIBS += $(UNISCRIBE_LIBS)
-HBSOURCES += hb-uniscribe.cc hb-uniscribe-private.hh
+HBSOURCES += hb-uniscribe.cc
HBHEADERS += hb-uniscribe.h
endif
if HAVE_CORETEXT
HBCFLAGS += $(CORETEXT_CFLAGS)
HBLIBS += $(CORETEXT_LIBS)
-HBSOURCES += hb-coretext.cc hb-coretext-private.hh
+HBSOURCES += hb-coretext.cc
HBHEADERS += hb-coretext.h
endif
@@ -151,7 +156,7 @@ if HAVE_HB_OLD
SUBDIRS += hb-old
HBCFLAGS += -I$(srcdir)/hb-old
HBLIBS += hb-old/libhb-old.la
-HBSOURCES += hb-old.cc hb-old-private.hh
+HBSOURCES += hb-old.cc
endif
DIST_SUBDIRS += hb-old
diff --git a/src/hb-coretext-private.hh b/src/hb-coretext-private.hh
deleted file mode 100644
index 153106c..0000000
--- a/src/hb-coretext-private.hh
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright © 2012 Mozilla Foundation.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Mozilla Author(s): Jonathan Kew
- */
-
-#ifndef HB_CORETEXT_PRIVATE_HH
-#define HB_CORETEXT_PRIVATE_HH
-
-#include "hb-private.hh"
-
-#include "hb-coretext.h"
-
-
-HB_INTERNAL hb_bool_t
-_hb_coretext_shape (hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *features,
- unsigned int num_features);
-
-
-#endif /* HB_CORETEXT_PRIVATE_HH */
diff --git a/src/hb-coretext.cc b/src/hb-coretext.cc
index c99ffc4..6e09c5e 100644
--- a/src/hb-coretext.cc
+++ b/src/hb-coretext.cc
@@ -24,7 +24,8 @@
* Mozilla Author(s): Jonathan Kew
*/
-#include "hb-private.hh"
+#define HB_SHAPER coretext
+#include "hb-shaper-private.hh"
#define GlyphID GlyphID_mac
#include <ApplicationServices/ApplicationServices.h>
@@ -32,9 +33,6 @@
#include "hb-coretext.h"
-#include "hb-ot-name-table.hh"
-#include "hb-ot-tag.h"
-
#include "hb-font-private.hh"
#include "hb-buffer-private.hh"
diff --git a/src/hb-fallback-shape-private.hh b/src/hb-fallback-shape-private.hh
deleted file mode 100644
index 0ef155c..0000000
--- a/src/hb-fallback-shape-private.hh
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright © 2011 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_FALLBACK_SHAPE_PRIVATE_HH
-#define HB_FALLBACK_SHAPE_PRIVATE_HH
-
-#include "hb-private.hh"
-
-#include "hb-shape.h"
-
-
-HB_INTERNAL hb_bool_t
-_hb_fallback_shape (hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *features,
- unsigned int num_features);
-
-#endif /* HB_FALLBACK_SHAPE_PRIVATE_HH */
diff --git a/src/hb-fallback-shape.cc b/src/hb-fallback-shape.cc
index b9480e6..4c9a3b3 100644
--- a/src/hb-fallback-shape.cc
+++ b/src/hb-fallback-shape.cc
@@ -24,9 +24,67 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb-fallback-shape-private.hh"
+#define HB_SHAPER fallback
+#include "hb-shaper-impl-private.hh"
-#include "hb-buffer-private.hh"
+
+/*
+ * shaper face data
+ */
+
+struct hb_fallback_shaper_face_data_t {};
+
+hb_fallback_shaper_face_data_t *
+_hb_fallback_shaper_face_data_create (hb_face_t *face)
+{
+ return (hb_fallback_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_fallback_shaper_face_data_destroy (hb_fallback_shaper_face_data_t *data)
+{
+}
+
+
+/*
+ * shaper font data
+ */
+
+struct hb_fallback_shaper_font_data_t {};
+
+hb_fallback_shaper_font_data_t *
+_hb_fallback_shaper_font_data_create (hb_font_t *font)
+{
+ return (hb_fallback_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_fallback_shaper_font_data_destroy (hb_fallback_shaper_font_data_t *data)
+{
+}
+
+
+/*
+ * shaper shape_plan 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)
+{
+ return (hb_fallback_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_fallback_shaper_shape_plan_data_destroy (hb_fallback_shaper_shape_plan_data_t *data)
+{
+}
+
+
+/*
+ * shaper
+ */
hb_bool_t
_hb_fallback_shape (hb_font_t *font,
diff --git a/src/hb-font-private.hh b/src/hb-font-private.hh
index 2f74cfa..97a86d5 100644
--- a/src/hb-font-private.hh
+++ b/src/hb-font-private.hh
@@ -33,6 +33,7 @@
#include "hb-font.h"
#include "hb-object-private.hh"
+#include "hb-shaper-private.hh"
@@ -100,8 +101,14 @@ struct hb_face_t {
unsigned int index;
unsigned int upem;
+
+ struct hb_shaper_data_t shaper_data;
};
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, face);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
/*
* hb_font_t
@@ -126,6 +133,8 @@ struct hb_font_t {
void *user_data;
hb_destroy_func_t destroy;
+ struct hb_shaper_data_t shaper_data;
+
/* Convert from font-space to user-space */
inline hb_position_t em_scale_x (int16_t v) { return em_scale (v, this->x_scale); }
@@ -163,6 +172,9 @@ 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_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, font);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
#endif /* HB_FONT_PRIVATE_HH */
diff --git a/src/hb-font.cc b/src/hb-font.cc
index 7c62fbe..1261077 100644
--- a/src/hb-font.cc
+++ b/src/hb-font.cc
@@ -1,5 +1,6 @@
/*
* Copyright © 2009 Red Hat, Inc.
+ * Copyright © 2012 Google, Inc.
*
* This is part of HarfBuzz, a text shaping library.
*
@@ -22,6 +23,7 @@
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
* Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
*/
#include "hb-private.hh"
@@ -707,6 +709,10 @@ hb_face_destroy (hb_face_t *face)
_hb_ot_layout_destroy (face->ot_layout);
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, face);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
if (face->destroy)
face->destroy (face->user_data);
@@ -888,11 +894,16 @@ 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
+
+ if (font->destroy)
+ font->destroy (font->user_data);
+
hb_font_destroy (font->parent);
hb_face_destroy (font->face);
hb_font_funcs_destroy (font->klass);
- if (font->destroy)
- font->destroy (font->user_data);
free (font);
}
diff --git a/src/hb-graphite2-private.hh b/src/hb-graphite2-private.hh
deleted file mode 100644
index 644ea75..0000000
--- a/src/hb-graphite2-private.hh
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright © 2012 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_GRAPHITE2_PRIVATE_HH
-#define HB_GRAPHITE2_PRIVATE_HH
-
-#include "hb-private.hh"
-
-#include "hb-graphite2.h"
-
-
-HB_INTERNAL hb_bool_t
-_hb_graphite2_shape (hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *features,
- unsigned int num_features);
-
-
-#endif /* HB_GRAPHITE2_PRIVATE_HH */
diff --git a/src/hb-old-private.hh b/src/hb-old-private.hh
deleted file mode 100644
index 7c51321..0000000
--- a/src/hb-old-private.hh
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright © 2012 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_OLD_PRIVATE_HH
-#define HB_OLD_PRIVATE_HH
-
-#include "hb-private.hh"
-
-
-HB_INTERNAL hb_bool_t
-_hb_old_shape (hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *features,
- unsigned int num_features);
-
-
-#endif /* HB_OLD_PRIVATE_HH */
diff --git a/src/hb-old.cc b/src/hb-old.cc
index be0187f..b898b3f 100644
--- a/src/hb-old.cc
+++ b/src/hb-old.cc
@@ -24,12 +24,10 @@
* Google Author(s): Behdad Esfahbod
*/
-#include "hb-private.hh"
-
-#include "hb-old-private.hh"
-
-#include "hb-font-private.hh"
-#include "hb-buffer-private.hh"
+#define HB_SHAPER old
+#define hb_old_shaper_face_data_t HB_FaceRec_
+#define hb_old_shaper_font_data_t HB_Font_
+#include "hb-shaper-impl-private.hh"
#include <harfbuzz.h>
@@ -166,8 +164,6 @@ static const HB_FontClass hb_old_font_class = {
-static hb_user_data_key_t hb_old_data_key;
-
static HB_Error
table_func (void *font, HB_Tag tag, HB_Byte *buffer, HB_UInt *length)
{
@@ -180,13 +176,86 @@ table_func (void *font, HB_Tag tag, HB_Byte *buffer, HB_UInt *length)
return HB_Err_Ok;
}
+
+/*
+ * shaper face data
+ */
+
+hb_old_shaper_face_data_t *
+_hb_old_shaper_face_data_create (hb_face_t *face)
+{
+ return HB_NewFace (face, table_func);
+}
+
+void
+_hb_old_shaper_face_data_destroy (hb_old_shaper_face_data_t *data)
+{
+ HB_FreeFace (data);
+}
+
+
+/*
+ * shaper font data
+ */
+
+hb_old_shaper_font_data_t *
+_hb_old_shaper_font_data_create (hb_font_t *font)
+{
+ HB_FontRec *data = (HB_FontRec *) calloc (1, sizeof (HB_FontRec));
+ if (unlikely (!data)) {
+ DEBUG_MSG (OLD, font, "malloc()ing HB_Font failed");
+ return NULL;
+ }
+
+ data->klass = &hb_old_font_class;
+ data->x_ppem = font->x_ppem;
+ data->y_ppem = font->y_ppem;
+ data->x_scale = font->x_scale; // XXX
+ data->y_scale = font->y_scale; // XXX
+ data->userData = font;
+
+ return data;
+}
+
+void
+_hb_old_shaper_font_data_destroy (hb_old_shaper_font_data_t *data)
+{
+ free (data);
+}
+
+
+/*
+ * shaper shape_plan 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)
+{
+ return (hb_old_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_old_shaper_shape_plan_data_destroy (hb_old_shaper_shape_plan_data_t *data)
+{
+}
+
+
+/*
+ * shaper
+ */
+
+
+static hb_user_data_key_t hb_old_data_key;
+
static HB_Face
_hb_old_face_get (hb_face_t *face)
{
HB_Face data = (HB_Face) hb_face_get_user_data (face, &hb_old_data_key);
if (likely (data)) return data;
- data = HB_NewFace (face, table_func);
+ data = _hb_old_shaper_face_data_create (face);
if (unlikely (!data)) {
DEBUG_MSG (OLD, face, "HB_NewFace failed");
@@ -194,10 +263,10 @@ _hb_old_face_get (hb_face_t *face)
}
if (unlikely (!hb_face_set_user_data (face, &hb_old_data_key, data,
- (hb_destroy_func_t) HB_FreeFace,
+ (hb_destroy_func_t) _hb_old_shaper_face_data_destroy,
false)))
{
- HB_FreeFace (data);
+ _hb_old_shaper_face_data_destroy (data);
data = (HB_Face) hb_face_get_user_data (face, &hb_old_data_key);
if (data)
return data;
@@ -212,24 +281,16 @@ _hb_old_face_get (hb_face_t *face)
static HB_Font
_hb_old_font_get (hb_font_t *font)
{
- HB_Font data = (HB_Font) calloc (1, sizeof (HB_FontRec));
- if (unlikely (!data)) {
- DEBUG_MSG (OLD, font, "malloc()ing HB_Font failed");
+ /* Ouch, check user_data! */
+ HB_Font data = _hb_old_shaper_font_data_create (font);
+ if (!data)
return NULL;
- }
-
- data->klass = &hb_old_font_class;
- data->x_ppem = font->x_ppem;
- data->y_ppem = font->y_ppem;
- data->x_scale = font->x_scale; // XXX
- data->y_scale = font->y_scale; // XXX
- data->userData = font;
if (unlikely (!hb_font_set_user_data (font, &hb_old_data_key, data,
- (hb_destroy_func_t) free,
+ (hb_destroy_func_t) _hb_old_shaper_font_data_destroy,
false)))
{
- free (data);
+ _hb_old_shaper_font_data_destroy (data);
data = (HB_Font) hb_font_get_user_data (font, &hb_old_data_key);
if (data)
return data;
diff --git a/src/hb-ot-shape-private.hh b/src/hb-ot-shape-private.hh
index df0c705..8c8876a 100644
--- a/src/hb-ot-shape-private.hh
+++ b/src/hb-ot-shape-private.hh
@@ -46,14 +46,6 @@ struct hb_ot_shape_plan_t
};
-
-HB_INTERNAL hb_bool_t
-_hb_ot_shape (hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *features,
- unsigned int num_features);
-
-
inline void
_hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_unicode_funcs_t *unicode)
{
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 3b1c1d7..512ffa5 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -26,14 +26,72 @@
* Google Author(s): Behdad Esfahbod
*/
+#define HB_SHAPER ot
+#define hb_ot_shaper_face_data_t hb_ot_layout_t
+#include "hb-shaper-impl-private.hh"
+
#include "hb-ot-shape-private.hh"
#include "hb-ot-shape-normalize-private.hh"
#include "hb-ot-layout-private.hh"
-#include "hb-font-private.hh"
#include "hb-set-private.hh"
+/*
+ * shaper face data
+ */
+
+hb_ot_shaper_face_data_t *
+_hb_ot_shaper_face_data_create (hb_face_t *face)
+{
+ return (hb_ot_shaper_face_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_ot_shaper_face_data_destroy (hb_ot_shaper_face_data_t *data)
+{
+}
+
+
+/*
+ * shaper font data
+ */
+
+struct hb_ot_shaper_font_data_t {};
+
+hb_ot_shaper_font_data_t *
+_hb_ot_shaper_font_data_create (hb_font_t *font)
+{
+ return (hb_ot_shaper_font_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_ot_shaper_font_data_destroy (hb_ot_shaper_font_data_t *data)
+{
+}
+
+
+/*
+ * shaper shape_plan 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)
+{
+ return (hb_ot_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
+
+void
+_hb_ot_shaper_shape_plan_data_destroy (hb_ot_shaper_shape_plan_data_t *data)
+{
+}
+
+
+/*
+ * shaper
+ */
hb_tag_t common_features[] = {
HB_TAG('c','c','m','p'),
diff --git a/src/hb-shape-plan-private.hh b/src/hb-shape-plan-private.hh
new file mode 100644
index 0000000..1f54608
--- /dev/null
+++ b/src/hb-shape-plan-private.hh
@@ -0,0 +1,52 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_SHAPE_PLAN_PRIVATE_HH
+#define HB_SHAPE_PLAN_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-shape-plan.h"
+
+#include "hb-shaper-private.hh"
+
+
+struct hb_shape_plan_t
+{
+ hb_object_header_t header;
+ ASSERT_POD ();
+
+ hb_shape_func_t *shapers[HB_NUM_SHAPERS];
+
+ struct hb_shaper_data_t shaper_data;
+};
+
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, shape_plan);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+
+#endif /* HB_SHAPE_PLAN_PRIVATE_HH */
diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc
new file mode 100644
index 0000000..b96d5f2
--- /dev/null
+++ b/src/hb-shape-plan.cc
@@ -0,0 +1,85 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-private.hh"
+
+#include "hb-shape-plan-private.hh"
+
+#include "hb-font-private.hh"
+
+
+/*
+ * hb_shape_plan_t
+ */
+
+hb_shape_plan_t *
+hb_shape_plan_create (hb_face_t *face,
+ const hb_segment_properties_t *props,
+ const hb_feature_t *user_features,
+ unsigned int num_user_features,
+ const char * const *shaper_list)
+{
+ hb_shape_plan_t *shape_plan;
+
+ if (unlikely (!face))
+ face = hb_face_get_empty ();
+ if (unlikely (!props || hb_object_is_inert (face)))
+ return hb_shape_plan_get_empty ();
+ if (!(shape_plan = hb_object_create<hb_shape_plan_t> ()))
+ return hb_shape_plan_get_empty ();
+
+ hb_face_make_immutable (face);
+
+ return shape_plan;
+}
+
+hb_shape_plan_t *
+hb_shape_plan_get_empty (void)
+{
+ static const hb_shape_plan_t _hb_shape_plan_nil = {
+ HB_OBJECT_HEADER_STATIC,
+ };
+
+ return const_cast<hb_shape_plan_t *> (&_hb_shape_plan_nil);
+}
+
+hb_shape_plan_t *
+hb_shape_plan_reference (hb_shape_plan_t *shape_plan)
+{
+ return hb_object_reference (shape_plan);
+}
+
+void
+hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
+{
+ if (!hb_object_destroy (shape_plan)) return;
+
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, shape_plan);
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+ free (shape_plan);
+}
diff --git a/src/hb-shape-plan.h b/src/hb-shape-plan.h
new file mode 100644
index 0000000..5160b95
--- /dev/null
+++ b/src/hb-shape-plan.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_SHAPE_PLAN_H
+#define HB_SHAPE_PLAN_H
+
+/* TODO To become public one day */
+
+#include "hb-private.hh"
+
+#include "hb-buffer-private.hh"
+
+
+typedef struct hb_shape_plan_t hb_shape_plan;
+
+/*
+ * hb_shape_plan_t
+ */
+
+HB_INTERNAL hb_shape_plan_t *
+hb_shape_plan_create (hb_face_t *face,
+ const hb_segment_properties_t *props,
+ const hb_feature_t *user_features,
+ unsigned int num_user_features,
+ const char * const *shaper_list);
+
+HB_INTERNAL hb_shape_plan_t *
+hb_shape_plan_get_empty (void);
+
+HB_INTERNAL hb_shape_plan_t *
+hb_shape_plan_reference (hb_shape_plan_t *shape_plan);
+
+HB_INTERNAL void
+hb_shape_plan_destroy (hb_shape_plan_t *shape_plan);
+
+
+#endif /* HB_SHAPE_PLAN_H */
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index da7d9e0..a1f3402 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -26,56 +26,18 @@
#include "hb-private.hh"
-#include "hb-shape.h"
-
+#include "hb-shaper-private.hh"
#include "hb-buffer-private.hh"
-#ifdef HAVE_GRAPHITE
-#include "hb-graphite2-private.hh"
-#endif
-#ifdef HAVE_UNISCRIBE
-# include "hb-uniscribe-private.hh"
-#endif
-#ifdef HAVE_CORETEXT
-# include "hb-coretext-private.hh"
-#endif
-#ifdef HAVE_HB_OLD
-# include "hb-old-private.hh"
-#endif
-#ifdef HAVE_OT
-# include "hb-ot-shape-private.hh"
-#endif
-#include "hb-fallback-shape-private.hh"
-
-typedef hb_bool_t (*hb_shape_func_t) (hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *features,
- unsigned int num_features);
-#define HB_SHAPER_IMPLEMENT(name) {#name, _hb_##name##_shape}
static const struct hb_shaper_pair_t {
char name[16];
- hb_shape_func_t func;
+ hb_shape_func_t *func;
} all_shapers[] = {
- /* v--- Add new shapers in the right place here */
-#ifdef HAVE_GRAPHITE
- HB_SHAPER_IMPLEMENT (graphite2),
-#endif
-#ifdef HAVE_UNISCRIBE
- HB_SHAPER_IMPLEMENT (uniscribe),
-#endif
-#ifdef HAVE_CORETEXT
- HB_SHAPER_IMPLEMENT (coretext),
-#endif
-#ifdef HAVE_OT
- HB_SHAPER_IMPLEMENT (ot),
-#endif
-#ifdef HAVE_HB_OLD
- HB_SHAPER_IMPLEMENT (old),
-#endif
- HB_SHAPER_IMPLEMENT (fallback), /* This should be last. */
-};
+#define HB_SHAPER_IMPLEMENT(name) {#name, _hb_##name##_shape},
+#include "hb-shaper-list.hh"
#undef HB_SHAPER_IMPLEMENT
+};
/* Thread-safe, lock-free, shapers */
diff --git a/src/hb-shaper-impl-private.hh b/src/hb-shaper-impl-private.hh
new file mode 100644
index 0000000..91ee14f
--- /dev/null
+++ b/src/hb-shaper-impl-private.hh
@@ -0,0 +1,44 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_SHAPER_IMPL_PRIVATE_HH
+#define HB_SHAPER_IMPL_PRIVATE_HH
+
+#include "hb-private.hh"
+
+#include "hb-shaper-private.hh"
+#include "hb-shape-plan-private.hh"
+#include "hb-font-private.hh"
+#include "hb-buffer-private.hh"
+
+
+#ifdef HB_SHAPER
+/* For use in things like font->shaper_data() in the shaper implementations. */
+#define shaper_data() shaper_data.HB_SHAPER
+#endif
+
+
+#endif /* HB_SHAPER_IMPL_PRIVATE_HH */
diff --git a/src/hb-shaper-list.hh b/src/hb-shaper-list.hh
new file mode 100644
index 0000000..ff1fdfd
--- /dev/null
+++ b/src/hb-shaper-list.hh
@@ -0,0 +1,50 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_SHAPER_LIST_HH
+#define HB_SHAPER_LIST_HH
+#endif /* HB_SHAPER_LIST_HH */ /* Dummy header guards */
+
+/* v--- Add new shapers in the right place here. */
+#ifdef HAVE_GRAPHITE
+HB_SHAPER_IMPLEMENT (graphite2)
+#endif
+#ifdef HAVE_UNISCRIBE
+HB_SHAPER_IMPLEMENT (uniscribe)
+#endif
+#ifdef HAVE_CORETEXT
+HB_SHAPER_IMPLEMENT (coretext)
+#endif
+
+#ifdef HAVE_OT
+HB_SHAPER_IMPLEMENT (ot) /* <--- This is our main OpenType shaper. */
+#endif
+
+#ifdef HAVE_HB_OLD
+HB_SHAPER_IMPLEMENT (old)
+#endif
+
+HB_SHAPER_IMPLEMENT (fallback) /* <--- This should be last. */
diff --git a/src/hb-shaper-private.hh b/src/hb-shaper-private.hh
new file mode 100644
index 0000000..88be96c
--- /dev/null
+++ b/src/hb-shaper-private.hh
@@ -0,0 +1,81 @@
+/*
+ * Copyright © 2012 Google, Inc.
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_SHAPER_PRIVATE_HH
+#define HB_SHAPER_PRIVATE_HH
+
+#include "hb-private.hh"
+
+typedef hb_bool_t hb_shape_func_t (hb_font_t *font,
+ hb_buffer_t *buffer,
+ const hb_feature_t *features,
+ unsigned int num_features);
+
+#define HB_SHAPER_IMPLEMENT(name) \
+ extern "C" HB_INTERNAL hb_shape_func_t _hb_##name##_shape;
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+
+/* For embedding in face / font / ... */
+struct hb_shaper_data_t {
+#define HB_SHAPER_IMPLEMENT(shaper) void *shaper;
+#include "hb-shaper-list.hh"
+#undef HB_SHAPER_IMPLEMENT
+};
+
+#define HB_NUM_SHAPERS (sizeof (hb_shaper_data_t) / sizeof (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_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_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
+
+#define HB_SHAPER_DATA_PROTOTYPE(shaper, object) \
+ HB_SHAPER_DATA_TYPE (shaper, object); /* Type forward declaration. */ \
+ static inline HB_SHAPER_DATA_TYPE (shaper, object) * \
+ 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); \
+ extern "C" HB_INTERNAL void \
+ HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA_TYPE (shaper, object) *data)
+
+#define HB_SHAPER_DATA_DESTROY(shaper, object) \
+ if (object->shaper_data.shaper && \
+ object->shaper_data.shaper != HB_SHAPER_DATA_INVALID && \
+ object->shaper_data.shaper != HB_SHAPER_DATA_SUCCEEDED) \
+ HB_SHAPER_DATA_DESTROY_FUNC (shaper, object) (HB_SHAPER_DATA (shaper, object));
+
+
+#endif /* HB_SHAPER_PRIVATE_HH */
diff --git a/src/hb-uniscribe-private.hh b/src/hb-uniscribe-private.hh
deleted file mode 100644
index 239ab0c..0000000
--- a/src/hb-uniscribe-private.hh
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright © 2012 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#ifndef HB_UNISCRIBE_PRIVATE_HH
-#define HB_UNISCRIBE_PRIVATE_HH
-
-#include "hb-private.hh"
-
-#include "hb-uniscribe.h"
-
-
-HB_INTERNAL hb_bool_t
-_hb_uniscribe_shape (hb_font_t *font,
- hb_buffer_t *buffer,
- const hb_feature_t *features,
- unsigned int num_features);
-
-
-#endif /* HB_UNISCRIBE_PRIVATE_HH */
diff --git a/src/hb-uniscribe.cc b/src/hb-uniscribe.cc
index 6b9a261..fe7be70 100644
--- a/src/hb-uniscribe.cc
+++ b/src/hb-uniscribe.cc
@@ -26,7 +26,8 @@
#define _WIN32_WINNT 0x0600
-#include "hb-private.hh"
+#define HB_SHAPER uniscribe
+#include "hb-shaper-impl-private.hh"
#include <windows.h>
#include <usp10.h>
@@ -38,10 +39,6 @@ typedef ULONG WIN_ULONG;
#include "hb-ot-name-table.hh"
#include "hb-ot-tag.h"
-#include "hb-font-private.hh"
-#include "hb-buffer-private.hh"
-
-
#ifndef HB_DEBUG_UNISCRIBE
#define HB_DEBUG_UNISCRIBE (HB_DEBUG+0)
@@ -91,31 +88,20 @@ populate_log_font (LOGFONTW *lf,
}
-static hb_user_data_key_t hb_uniscribe_data_key;
-
+/*
+ * shaper face data
+ */
-static struct hb_uniscribe_face_data_t {
+struct hb_uniscribe_shaper_face_data_t {
HANDLE fh;
-} _hb_uniscribe_face_data_nil = {0};
-
-static void
-_hb_uniscribe_face_data_destroy (hb_uniscribe_face_data_t *data)
-{
- if (data->fh)
- RemoveFontMemResourceEx (data->fh);
- free (data);
-}
+};
-static hb_uniscribe_face_data_t *
-_hb_uniscribe_face_get_data (hb_face_t *face)
+hb_uniscribe_shaper_face_data_t *
+_hb_uniscribe_shaper_face_data_create (hb_face_t *face)
{
- hb_uniscribe_face_data_t *data = (hb_uniscribe_face_data_t *) hb_face_get_user_data (face, &hb_uniscribe_data_key);
- if (likely (data)) return data;
-
- data = (hb_uniscribe_face_data_t *) calloc (1, sizeof (hb_uniscribe_face_data_t));
+ hb_uniscribe_shaper_face_data_t *data = (hb_uniscribe_shaper_face_data_t *) calloc (1, sizeof (hb_uniscribe_shaper_face_data_t));
if (unlikely (!data))
- return &_hb_uniscribe_face_data_nil;
-
+ return NULL;
hb_blob_t *blob = hb_face_reference_blob (face);
unsigned int blob_length;
@@ -126,35 +112,68 @@ _hb_uniscribe_face_get_data (hb_face_t *face)
DWORD num_fonts_installed;
data->fh = AddFontMemResourceEx ((void *) blob_data, blob_length, 0, &num_fonts_installed);
hb_blob_destroy (blob);
- if (unlikely (!data->fh))
+ if (unlikely (!data->fh)) {
DEBUG_MSG (UNISCRIBE, face, "Face AddFontMemResourceEx() failed");
-
-
- if (unlikely (!hb_face_set_user_data (face, &hb_uniscribe_data_key, data,
- (hb_destroy_func_t) _hb_uniscribe_face_data_destroy,
- false)))
- {
- _hb_uniscribe_face_data_destroy (data);
- data = (hb_uniscribe_face_data_t *) hb_face_get_user_data (face, &hb_uniscribe_data_key);
- if (data)
- return data;
- else
- return &_hb_uniscribe_face_data_nil;
+ free (data);
+ return NULL;
}
return data;
}
+void
+_hb_uniscribe_shaper_face_data_destroy (hb_uniscribe_shaper_face_data_t *data)
+{
+ if (data->fh)
+ RemoveFontMemResourceEx (data->fh);
+ free (data);
+}
-static struct hb_uniscribe_font_data_t {
+
+/*
+ * shaper font data
+ */
+
+struct hb_uniscribe_shaper_font_data_t {
HDC hdc;
LOGFONTW log_font;
HFONT hfont;
SCRIPT_CACHE script_cache;
-} _hb_uniscribe_font_data_nil = {NULL, NULL, NULL};
+};
-static void
-_hb_uniscribe_font_data_destroy (hb_uniscribe_font_data_t *data)
+hb_uniscribe_shaper_font_data_t *
+_hb_uniscribe_shaper_font_data_create (hb_font_t *font)
+{
+ hb_uniscribe_shaper_font_data_t * data = (hb_uniscribe_shaper_font_data_t *) calloc (1, sizeof (hb_uniscribe_shaper_font_data_t));
+ if (unlikely (!data))
+ return NULL;
+
+ data->hdc = GetDC (NULL);
+
+ if (unlikely (!populate_log_font (&data->log_font, font))) {
+ DEBUG_MSG (UNISCRIBE, font, "Font populate_log_font() failed");
+ _hb_uniscribe_shaper_font_data_destroy (data);
+ return NULL;
+ }
+
+ data->hfont = CreateFontIndirectW (&data->log_font);
+ if (unlikely (!data->hfont)) {
+ DEBUG_MSG (UNISCRIBE, font, "Font CreateFontIndirectW() failed");
+ _hb_uniscribe_shaper_font_data_destroy (data);
+ return NULL;
+ }
+
+ if (!SelectObject (data->hdc, data->hfont)) {
+ DEBUG_MSG (UNISCRIBE, font, "Font SelectObject() failed");
+ _hb_uniscribe_shaper_font_data_destroy (data);
+ return NULL;
+ }
+
+ return data;
+}
+
+void
+_hb_uniscribe_shaper_font_data_destroy (hb_uniscribe_shaper_font_data_t *data)
{
if (data->hdc)
ReleaseDC (NULL, data->hdc);
@@ -165,38 +184,67 @@ _hb_uniscribe_font_data_destroy (hb_uniscribe_font_data_t *data)
free (data);
}
-static hb_uniscribe_font_data_t *
-_hb_uniscribe_font_get_data (hb_font_t *font)
+
+/*
+ * shaper shape_plan 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_font_data_t *data = (hb_uniscribe_font_data_t *) hb_font_get_user_data (font, &hb_uniscribe_data_key);
- if (likely (data)) return data;
+ return (hb_uniscribe_shaper_shape_plan_data_t *) HB_SHAPER_DATA_SUCCEEDED;
+}
- data = (hb_uniscribe_font_data_t *) calloc (1, sizeof (hb_uniscribe_font_data_t));
- if (unlikely (!data))
- return &_hb_uniscribe_font_data_nil;
+void
+_hb_uniscribe_shaper_shape_plan_data_destroy (hb_uniscribe_shaper_shape_plan_data_t *data)
+{
+}
- data->hdc = GetDC (NULL);
- if (unlikely (!populate_log_font (&data->log_font, font)))
- DEBUG_MSG (UNISCRIBE, font, "Font populate_log_font() failed");
- else {
- data->hfont = CreateFontIndirectW (&data->log_font);
- if (unlikely (!data->hfont))
- DEBUG_MSG (UNISCRIBE, font, "Font CreateFontIndirectW() failed");
- if (!SelectObject (data->hdc, data->hfont))
- DEBUG_MSG (UNISCRIBE, font, "Font SelectObject() failed");
+/*
+ * shaper
+ */
+static hb_user_data_key_t hb_uniscribe_data_key;
+
+static hb_uniscribe_shaper_face_data_t *
+_hb_uniscribe_face_get_data (hb_face_t *face)
+{
+ hb_uniscribe_shaper_face_data_t *data = (hb_uniscribe_shaper_face_data_t *) hb_face_get_user_data (face, &hb_uniscribe_data_key);
+ if (likely (data)) return data;
+
+ data = _hb_uniscribe_shaper_face_data_create (face);
+ if (!data) return NULL;
+
+ if (unlikely (!hb_face_set_user_data (face, &hb_uniscribe_data_key, data,
+ (hb_destroy_func_t) _hb_uniscribe_shaper_face_data_destroy,
+ false)))
+ {
+ _hb_uniscribe_shaper_face_data_destroy (data);
+ data = (hb_uniscribe_shaper_face_data_t *) hb_face_get_user_data (face, &hb_uniscribe_data_key);
}
+ return data;
+}
+
+
+static hb_uniscribe_shaper_font_data_t *
+_hb_uniscribe_font_get_data (hb_font_t *font)
+{
+ hb_uniscribe_shaper_font_data_t *data = (hb_uniscribe_shaper_font_data_t *) hb_font_get_user_data (font, &hb_uniscribe_data_key);
+ if (likely (data)) return data;
+
+ data = _hb_uniscribe_shaper_font_data_create (font);
+ if (unlikely (!data))
+ return NULL;
+
if (unlikely (!hb_font_set_user_data (font, &hb_uniscribe_data_key, data,
- (hb_destroy_func_t) _hb_uniscribe_font_data_destroy,
+ (hb_destroy_func_t) _hb_uniscribe_shaper_font_data_destroy,
false)))
{
- _hb_uniscribe_font_data_destroy (data);
- data = (hb_uniscribe_font_data_t *) hb_font_get_user_data (font, &hb_uniscribe_data_key);
- if (data)
- return data;
- else
- return &_hb_uniscribe_font_data_nil;
+ _hb_uniscribe_shaper_font_data_destroy (data);
+ data = (hb_uniscribe_shaper_font_data_t *) hb_font_get_user_data (font, &hb_uniscribe_data_key);
}
return data;
@@ -205,7 +253,7 @@ _hb_uniscribe_font_get_data (hb_font_t *font)
LOGFONTW *
hb_uniscribe_font_get_logfontw (hb_font_t *font)
{
- hb_uniscribe_font_data_t *font_data = _hb_uniscribe_font_get_data (font);
+ hb_uniscribe_shaper_font_data_t *font_data = _hb_uniscribe_font_get_data (font);
if (unlikely (!font_data))
return NULL;
return &font_data->log_font;
@@ -214,7 +262,7 @@ hb_uniscribe_font_get_logfontw (hb_font_t *font)
HFONT
hb_uniscribe_font_get_hfont (hb_font_t *font)
{
- hb_uniscribe_font_data_t *font_data = _hb_uniscribe_font_get_data (font);
+ hb_uniscribe_shaper_font_data_t *font_data = _hb_uniscribe_font_get_data (font);
if (unlikely (!font_data))
return 0;
return font_data->hfont;
@@ -235,11 +283,11 @@ _hb_uniscribe_shape (hb_font_t *font,
return false; \
} HB_STMT_END;
- hb_uniscribe_face_data_t *face_data = _hb_uniscribe_face_get_data (font->face);
+ hb_uniscribe_shaper_face_data_t *face_data = _hb_uniscribe_face_get_data (font->face);
if (unlikely (!face_data->fh))
FAIL ("Couldn't get face data");
- hb_uniscribe_font_data_t *font_data = _hb_uniscribe_font_get_data (font);
+ hb_uniscribe_shaper_font_data_t *font_data = _hb_uniscribe_font_get_data (font);
if (unlikely (!font_data->hfont))
FAIL ("Couldn't get font font");
More information about the HarfBuzz
mailing list