hb-unicode.cc 7.0 KB
Newer Older
B
Behdad Esfahbod 已提交
1
/*
B
Behdad Esfahbod 已提交
2
 * Copyright © 2009  Red Hat, Inc.
3
 * Copyright © 2011 Codethink Limited
B
Behdad Esfahbod 已提交
4
 * Copyright © 2010,2011  Google, Inc.
B
Behdad Esfahbod 已提交
5
 *
B
Behdad Esfahbod 已提交
6
 *  This is part of HarfBuzz, a text shaping library.
B
Behdad Esfahbod 已提交
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
 *
 * 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
27
 * Codethink Author(s): Ryan Lortie
28
 * Google Author(s): Behdad Esfahbod
B
Behdad Esfahbod 已提交
29 30
 */

31
#include "hb-private.hh"
B
Behdad Esfahbod 已提交
32

33
#include "hb-unicode-private.hh"
B
Behdad Esfahbod 已提交
34

B
Behdad Esfahbod 已提交
35 36 37
HB_BEGIN_DECLS


B
Behdad Esfahbod 已提交
38 39 40 41
/*
 * hb_unicode_funcs_t
 */

B
Behdad Esfahbod 已提交
42
static unsigned int
43 44 45
hb_unicode_combining_class_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
				hb_codepoint_t      unicode   HB_UNUSED,
				void               *user_data HB_UNUSED)
B
Behdad Esfahbod 已提交
46 47
{
  return 0;
48 49
}

B
Behdad Esfahbod 已提交
50
static unsigned int
51 52 53
hb_unicode_eastasian_width_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
				hb_codepoint_t      unicode   HB_UNUSED,
				void               *user_data HB_UNUSED)
B
Behdad Esfahbod 已提交
54 55 56 57 58
{
  return 1;
}

static hb_unicode_general_category_t
59 60 61
hb_unicode_general_category_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
				 hb_codepoint_t      unicode   HB_UNUSED,
				 void               *user_data HB_UNUSED)
B
Behdad Esfahbod 已提交
62 63 64 65 66
{
  return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER;
}

static hb_codepoint_t
67 68 69
hb_unicode_mirroring_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
			  hb_codepoint_t      unicode   HB_UNUSED,
			  void               *user_data HB_UNUSED)
B
Behdad Esfahbod 已提交
70 71 72 73 74
{
  return unicode;
}

static hb_script_t
75 76 77
hb_unicode_script_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
		       hb_codepoint_t      unicode   HB_UNUSED,
		       void               *user_data HB_UNUSED)
B
Behdad Esfahbod 已提交
78 79 80
{
  return HB_SCRIPT_UNKNOWN;
}
81

82
static hb_bool_t
83
hb_unicode_compose_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
84 85 86 87 88 89 90 91 92 93
			hb_codepoint_t      a         HB_UNUSED,
			hb_codepoint_t      b         HB_UNUSED,
			hb_codepoint_t     *ab        HB_UNUSED,
			void               *user_data HB_UNUSED)
{
  /* TODO handle Hangul jamo here? */
  return FALSE;
}

static hb_bool_t
94
hb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
95 96 97 98 99 100 101 102 103
			  hb_codepoint_t      ab        HB_UNUSED,
			  hb_codepoint_t     *a         HB_UNUSED,
			  hb_codepoint_t     *b         HB_UNUSED,
			  void               *user_data HB_UNUSED)
{
  /* TODO handle Hangul jamo here? */
  return FALSE;
}

104

105
hb_unicode_funcs_t _hb_unicode_funcs_nil = {
106 107
  HB_OBJECT_HEADER_STATIC,

108
  NULL, /* parent */
109
  TRUE, /* immutable */
110
  {
111
#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil,
B
Behdad Esfahbod 已提交
112 113
    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_UNICODE_FUNC_IMPLEMENT
114
  }
B
Behdad Esfahbod 已提交
115 116
};

117

118 119 120 121 122 123
hb_unicode_funcs_t *
hb_unicode_funcs_get_default (void)
{
  return &_hb_unicode_funcs_default;
}

B
Behdad Esfahbod 已提交
124
hb_unicode_funcs_t *
125
hb_unicode_funcs_create (hb_unicode_funcs_t *parent)
B
Behdad Esfahbod 已提交
126 127 128
{
  hb_unicode_funcs_t *ufuncs;

129
  if (!(ufuncs = hb_object_create<hb_unicode_funcs_t> ()))
B
Behdad Esfahbod 已提交
130 131
    return &_hb_unicode_funcs_nil;

132 133
  if (!parent)
    parent = &_hb_unicode_funcs_nil;
134

135 136
  hb_unicode_funcs_make_immutable (parent);
  ufuncs->parent = hb_unicode_funcs_reference (parent);
137

138
  ufuncs->func = parent->func;
139 140 141 142 143

  /* 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;
144

B
Behdad Esfahbod 已提交
145 146 147
  return ufuncs;
}

148 149 150 151 152 153
hb_unicode_funcs_t *
hb_unicode_funcs_get_empty (void)
{
  return &_hb_unicode_funcs_nil;
}

B
Behdad Esfahbod 已提交
154 155 156
hb_unicode_funcs_t *
hb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs)
{
157
  return hb_object_reference (ufuncs);
B
Behdad Esfahbod 已提交
158 159 160 161 162
}

void
hb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
{
163
  if (!hb_object_destroy (ufuncs)) return;
B
Behdad Esfahbod 已提交
164

B
Behdad Esfahbod 已提交
165
#define HB_UNICODE_FUNC_IMPLEMENT(name) \
B
Behdad Esfahbod 已提交
166 167 168
  if (ufuncs->destroy.name) ufuncs->destroy.name (ufuncs->user_data.name);
    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_UNICODE_FUNC_IMPLEMENT
169

170
  hb_unicode_funcs_destroy (ufuncs->parent);
171

B
Behdad Esfahbod 已提交
172 173 174
  free (ufuncs);
}

175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191
hb_bool_t
hb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
			        hb_user_data_key_t *key,
			        void *              data,
			        hb_destroy_func_t   destroy)
{
  return hb_object_set_user_data (ufuncs, key, data, destroy);
}

void *
hb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
			        hb_user_data_key_t *key)
{
  return hb_object_get_user_data (ufuncs, key);
}


192 193 194
void
hb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
{
195
  if (hb_object_is_inert (ufuncs))
196 197 198 199 200
    return;

  ufuncs->immutable = TRUE;
}

B
Behdad Esfahbod 已提交
201 202 203 204 205 206
hb_bool_t
hb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs)
{
  return ufuncs->immutable;
}

207 208 209
hb_unicode_funcs_t *
hb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs)
{
210
  return ufuncs->parent ? ufuncs->parent : &_hb_unicode_funcs_nil;
211 212
}

B
Behdad Esfahbod 已提交
213

B
Behdad Esfahbod 已提交
214
#define HB_UNICODE_FUNC_IMPLEMENT(name)						\
B
Behdad Esfahbod 已提交
215 216 217
										\
void										\
hb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t		   *ufuncs,	\
218
				    hb_unicode_##name##_func_t	    func,	\
B
Behdad Esfahbod 已提交
219 220 221 222 223 224 225 226 227 228
				    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) {									\
229
    ufuncs->func.name = func;							\
B
Behdad Esfahbod 已提交
230 231 232
    ufuncs->user_data.name = user_data;						\
    ufuncs->destroy.name = destroy;						\
  } else {									\
233
    ufuncs->func.name = ufuncs->parent->func.name;				\
B
Behdad Esfahbod 已提交
234 235 236
    ufuncs->user_data.name = ufuncs->parent->user_data.name;			\
    ufuncs->destroy.name = NULL;						\
  }										\
B
Behdad Esfahbod 已提交
237 238 239 240 241 242 243
}

    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_UNICODE_FUNC_IMPLEMENT


#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name)				\
B
Behdad Esfahbod 已提交
244 245
										\
return_type									\
246 247
hb_unicode_##name (hb_unicode_funcs_t *ufuncs,					\
		   hb_codepoint_t      unicode)					\
B
Behdad Esfahbod 已提交
248
{										\
249
  return ufuncs->func.name (ufuncs, unicode, ufuncs->user_data.name);		\
B
Behdad Esfahbod 已提交
250
}
B
Behdad Esfahbod 已提交
251
    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
B
Behdad Esfahbod 已提交
252
#undef HB_UNICODE_FUNC_IMPLEMENT
B
Behdad Esfahbod 已提交
253

254 255 256 257 258 259
hb_bool_t
hb_unicode_compose (hb_unicode_funcs_t *ufuncs,
		    hb_codepoint_t      a,
		    hb_codepoint_t      b,
		    hb_codepoint_t     *ab)
{
260
  *ab = 0;
261 262 263 264 265 266 267 268 269
  return ufuncs->func.compose (ufuncs, a, b, ab, ufuncs->user_data.compose);
}

hb_bool_t
hb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
		      hb_codepoint_t      ab,
		      hb_codepoint_t     *a,
		      hb_codepoint_t     *b)
{
270
  *a = *b = 0;
271 272
  return ufuncs->func.decompose (ufuncs, ab, a, b, ufuncs->user_data.decompose);
}
B
Behdad Esfahbod 已提交
273

B
Behdad Esfahbod 已提交
274
HB_END_DECLS