Add hb_object_header_t which is the common part of all objects

Makes way for adding arbitrary user_data support.
This commit is contained in:
Behdad Esfahbod 2011-04-21 18:24:02 -04:00
parent a9f24c8029
commit fca368c468
13 changed files with 82 additions and 66 deletions

View File

@ -30,12 +30,13 @@
#include "hb-private.hh"
#include "hb-blob.h"
#include "hb-object-private.hh"
HB_BEGIN_DECLS
struct _hb_blob_t {
hb_reference_count_t ref_count;
hb_object_header_t header;
unsigned int length;

View File

@ -46,7 +46,7 @@ HB_BEGIN_DECLS
#endif
hb_blob_t _hb_blob_nil = {
HB_REFERENCE_COUNT_INVALID, /* ref_count */
HB_OBJECT_HEADER_STATIC,
0, /* length */

View File

@ -30,6 +30,7 @@
#include "hb-private.hh"
#include "hb-buffer.h"
#include "hb-object-private.hh"
#include "hb-unicode-private.hh"
HB_BEGIN_DECLS
@ -85,7 +86,7 @@ _hb_buffer_set_masks (hb_buffer_t *buffer,
struct _hb_buffer_t {
hb_reference_count_t ref_count;
hb_object_header_t header;
/* Information about how the text in the buffer should be treated */
@ -94,9 +95,9 @@ struct _hb_buffer_t {
/* Buffer contents */
hb_bool_t have_output; /* Whether we have an output buffer going on */
hb_bool_t have_positions; /* Whether we have positions */
hb_bool_t in_error; /* Allocation failed */
bool have_output; /* Whether we have an output buffer going on */
bool have_positions; /* Whether we have positions */
bool in_error; /* Allocation failed */
unsigned int i; /* Cursor into ->info and ->pos arrays */
unsigned int len; /* Length of ->info and ->pos arrays */

View File

@ -35,7 +35,7 @@ HB_BEGIN_DECLS
static hb_buffer_t _hb_buffer_nil = {
HB_REFERENCE_COUNT_INVALID, /* ref_count */
HB_OBJECT_HEADER_STATIC,
&_hb_unicode_funcs_nil, /* unicode */
{

View File

@ -32,6 +32,7 @@
#include "hb-private.hh"
#include "hb-font.h"
#include "hb-object-private.hh"
HB_BEGIN_DECLS
@ -41,7 +42,7 @@ HB_BEGIN_DECLS
*/
struct _hb_font_funcs_t {
hb_reference_count_t ref_count;
hb_object_header_t header;
hb_bool_t immutable;
@ -62,7 +63,7 @@ extern HB_INTERNAL hb_font_funcs_t _hb_font_funcs_nil;
*/
struct _hb_face_t {
hb_reference_count_t ref_count;
hb_object_header_t header;
hb_get_table_func_t get_table;
void *user_data;
@ -80,7 +81,7 @@ struct _hb_face_t {
*/
struct _hb_font_t {
hb_reference_count_t ref_count;
hb_object_header_t header;
unsigned int x_scale;
unsigned int y_scale;

View File

@ -85,7 +85,8 @@ hb_font_get_kerning_nil (hb_font_t *font HB_UNUSED,
{ return 0; }
hb_font_funcs_t _hb_font_funcs_nil = {
HB_REFERENCE_COUNT_INVALID, /* ref_count */
HB_OBJECT_HEADER_STATIC,
TRUE, /* immutable */
{
hb_font_get_glyph_nil,
@ -287,7 +288,7 @@ hb_font_get_kerning (hb_font_t *font, hb_face_t *face,
*/
static hb_face_t _hb_face_nil = {
HB_REFERENCE_COUNT_INVALID, /* ref_count */
HB_OBJECT_HEADER_STATIC,
NULL, /* get_table */
NULL, /* user_data */
@ -435,7 +436,7 @@ hb_face_get_upem (hb_face_t *face)
*/
static hb_font_t _hb_font_nil = {
HB_REFERENCE_COUNT_INVALID, /* ref_count */
HB_OBJECT_HEADER_STATIC,
0, /* x_scale */
0, /* y_scale */

View File

@ -145,7 +145,8 @@ hb_ft_get_kerning (hb_font_t *font HB_UNUSED,
}
static hb_font_funcs_t ft_ffuncs = {
HB_REFERENCE_COUNT_INVALID, /* ref_count */
HB_OBJECT_HEADER_STATIC,
TRUE, /* immutable */
{
hb_ft_get_glyph,

View File

@ -221,7 +221,8 @@ hb_glib_get_script (hb_unicode_funcs_t *ufuncs,
}
static hb_unicode_funcs_t glib_ufuncs = {
HB_REFERENCE_COUNT_INVALID, /* ref_count */
HB_OBJECT_HEADER_STATIC,
NULL, /* parent */
TRUE, /* immutable */
{

View File

@ -161,7 +161,8 @@ hb_icu_get_script (hb_unicode_funcs_t *ufuncs,
}
static hb_unicode_funcs_t icu_ufuncs = {
HB_REFERENCE_COUNT_INVALID, /* ref_count */
HB_OBJECT_HEADER_STATIC,
NULL, /* parent */
TRUE, /* immutable */
{

View File

@ -37,75 +37,84 @@
HB_BEGIN_DECLS
/* Debug */
#ifndef HB_DEBUG_OBJECT
#define HB_DEBUG_OBJECT (HB_DEBUG+0)
#endif
static inline void
_hb_trace_object (const void *obj,
hb_reference_count_t *ref_count,
const char *function)
{
typedef struct _hb_object_header_t hb_object_header_t;
struct _hb_object_header_t {
hb_reference_count_t ref_count;
#define HB_OBJECT_HEADER_STATIC {HB_REFERENCE_COUNT_INVALID}
static inline void *create (unsigned int size) {
hb_object_header_t *obj = (hb_object_header_t *) calloc (1, size);
if (likely (obj))
obj->init ();
return obj;
}
inline void init (void) {
ref_count.init (1);
}
inline bool is_inert (void) const { return unlikely (ref_count.is_invalid ()); }
inline void reference (void) {
if (unlikely (!this || this->is_inert ()))
return;
ref_count.inc ();
}
inline bool destroy (void) {
if (unlikely (!this || this->is_inert ()))
return false;
return ref_count.dec () == 1;
}
inline void trace (const char *function) const {
(void) (HB_DEBUG_OBJECT &&
fprintf (stderr, "OBJECT(%p) refcount=%d %s\n",
obj,
ref_count->get (),
this,
this ? ref_count.get () : 0,
function));
}
#define TRACE_OBJECT(obj) _hb_trace_object (obj, &obj->ref_count, __FUNCTION__)
}
};
/* Object allocation and lifecycle manamgement macros */
#define TRACE_OBJECT(obj) \
obj->header.trace (__FUNCTION__)
#define HB_OBJECT_IS_INERT(obj) \
(unlikely ((obj)->ref_count.is_invalid ()))
#define HB_OBJECT_DO_INIT_EXPR(obj) \
obj->ref_count.init (1)
#define HB_OBJECT_DO_INIT(obj) \
HB_STMT_START { \
HB_OBJECT_DO_INIT_EXPR (obj); \
} HB_STMT_END
(unlikely ((obj)->header.is_inert ()))
#define HB_OBJECT_DO_CREATE(Type, obj) \
likely (( \
(void) ( \
((obj) = (Type *) calloc (1, sizeof (Type))) && \
( \
HB_OBJECT_DO_INIT_EXPR (obj), \
((obj) = (Type *) hb_object_header_t::create (sizeof (Type))), \
TRACE_OBJECT (obj), \
TRUE \
) \
), \
(obj) \
))
#define HB_OBJECT_DO_REFERENCE(obj) \
HB_STMT_START { \
int old_count; \
if (unlikely (!(obj) || HB_OBJECT_IS_INERT (obj))) \
return obj; \
TRACE_OBJECT (obj); \
old_count = obj->ref_count.inc (); \
assert (old_count > 0); \
obj->header.reference (); \
return obj; \
} HB_STMT_END
#define HB_OBJECT_DO_DESTROY(obj) \
HB_STMT_START { \
int old_count; \
if (unlikely (!(obj) || HB_OBJECT_IS_INERT (obj))) \
return; \
TRACE_OBJECT (obj); \
old_count = obj->ref_count.dec (); \
assert (old_count > 0); \
if (old_count != 1) \
if (!obj->header.destroy ()) \
return; \
} HB_STMT_END

View File

@ -305,7 +305,7 @@ typedef struct {
#define HB_DEBUG 0
#endif
static inline hb_bool_t /* always returns TRUE */
static inline bool /* always returns TRUE */
_hb_trace (const char *what,
const char *function,
const void *obj,
@ -317,9 +317,6 @@ _hb_trace (const char *what,
}
#include "hb-object-private.hh"
HB_END_DECLS
#endif /* HB_PRIVATE_HH */

View File

@ -34,6 +34,7 @@
#include "hb-private.hh"
#include "hb-unicode.h"
#include "hb-object-private.hh"
HB_BEGIN_DECLS
@ -43,10 +44,11 @@ HB_BEGIN_DECLS
*/
struct _hb_unicode_funcs_t {
hb_reference_count_t ref_count;
hb_object_header_t header;
hb_unicode_funcs_t *parent;
hb_bool_t immutable;
bool immutable;
#define IMPLEMENT(return_type, name) \
inline return_type \

View File

@ -81,7 +81,8 @@ hb_unicode_get_script_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
hb_unicode_funcs_t _hb_unicode_funcs_nil = {
HB_REFERENCE_COUNT_INVALID, /* ref_count */
HB_OBJECT_HEADER_STATIC,
NULL, /* parent */
TRUE, /* immutable */
{