unicode: Cleanup implementation
diff --git a/src/Makefile.am b/src/Makefile.am
index 2fbf278..70c51d1 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -24,8 +24,8 @@
hb-ot-head-private.hh \
hb-private.h \
hb-shape.cc \
- hb-unicode.c \
- hb-unicode-private.h \
+ hb-unicode.cc \
+ hb-unicode-private.hh \
$(NULL)
HBHEADERS = \
hb.h \
@@ -65,7 +65,7 @@
HBCFLAGS += $(GLIB_CFLAGS)
HBLIBS += $(GLIB_LIBS)
HBSOURCES += \
- hb-glib.c \
+ hb-glib.cc \
$(NULL)
HBHEADERS += \
hb-glib.h \
@@ -76,7 +76,7 @@
HBCFLAGS += $(ICU_CFLAGS)
HBLIBS += $(ICU_LIBS)
HBSOURCES += \
- hb-icu.c \
+ hb-icu.cc \
$(NULL)
HBHEADERS += \
hb-icu.h \
diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh
index 2b063b7..dfcc45d 100644
--- a/src/hb-buffer-private.hh
+++ b/src/hb-buffer-private.hh
@@ -30,7 +30,7 @@
#include "hb-private.h"
#include "hb-buffer.h"
-#include "hb-unicode-private.h"
+#include "hb-unicode-private.hh"
HB_BEGIN_DECLS
diff --git a/src/hb-glib.c b/src/hb-glib.cc
similarity index 95%
rename from src/hb-glib.c
rename to src/hb-glib.cc
index 1905637..5bebf5e 100644
--- a/src/hb-glib.c
+++ b/src/hb-glib.cc
@@ -28,20 +28,28 @@
#include "hb-glib.h"
-#include "hb-unicode-private.h"
+#include "hb-unicode-private.hh"
#include <glib.h>
HB_BEGIN_DECLS
-static hb_codepoint_t
-hb_glib_get_mirroring (hb_unicode_funcs_t *ufuncs,
- hb_codepoint_t unicode,
- void *user_data)
+static unsigned int
+hb_glib_get_combining_class (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode,
+ void *user_data)
+
{
- g_unichar_get_mirror_char (unicode, &unicode);
- return unicode;
+ return g_unichar_combining_class (unicode);
+}
+
+static unsigned int
+hb_glib_get_eastasian_width (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode,
+ void *user_data)
+{
+ return g_unichar_iswide (unicode) ? 2 : 1;
}
static hb_unicode_general_category_t
@@ -50,7 +58,17 @@
void *user_data)
{
- return g_unichar_type (unicode);
+ /* hb_unicode_general_category_t and GUnicodeType are identical */
+ return (hb_unicode_general_category_t) g_unichar_type (unicode);
+}
+
+static hb_codepoint_t
+hb_glib_get_mirroring (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode,
+ void *user_data)
+{
+ g_unichar_get_mirror_char (unicode, &unicode);
+ return unicode;
}
static hb_script_t
@@ -167,7 +185,7 @@
MATCH_SCRIPT (LISU); /* Lisu */
MATCH_SCRIPT (MEETEI_MAYEK); /* Mtei */
MATCH_SCRIPT (OLD_SOUTH_ARABIAN); /* Sarb */
-#if GLIB_CHECK_VERSION(2,28,0)
+#if GLIB_CHECK_VERSION(2,27,92)
MATCH_SCRIPT (OLD_TURKIC); /* Orkh */
#else
MATCH_SCRIPT2(OLD_TURKISH, OLD_TURKIC);/* Orkh */
@@ -190,33 +208,16 @@
return HB_SCRIPT_UNKNOWN;
}
-static unsigned int
-hb_glib_get_combining_class (hb_unicode_funcs_t *ufuncs,
- hb_codepoint_t unicode,
- void *user_data)
-
-{
- return g_unichar_combining_class (unicode);
-}
-
-static unsigned int
-hb_glib_get_eastasian_width (hb_unicode_funcs_t *ufuncs,
- hb_codepoint_t unicode,
- void *user_data)
-{
- return g_unichar_iswide (unicode) ? 2 : 1;
-}
-
static hb_unicode_funcs_t glib_ufuncs = {
HB_REFERENCE_COUNT_INVALID, /* ref_count */
- NULL,
+ NULL, /* parent */
TRUE, /* immutable */
{
- hb_glib_get_general_category, NULL, NULL,
- hb_glib_get_combining_class, NULL, NULL,
- hb_glib_get_mirroring, NULL, NULL,
- hb_glib_get_script, NULL, NULL,
- hb_glib_get_eastasian_width, NULL, NULL
+ hb_glib_get_combining_class,
+ hb_glib_get_eastasian_width,
+ hb_glib_get_general_category,
+ hb_glib_get_mirroring,
+ hb_glib_get_script
}
};
diff --git a/src/hb-icu.c b/src/hb-icu.cc
similarity index 97%
rename from src/hb-icu.c
rename to src/hb-icu.cc
index 6bc3339..4978bf5 100644
--- a/src/hb-icu.c
+++ b/src/hb-icu.cc
@@ -29,7 +29,7 @@
#include "hb-icu.h"
-#include "hb-unicode-private.h"
+#include "hb-unicode-private.hh"
#include <unicode/uversion.h>
#include <unicode/uchar.h>
@@ -38,14 +38,6 @@
HB_BEGIN_DECLS
-static hb_codepoint_t
-hb_icu_get_mirroring (hb_unicode_funcs_t *ufuncs,
- hb_codepoint_t unicode,
- void *user_data)
-{
- return u_charMirror(unicode);
-}
-
static unsigned int
hb_icu_get_combining_class (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode,
@@ -125,6 +117,14 @@
return HB_UNICODE_GENERAL_CATEGORY_UNASSIGNED;
}
+static hb_codepoint_t
+hb_icu_get_mirroring (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode,
+ void *user_data)
+{
+ return u_charMirror(unicode);
+}
+
static hb_script_t
hb_icu_get_script (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode,
@@ -264,14 +264,14 @@
static hb_unicode_funcs_t icu_ufuncs = {
HB_REFERENCE_COUNT_INVALID, /* ref_count */
- NULL,
+ NULL, /* parent */
TRUE, /* immutable */
{
- hb_icu_get_general_category, NULL, NULL,
- hb_icu_get_combining_class, NULL, NULL,
- hb_icu_get_mirroring, NULL, NULL,
- hb_icu_get_script, NULL, NULL,
- hb_icu_get_eastasian_width, NULL, NULL
+ hb_icu_get_combining_class,
+ hb_icu_get_eastasian_width,
+ hb_icu_get_general_category,
+ hb_icu_get_mirroring,
+ hb_icu_get_script
}
};
diff --git a/src/hb-ot-shape.cc b/src/hb-ot-shape.cc
index 2ffb076..589dee3 100644
--- a/src/hb-ot-shape.cc
+++ b/src/hb-ot-shape.cc
@@ -143,16 +143,13 @@
static void
hb_set_unicode_props (hb_ot_shape_context_t *c)
{
- hb_unicode_get_general_category_func_t get_general_category = c->buffer->unicode->v.get_general_category;
- hb_unicode_get_combining_class_func_t get_combining_class = c->buffer->unicode->v.get_combining_class;
+ hb_unicode_funcs_t *unicode = c->buffer->unicode;
hb_glyph_info_t *info = c->buffer->info;
unsigned int count = c->buffer->len;
for (unsigned int i = 1; i < count; i++) {
- info[i].general_category() = get_general_category (c->buffer->unicode, info[i].codepoint,
- c->buffer->unicode->v.get_general_category_data);
- info[i].combining_class() = get_combining_class (c->buffer->unicode, info[i].codepoint,
- c->buffer->unicode->v.get_combining_class_data);
+ info[i].general_category() = unicode->get_general_category (info[i].codepoint);
+ info[i].combining_class() = unicode->get_combining_class (info[i].codepoint);
}
}
@@ -193,7 +190,7 @@
static void
hb_mirror_chars (hb_ot_shape_context_t *c)
{
- hb_unicode_get_mirroring_func_t get_mirroring = c->buffer->unicode->v.get_mirroring;
+ hb_unicode_funcs_t *unicode = c->buffer->unicode;
if (HB_DIRECTION_IS_FORWARD (c->target_direction))
return;
@@ -202,8 +199,7 @@
unsigned int count = c->buffer->len;
for (unsigned int i = 0; i < count; i++) {
- hb_codepoint_t codepoint = get_mirroring (c->buffer->unicode, c->buffer->info[i].codepoint,
- c->buffer->unicode->v.get_mirroring_data);
+ hb_codepoint_t codepoint = unicode->get_mirroring (c->buffer->info[i].codepoint);
if (likely (codepoint == c->buffer->info[i].codepoint))
c->buffer->info[i].mask |= rtlm_mask; /* XXX this should be moved to before setting user-feature masks */
else
diff --git a/src/hb-shape.cc b/src/hb-shape.cc
index 9d9bf25..2b536fa 100644
--- a/src/hb-shape.cc
+++ b/src/hb-shape.cc
@@ -74,10 +74,10 @@
/* If script is set to INVALID, guess from buffer contents */
if (buffer->props.script == HB_SCRIPT_INVALID) {
- hb_unicode_get_script_func_t get_script = buffer->unicode->v.get_script;
+ hb_unicode_funcs_t *unicode = buffer->unicode;
unsigned int count = buffer->len;
for (unsigned int i = 0; i < count; i++) {
- hb_script_t script = get_script (buffer->unicode, buffer->info[i].codepoint, buffer->unicode->v.get_script_data);
+ hb_script_t script = unicode->get_script (buffer->info[i].codepoint);
if (likely (script != HB_SCRIPT_COMMON &&
script != HB_SCRIPT_INHERITED &&
script != HB_SCRIPT_UNKNOWN)) {
diff --git a/src/hb-unicode-private.h b/src/hb-unicode-private.h
deleted file mode 100644
index 456d8de..0000000
--- a/src/hb-unicode-private.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2009 Red Hat, Inc.
- * Copyright © 2011 Codethink Limited
- *
- * 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.
- *
- * Red Hat Author(s): Behdad Esfahbod
- * Codethink Author(s): Ryan Lortie
- */
-
-#ifndef HB_UNICODE_PRIVATE_H
-#define HB_UNICODE_PRIVATE_H
-
-#include "hb-private.h"
-
-#include "hb-unicode.h"
-
-HB_BEGIN_DECLS
-
-
-/*
- * hb_unicode_funcs_t
- */
-
-struct _hb_unicode_funcs_t {
- hb_reference_count_t ref_count;
- hb_unicode_funcs_t *parent;
-
- hb_bool_t immutable;
-
- struct {
- hb_unicode_get_general_category_func_t get_general_category;
- void *get_general_category_data;
- hb_destroy_func_t get_general_category_destroy;
-
- hb_unicode_get_combining_class_func_t get_combining_class;
- void *get_combining_class_data;
- hb_destroy_func_t get_combining_class_destroy;
-
- hb_unicode_get_mirroring_func_t get_mirroring;
- void *get_mirroring_data;
- hb_destroy_func_t get_mirroring_destroy;
-
- hb_unicode_get_script_func_t get_script;
- void *get_script_data;
- hb_destroy_func_t get_script_destroy;
-
- hb_unicode_get_eastasian_width_func_t get_eastasian_width;
- void *get_eastasian_width_data;
- hb_destroy_func_t get_eastasian_width_destroy;
- } v;
-};
-
-extern HB_INTERNAL hb_unicode_funcs_t _hb_unicode_funcs_nil;
-
-
-HB_END_DECLS
-
-#endif /* HB_UNICODE_PRIVATE_H */
diff --git a/src/hb-unicode-private.hh b/src/hb-unicode-private.hh
new file mode 100644
index 0000000..67a60f5d
--- /dev/null
+++ b/src/hb-unicode-private.hh
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright © 2011 Codethink Limited
+ * Copyright (C) 2010 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Codethink Author(s): Ryan Lortie
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef HB_UNICODE_PRIVATE_HH
+#define HB_UNICODE_PRIVATE_HH
+
+#include "hb-private.h"
+
+#include "hb-unicode.h"
+
+HB_BEGIN_DECLS
+
+
+/*
+ * hb_unicode_funcs_t
+ */
+
+struct _hb_unicode_funcs_t {
+ hb_reference_count_t ref_count;
+ hb_unicode_funcs_t *parent;
+
+ hb_bool_t immutable;
+
+#define IMPLEMENT(return_type, name) \
+ inline return_type \
+ get_##name (hb_codepoint_t unicode) \
+ { return this->get.name (this, unicode, this->user_data.name); }
+
+ IMPLEMENT (unsigned int, combining_class)
+ IMPLEMENT (unsigned int, eastasian_width)
+ IMPLEMENT (hb_unicode_general_category_t, general_category)
+ IMPLEMENT (hb_codepoint_t, mirroring)
+ IMPLEMENT (hb_script_t, script)
+
+#undef IMPLEMENT
+
+ /* Don't access these directly. Call get_*() instead. */
+
+ struct {
+ hb_unicode_get_combining_class_func_t combining_class;
+ hb_unicode_get_eastasian_width_func_t eastasian_width;
+ hb_unicode_get_general_category_func_t general_category;
+ hb_unicode_get_mirroring_func_t mirroring;
+ hb_unicode_get_script_func_t script;
+ } get;
+
+ struct {
+ void *combining_class;
+ void *eastasian_width;
+ void *general_category;
+ void *mirroring;
+ void *script;
+ } user_data;
+
+ struct {
+ hb_destroy_func_t combining_class;
+ hb_destroy_func_t eastasian_width;
+ hb_destroy_func_t general_category;
+ hb_destroy_func_t mirroring;
+ hb_destroy_func_t script;
+ } destroy;
+};
+
+extern HB_INTERNAL hb_unicode_funcs_t _hb_unicode_funcs_nil;
+
+
+HB_END_DECLS
+
+#endif /* HB_UNICODE_PRIVATE_HH */
diff --git a/src/hb-unicode.c b/src/hb-unicode.c
deleted file mode 100644
index e047ef7..0000000
--- a/src/hb-unicode.c
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (C) 2009 Red Hat, Inc.
- * Copyright © 2011 Codethink Limited
- *
- * 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.
- *
- * Red Hat Author(s): Behdad Esfahbod
- * Codethink Author(s): Ryan Lortie
- */
-
-#include "hb-private.h"
-
-#include "hb-unicode-private.h"
-
-HB_BEGIN_DECLS
-
-
-/*
- * hb_unicode_funcs_t
- */
-
-static hb_codepoint_t
-hb_unicode_get_mirroring_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t unicode HB_UNUSED,
- void *user_data HB_UNUSED)
-{
- return unicode;
-}
-
-static hb_unicode_general_category_t
-hb_unicode_get_general_category_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t unicode HB_UNUSED,
- void *user_data HB_UNUSED)
-{
- return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER;
-}
-
-static hb_script_t
-hb_unicode_get_script_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t unicode HB_UNUSED,
- void *user_data HB_UNUSED)
-{
- return HB_SCRIPT_UNKNOWN;
-}
-
-static unsigned int
-hb_unicode_get_combining_class_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t unicode HB_UNUSED,
- void *user_data HB_UNUSED)
-{
- return 0;
-}
-
-static unsigned int
-hb_unicode_get_eastasian_width_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
- hb_codepoint_t unicode HB_UNUSED,
- void *user_data HB_UNUSED)
-{
- return 1;
-}
-
-hb_unicode_funcs_t _hb_unicode_funcs_nil = {
- HB_REFERENCE_COUNT_INVALID, /* ref_count */
- NULL, /* parent */
- TRUE, /* immutable */
- {
- hb_unicode_get_general_category_nil, NULL, NULL,
- hb_unicode_get_combining_class_nil, NULL, NULL,
- hb_unicode_get_mirroring_nil, NULL, NULL,
- hb_unicode_get_script_nil, NULL, NULL,
- hb_unicode_get_eastasian_width_nil, NULL, NULL
- }
-};
-
-hb_unicode_funcs_t *
-hb_unicode_funcs_create (hb_unicode_funcs_t *parent)
-{
- hb_unicode_funcs_t *ufuncs;
-
- if (!HB_OBJECT_DO_CREATE (hb_unicode_funcs_t, ufuncs))
- return &_hb_unicode_funcs_nil;
-
- if (parent != NULL) {
- ufuncs->parent = hb_unicode_funcs_reference (parent);
- hb_unicode_funcs_make_immutable (parent);
- ufuncs->v = parent->v;
-
- /* Clear out the destroy notifies from our parent.
- *
- * We don't want to destroy the user_data twice and since we hold a
- * reference on our parent then we know that the user_data will
- * survive for at least as long as we do anyway.
- */
- ufuncs->v.get_general_category_destroy = NULL;
- ufuncs->v.get_combining_class_destroy = NULL;
- ufuncs->v.get_mirroring_destroy = NULL;
- ufuncs->v.get_script_destroy = NULL;
- ufuncs->v.get_eastasian_width_destroy = NULL;
- } else {
- ufuncs->v = _hb_unicode_funcs_nil.v;
- }
-
- return ufuncs;
-}
-
-hb_unicode_funcs_t *
-hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs)
-{
- HB_OBJECT_DO_REFERENCE (ufuncs);
-}
-
-unsigned int
-hb_unicode_funcs_get_reference_count (hb_unicode_funcs_t *ufuncs)
-{
- HB_OBJECT_DO_GET_REFERENCE_COUNT (ufuncs);
-}
-
-void
-hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
-{
- HB_OBJECT_DO_DESTROY (ufuncs);
-
- if (ufuncs->parent != NULL)
- hb_unicode_funcs_destroy (ufuncs->parent);
-
- if (ufuncs->v.get_general_category_destroy != NULL)
- ufuncs->v.get_general_category_destroy (ufuncs->v.get_general_category_data);
-
- if (ufuncs->v.get_combining_class_destroy != NULL)
- ufuncs->v.get_combining_class_destroy (ufuncs->v.get_combining_class_data);
-
- if (ufuncs->v.get_mirroring_destroy != NULL)
- ufuncs->v.get_mirroring_destroy (ufuncs->v.get_mirroring_data);
-
- if (ufuncs->v.get_script_destroy != NULL)
- ufuncs->v.get_script_destroy (ufuncs->v.get_script_data);
-
- if (ufuncs->v.get_eastasian_width_destroy != NULL)
- ufuncs->v.get_eastasian_width_destroy (ufuncs->v.get_eastasian_width_data);
-
- free (ufuncs);
-}
-
-hb_unicode_funcs_t *
-hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs)
-{
- return ufuncs->parent;
-}
-
-void
-hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
-{
- if (HB_OBJECT_IS_INERT (ufuncs))
- return;
-
- ufuncs->immutable = TRUE;
-}
-
-hb_bool_t
-hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs)
-{
- return ufuncs->immutable;
-}
-
-
-#define SETTER(name) \
-void \
-hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t *ufuncs, \
- hb_unicode_get_##name##_func_t func, \
- void *user_data, \
- hb_destroy_func_t destroy) \
-{ \
- if (ufuncs->immutable) \
- return; \
- \
- if (func != NULL) { \
- ufuncs->v.get_##name = func; \
- ufuncs->v.get_##name##_data = user_data; \
- ufuncs->v.get_##name##_destroy = destroy; \
- } else if (ufuncs->parent != NULL) { \
- ufuncs->v.get_##name = ufuncs->parent->v.get_##name; \
- ufuncs->v.get_##name##_data = ufuncs->parent->v.get_##name##_data;; \
- ufuncs->v.get_##name##_destroy = NULL; \
- } else { \
- ufuncs->v.get_##name = hb_unicode_get_##name##_nil; \
- ufuncs->v.get_##name##_data = NULL; \
- ufuncs->v.get_##name##_destroy = NULL; \
- } \
-}
-
-SETTER(mirroring)
-SETTER(general_category)
-SETTER(script)
-SETTER(combining_class)
-SETTER(eastasian_width)
-
-hb_codepoint_t
-hb_unicode_get_mirroring (hb_unicode_funcs_t *ufuncs,
- hb_codepoint_t unicode)
-{
- return ufuncs->v.get_mirroring (ufuncs, unicode,
- ufuncs->v.get_mirroring_data);
-}
-
-hb_unicode_general_category_t
-hb_unicode_get_general_category (hb_unicode_funcs_t *ufuncs,
- hb_codepoint_t unicode)
-{
- return ufuncs->v.get_general_category (ufuncs, unicode,
- ufuncs->v.get_general_category_data);
-}
-
-hb_script_t
-hb_unicode_get_script (hb_unicode_funcs_t *ufuncs,
- hb_codepoint_t unicode)
-{
- return ufuncs->v.get_script (ufuncs, unicode,
- ufuncs->v.get_script_data);
-}
-
-unsigned int
-hb_unicode_get_combining_class (hb_unicode_funcs_t *ufuncs,
- hb_codepoint_t unicode)
-{
- return ufuncs->v.get_combining_class (ufuncs, unicode,
- ufuncs->v.get_combining_class_data);
-}
-
-unsigned int
-hb_unicode_get_eastasian_width (hb_unicode_funcs_t *ufuncs,
- hb_codepoint_t unicode)
-{
- return ufuncs->v.get_eastasian_width (ufuncs, unicode,
- ufuncs->v.get_eastasian_width_data);
-}
-
-
-HB_END_DECLS
diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc
new file mode 100644
index 0000000..ddad884
--- /dev/null
+++ b/src/hb-unicode.cc
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2009 Red Hat, Inc.
+ * Copyright © 2011 Codethink Limited
+ * Copyright (C) 2010 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.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Codethink Author(s): Ryan Lortie
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#include "hb-private.h"
+
+#include "hb-unicode-private.hh"
+
+HB_BEGIN_DECLS
+
+
+/*
+ * hb_unicode_funcs_t
+ */
+
+static unsigned int
+hb_unicode_get_combining_class_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
+ hb_codepoint_t unicode HB_UNUSED,
+ void *user_data HB_UNUSED)
+{
+ return 0;
+}
+
+static unsigned int
+hb_unicode_get_eastasian_width_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
+ hb_codepoint_t unicode HB_UNUSED,
+ void *user_data HB_UNUSED)
+{
+ return 1;
+}
+
+static hb_unicode_general_category_t
+hb_unicode_get_general_category_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
+ hb_codepoint_t unicode HB_UNUSED,
+ void *user_data HB_UNUSED)
+{
+ return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER;
+}
+
+static hb_codepoint_t
+hb_unicode_get_mirroring_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
+ hb_codepoint_t unicode HB_UNUSED,
+ void *user_data HB_UNUSED)
+{
+ return unicode;
+}
+
+static hb_script_t
+hb_unicode_get_script_nil (hb_unicode_funcs_t *ufuncs HB_UNUSED,
+ hb_codepoint_t unicode HB_UNUSED,
+ void *user_data HB_UNUSED)
+{
+ return HB_SCRIPT_UNKNOWN;
+}
+
+
+hb_unicode_funcs_t _hb_unicode_funcs_nil = {
+ HB_REFERENCE_COUNT_INVALID, /* ref_count */
+ NULL, /* parent */
+ TRUE, /* immutable */
+ {
+ hb_unicode_get_combining_class_nil,
+ hb_unicode_get_eastasian_width_nil,
+ hb_unicode_get_general_category_nil,
+ hb_unicode_get_mirroring_nil,
+ hb_unicode_get_script_nil,
+ }
+};
+
+
+hb_unicode_funcs_t *
+hb_unicode_funcs_create (hb_unicode_funcs_t *parent)
+{
+ hb_unicode_funcs_t *ufuncs;
+
+ if (!HB_OBJECT_DO_CREATE (hb_unicode_funcs_t, ufuncs))
+ return &_hb_unicode_funcs_nil;
+
+ if (parent != NULL)
+ {
+ hb_unicode_funcs_make_immutable (parent);
+ ufuncs->parent = hb_unicode_funcs_reference (parent);
+
+ ufuncs->get = parent->get;
+
+ /* We can safely copy user_data from parent since we hold a reference
+ * onto it and it's immutable. We should not copy the destroy notifiers
+ * though. */
+ ufuncs->user_data = parent->user_data;
+ }
+ else
+ {
+ ufuncs->get = _hb_unicode_funcs_nil.get;
+ }
+
+ return ufuncs;
+}
+
+hb_unicode_funcs_t *
+hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs)
+{
+ HB_OBJECT_DO_REFERENCE (ufuncs);
+}
+
+unsigned int
+hb_unicode_funcs_get_reference_count (hb_unicode_funcs_t *ufuncs)
+{
+ HB_OBJECT_DO_GET_REFERENCE_COUNT (ufuncs);
+}
+
+void
+hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
+{
+ HB_OBJECT_DO_DESTROY (ufuncs);
+
+#define DESTROY(name) if (ufuncs->destroy.name) ufuncs->destroy.name (ufuncs->user_data.name)
+ DESTROY (combining_class);
+ DESTROY (eastasian_width);
+ DESTROY (general_category);
+ DESTROY (mirroring);
+ DESTROY (script);
+#undef DESTROY
+
+ if (ufuncs->parent != NULL)
+ hb_unicode_funcs_destroy (ufuncs->parent);
+
+ free (ufuncs);
+}
+
+void
+hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
+{
+ if (HB_OBJECT_IS_INERT (ufuncs))
+ return;
+
+ ufuncs->immutable = TRUE;
+}
+
+hb_bool_t
+hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs)
+{
+ return ufuncs->immutable;
+}
+
+hb_unicode_funcs_t *
+hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs)
+{
+ return ufuncs->parent;
+}
+
+
+#define IMPLEMENT(return_type, name) \
+ \
+void \
+hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t *ufuncs, \
+ hb_unicode_get_##name##_func_t func, \
+ void *user_data, \
+ hb_destroy_func_t destroy) \
+{ \
+ if (ufuncs->immutable) \
+ return; \
+ \
+ if (ufuncs->destroy.name) \
+ ufuncs->destroy.name (ufuncs->user_data.name); \
+ \
+ if (func) { \
+ ufuncs->get.name = func; \
+ ufuncs->user_data.name = user_data; \
+ ufuncs->destroy.name = destroy; \
+ } else if (ufuncs->parent != NULL) { \
+ ufuncs->get.name = ufuncs->parent->get.name; \
+ ufuncs->user_data.name = ufuncs->parent->user_data.name; \
+ ufuncs->destroy.name = NULL; \
+ } else { \
+ ufuncs->get.name = hb_unicode_get_##name##_nil; \
+ ufuncs->user_data.name = NULL; \
+ ufuncs->destroy.name = NULL; \
+ } \
+} \
+ \
+return_type \
+hb_unicode_get_##name (hb_unicode_funcs_t *ufuncs, \
+ hb_codepoint_t unicode) \
+{ \
+ return ufuncs->get.name (ufuncs, unicode, ufuncs->user_data.name); \
+}
+
+IMPLEMENT (unsigned int, combining_class)
+IMPLEMENT (unsigned int, eastasian_width)
+IMPLEMENT (hb_unicode_general_category_t, general_category)
+IMPLEMENT (hb_codepoint_t, mirroring)
+IMPLEMENT (hb_script_t, script)
+
+#undef IMPLEMENT
+
+
+HB_END_DECLS
diff --git a/src/hb-unicode.h b/src/hb-unicode.h
index 9785f3e..0b94aa3 100644
--- a/src/hb-unicode.h
+++ b/src/hb-unicode.h
@@ -68,40 +68,25 @@
/* typedefs */
-typedef hb_codepoint_t (*hb_unicode_get_mirroring_func_t) (hb_unicode_funcs_t *ufuncs,
- hb_codepoint_t unicode,
- void *user_data);
-typedef hb_unicode_general_category_t (*hb_unicode_get_general_category_func_t) (hb_unicode_funcs_t *ufuncs,
- hb_codepoint_t unicode,
- void *user_data);
-typedef hb_script_t (*hb_unicode_get_script_func_t) (hb_unicode_funcs_t *ufuncs,
- hb_codepoint_t unicode,
- void *user_data);
typedef unsigned int (*hb_unicode_get_combining_class_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode,
void *user_data);
typedef unsigned int (*hb_unicode_get_eastasian_width_func_t) (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode,
void *user_data);
+typedef hb_unicode_general_category_t (*hb_unicode_get_general_category_func_t) (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode,
+ void *user_data);
+typedef hb_codepoint_t (*hb_unicode_get_mirroring_func_t) (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode,
+ void *user_data);
+typedef hb_script_t (*hb_unicode_get_script_func_t) (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode,
+ void *user_data);
/* setters */
void
-hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs,
- hb_unicode_get_mirroring_func_t mirroring_func,
- void *user_data, hb_destroy_func_t destroy);
-
-void
-hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs,
- hb_unicode_get_general_category_func_t general_category_func,
- void *user_data, hb_destroy_func_t destroy);
-
-void
-hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs,
- hb_unicode_get_script_func_t script_func,
- void *user_data, hb_destroy_func_t destroy);
-
-void
hb_unicode_funcs_set_combining_class_func (hb_unicode_funcs_t *ufuncs,
hb_unicode_get_combining_class_func_t combining_class_func,
void *user_data, hb_destroy_func_t destroy);
@@ -111,21 +96,25 @@
hb_unicode_get_eastasian_width_func_t eastasian_width_func,
void *user_data, hb_destroy_func_t destroy);
+void
+hb_unicode_funcs_set_general_category_func (hb_unicode_funcs_t *ufuncs,
+ hb_unicode_get_general_category_func_t general_category_func,
+ void *user_data, hb_destroy_func_t destroy);
+
+void
+hb_unicode_funcs_set_mirroring_func (hb_unicode_funcs_t *ufuncs,
+ hb_unicode_get_mirroring_func_t mirroring_func,
+ void *user_data, hb_destroy_func_t destroy);
+
+void
+hb_unicode_funcs_set_script_func (hb_unicode_funcs_t *ufuncs,
+ hb_unicode_get_script_func_t script_func,
+ void *user_data, hb_destroy_func_t destroy);
+
+
/* accessors */
-hb_codepoint_t
-hb_unicode_get_mirroring (hb_unicode_funcs_t *ufuncs,
- hb_codepoint_t unicode);
-
-hb_unicode_general_category_t
-hb_unicode_get_general_category (hb_unicode_funcs_t *ufuncs,
- hb_codepoint_t unicode);
-
-hb_script_t
-hb_unicode_get_script (hb_unicode_funcs_t *ufuncs,
- hb_codepoint_t unicode);
-
unsigned int
hb_unicode_get_combining_class (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode);
@@ -134,6 +123,18 @@
hb_unicode_get_eastasian_width (hb_unicode_funcs_t *ufuncs,
hb_codepoint_t unicode);
+hb_unicode_general_category_t
+hb_unicode_get_general_category (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode);
+
+hb_codepoint_t
+hb_unicode_get_mirroring (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode);
+
+hb_script_t
+hb_unicode_get_script (hb_unicode_funcs_t *ufuncs,
+ hb_codepoint_t unicode);
+
HB_END_DECLS
diff --git a/test/test-unicode.c b/test/test-unicode.c
index f610c1d..c210d54 100644
--- a/test/test-unicode.c
+++ b/test/test-unicode.c
@@ -120,10 +120,14 @@
static void
test_subclassing_nil (void)
{
- hb_unicode_funcs_t *uf = hb_unicode_funcs_create (NULL);
+ hb_unicode_funcs_t *uf, *aa;
+
+ uf = hb_unicode_funcs_create (NULL);
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 1);
- hb_unicode_funcs_t *aa = hb_unicode_funcs_create (uf);
+
+ aa = hb_unicode_funcs_create (uf);
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 2);
+
hb_unicode_funcs_destroy (uf);
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 1);
@@ -133,7 +137,6 @@
g_assert_cmpint (hb_unicode_get_script (aa, 'a'), ==, HB_SCRIPT_ARABIC);
g_assert_cmpint (hb_unicode_get_script (aa, 'b'), ==, HB_SCRIPT_UNKNOWN);
-
g_assert_cmpint (hb_unicode_funcs_get_reference_count (aa), ==, 1);
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 1);
g_assert (!freed0 && !freed1);
@@ -145,10 +148,14 @@
static void
test_subclassing_glib (void)
{
- hb_unicode_funcs_t *uf = hb_glib_get_unicode_funcs ();
+ hb_unicode_funcs_t *uf, *aa;
+
+ uf = hb_glib_get_unicode_funcs ();
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 0);
- hb_unicode_funcs_t *aa = hb_unicode_funcs_create (uf);
+
+ aa = hb_unicode_funcs_create (uf);
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 0);
+
hb_unicode_funcs_destroy (uf);
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 0);
@@ -168,13 +175,15 @@
static void
test_subclassing_deep (void)
{
- hb_unicode_funcs_t *uf = hb_unicode_funcs_create (NULL);
+ hb_unicode_funcs_t *uf, *aa;
+
+ uf = hb_unicode_funcs_create (NULL);
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 1);
hb_unicode_funcs_set_script_func (uf, simple_get_script,
unique_pointer0, free_up);
- hb_unicode_funcs_t *aa = hb_unicode_funcs_create (uf);
+ aa = hb_unicode_funcs_create (uf);
g_assert_cmpint (hb_unicode_funcs_get_reference_count (aa), ==, 1);
g_assert_cmpint (hb_unicode_funcs_get_reference_count (uf), ==, 2);