hb-unicode.cc revision 2db2a566826ed4763ce69629194ec656bd48b0bd
15c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod/*
22409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 2009  Red Hat, Inc.
32fd0c577e322ccbf762927bc4600b3ea31db4c80Ryan Lortie * Copyright © 2011 Codethink Limited
42409d5f8d7dd8b535ce5ea29e933f7db27d33793Behdad Esfahbod * Copyright © 2010,2011  Google, Inc.
55c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod *
6c755cb3e3ac55156d0d2ec05adea7a650b97cc41Behdad Esfahbod *  This is part of HarfBuzz, a text shaping library.
75c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod *
85c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod * Permission is hereby granted, without written agreement and without
95c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this
105c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod * software and its documentation for any purpose, provided that the
115c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod * above copyright notice and the following two paragraphs appear in
125c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod * all copies of this software.
135c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod *
145c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
155c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
165c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
175c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
185c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod * DAMAGE.
195c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod *
205c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
215c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
225c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
235c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
245c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
255c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod *
265c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod * Red Hat Author(s): Behdad Esfahbod
272fd0c577e322ccbf762927bc4600b3ea31db4c80Ryan Lortie * Codethink Author(s): Ryan Lortie
28fb194b8794898f51eb596fa4092c26606889d376Behdad Esfahbod * Google Author(s): Behdad Esfahbod
295c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod */
305c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod
31c57d454accff66e5f2c58006e8fb40bc020b6182Behdad Esfahbod#include "hb-private.hh"
325c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod
33fb194b8794898f51eb596fa4092c26606889d376Behdad Esfahbod#include "hb-unicode-private.hh"
345c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod
35acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod
36acdba3f90b232fc12fcb200dca2584481b339118Behdad Esfahbod
375c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod/*
385c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod * hb_unicode_funcs_t
395c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod */
405c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod
41891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbodstatic unsigned int
42c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbodhb_unicode_combining_class_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
43c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod				hb_codepoint_t      unicode   HB_UNUSED,
44c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod				void               *user_data HB_UNUSED)
45891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod{
46891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod  return 0;
472fd0c577e322ccbf762927bc4600b3ea31db4c80Ryan Lortie}
482fd0c577e322ccbf762927bc4600b3ea31db4c80Ryan Lortie
49891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbodstatic unsigned int
50c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbodhb_unicode_eastasian_width_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
51c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod				hb_codepoint_t      unicode   HB_UNUSED,
52c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod				void               *user_data HB_UNUSED)
53891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod{
54891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod  return 1;
55891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod}
56891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod
57891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbodstatic hb_unicode_general_category_t
58c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbodhb_unicode_general_category_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
59c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod				 hb_codepoint_t      unicode   HB_UNUSED,
60c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod				 void               *user_data HB_UNUSED)
61891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod{
62891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod  return HB_UNICODE_GENERAL_CATEGORY_OTHER_LETTER;
63891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod}
64891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod
65891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbodstatic hb_codepoint_t
66c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbodhb_unicode_mirroring_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
67c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod			  hb_codepoint_t      unicode   HB_UNUSED,
68c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod			  void               *user_data HB_UNUSED)
69891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod{
70891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod  return unicode;
71891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod}
72891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod
73891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbodstatic hb_script_t
74c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbodhb_unicode_script_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
75c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod		       hb_codepoint_t      unicode   HB_UNUSED,
76c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod		       void               *user_data HB_UNUSED)
77891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod{
78891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod  return HB_SCRIPT_UNKNOWN;
79891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod}
802fd0c577e322ccbf762927bc4600b3ea31db4c80Ryan Lortie
81c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbodstatic hb_bool_t
8222fdc66712464bdb02e45eed49e4be57e79b442fBehdad Esfahbodhb_unicode_compose_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
83c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod			hb_codepoint_t      a         HB_UNUSED,
84c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod			hb_codepoint_t      b         HB_UNUSED,
85c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod			hb_codepoint_t     *ab        HB_UNUSED,
86c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod			void               *user_data HB_UNUSED)
87c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod{
88c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod  /* TODO handle Hangul jamo here? */
89c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod  return FALSE;
90c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod}
91c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod
92c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbodstatic hb_bool_t
9322fdc66712464bdb02e45eed49e4be57e79b442fBehdad Esfahbodhb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
94c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod			  hb_codepoint_t      ab        HB_UNUSED,
95c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod			  hb_codepoint_t     *a         HB_UNUSED,
96c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod			  hb_codepoint_t     *b         HB_UNUSED,
97c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod			  void               *user_data HB_UNUSED)
98c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod{
99c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod  /* TODO handle Hangul jamo here? */
100c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod  return FALSE;
101c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod}
102c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod
10348910f8f0034c54b4e11cef3d08aa40e52c06b28Behdad Esfahbod
104af9e104028b7cdc1fbba0eb1d86cfa4d5258657fBehdad Esfahbodhb_unicode_funcs_t _hb_unicode_funcs_nil = {
105fca368c4682624346a0aaee690e1ad6ed4c0b337Behdad Esfahbod  HB_OBJECT_HEADER_STATIC,
106fca368c4682624346a0aaee690e1ad6ed4c0b337Behdad Esfahbod
1072fd0c577e322ccbf762927bc4600b3ea31db4c80Ryan Lortie  NULL, /* parent */
108eb27ec0cef0d92740875ab5035b53acc639e5faeBehdad Esfahbod  TRUE, /* immutable */
109bf36a1074ab23abeab0a7a6c47db26770dc1ab0aBehdad Esfahbod  {
110c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil,
1114b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
1124b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod#undef HB_UNICODE_FUNC_IMPLEMENT
113bf36a1074ab23abeab0a7a6c47db26770dc1ab0aBehdad Esfahbod  }
1145c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod};
1155c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod
116fb194b8794898f51eb596fa4092c26606889d376Behdad Esfahbod
1175c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbodhb_unicode_funcs_t *
118d4bee9f813bb299b1c4aab7c33d588be2a7d354bBehdad Esfahbodhb_unicode_funcs_get_default (void)
119d4bee9f813bb299b1c4aab7c33d588be2a7d354bBehdad Esfahbod{
120d4bee9f813bb299b1c4aab7c33d588be2a7d354bBehdad Esfahbod  return &_hb_unicode_funcs_default;
121d4bee9f813bb299b1c4aab7c33d588be2a7d354bBehdad Esfahbod}
122d4bee9f813bb299b1c4aab7c33d588be2a7d354bBehdad Esfahbod
123d4bee9f813bb299b1c4aab7c33d588be2a7d354bBehdad Esfahbodhb_unicode_funcs_t *
1242fd0c577e322ccbf762927bc4600b3ea31db4c80Ryan Lortiehb_unicode_funcs_create (hb_unicode_funcs_t *parent)
1255c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod{
1265c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod  hb_unicode_funcs_t *ufuncs;
1275c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod
12847e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod  if (!(ufuncs = hb_object_create<hb_unicode_funcs_t> ()))
1295c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod    return &_hb_unicode_funcs_nil;
1305c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod
131c784c67a28f5b92d396eaa9529d57ef91a5cb9acBehdad Esfahbod  if (!parent)
132c784c67a28f5b92d396eaa9529d57ef91a5cb9acBehdad Esfahbod    parent = &_hb_unicode_funcs_nil;
133fb194b8794898f51eb596fa4092c26606889d376Behdad Esfahbod
134c784c67a28f5b92d396eaa9529d57ef91a5cb9acBehdad Esfahbod  hb_unicode_funcs_make_immutable (parent);
135c784c67a28f5b92d396eaa9529d57ef91a5cb9acBehdad Esfahbod  ufuncs->parent = hb_unicode_funcs_reference (parent);
136fb194b8794898f51eb596fa4092c26606889d376Behdad Esfahbod
137c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod  ufuncs->func = parent->func;
138c784c67a28f5b92d396eaa9529d57ef91a5cb9acBehdad Esfahbod
139c784c67a28f5b92d396eaa9529d57ef91a5cb9acBehdad Esfahbod  /* We can safely copy user_data from parent since we hold a reference
140c784c67a28f5b92d396eaa9529d57ef91a5cb9acBehdad Esfahbod   * onto it and it's immutable.  We should not copy the destroy notifiers
141c784c67a28f5b92d396eaa9529d57ef91a5cb9acBehdad Esfahbod   * though. */
142c784c67a28f5b92d396eaa9529d57ef91a5cb9acBehdad Esfahbod  ufuncs->user_data = parent->user_data;
14348910f8f0034c54b4e11cef3d08aa40e52c06b28Behdad Esfahbod
1445c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod  return ufuncs;
1455c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod}
1465c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod
1475c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbodhb_unicode_funcs_t *
14880a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbodhb_unicode_funcs_get_empty (void)
14980a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbod{
15080a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbod  return &_hb_unicode_funcs_nil;
15180a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbod}
15280a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbod
15380a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbodhb_unicode_funcs_t *
1545c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbodhb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs)
1555c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod{
15647e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod  return hb_object_reference (ufuncs);
1575c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod}
1585c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod
1595c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbodvoid
1605c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbodhb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
1615c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod{
16247e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod  if (!hb_object_destroy (ufuncs)) return;
1635c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod
164891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod#define HB_UNICODE_FUNC_IMPLEMENT(name) \
1654b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod  if (ufuncs->destroy.name) ufuncs->destroy.name (ufuncs->user_data.name);
1664b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
1674b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod#undef HB_UNICODE_FUNC_IMPLEMENT
168fb194b8794898f51eb596fa4092c26606889d376Behdad Esfahbod
169c784c67a28f5b92d396eaa9529d57ef91a5cb9acBehdad Esfahbod  hb_unicode_funcs_destroy (ufuncs->parent);
1702fd0c577e322ccbf762927bc4600b3ea31db4c80Ryan Lortie
1715c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod  free (ufuncs);
1725c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod}
1735c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod
1745fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_bool_t
1755fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
1765fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod			        hb_user_data_key_t *key,
1775fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod			        void *              data,
17833ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod			        hb_destroy_func_t   destroy,
17933ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod				hb_bool_t           replace)
1805fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod{
18133ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod  return hb_object_set_user_data (ufuncs, key, data, destroy, replace);
1825fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod}
1835fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod
1845fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodvoid *
1855fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
1865fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod			        hb_user_data_key_t *key)
1875fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod{
1885fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod  return hb_object_get_user_data (ufuncs, key);
1895fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod}
1905fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod
1915fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod
192eb27ec0cef0d92740875ab5035b53acc639e5faeBehdad Esfahbodvoid
193eb27ec0cef0d92740875ab5035b53acc639e5faeBehdad Esfahbodhb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
194eb27ec0cef0d92740875ab5035b53acc639e5faeBehdad Esfahbod{
19547e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod  if (hb_object_is_inert (ufuncs))
196eb27ec0cef0d92740875ab5035b53acc639e5faeBehdad Esfahbod    return;
197eb27ec0cef0d92740875ab5035b53acc639e5faeBehdad Esfahbod
198eb27ec0cef0d92740875ab5035b53acc639e5faeBehdad Esfahbod  ufuncs->immutable = TRUE;
199eb27ec0cef0d92740875ab5035b53acc639e5faeBehdad Esfahbod}
200eb27ec0cef0d92740875ab5035b53acc639e5faeBehdad Esfahbod
201645f6f265b5f6fb85b3c0f59ea874d58c86e3917Behdad Esfahbodhb_bool_t
202645f6f265b5f6fb85b3c0f59ea874d58c86e3917Behdad Esfahbodhb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs)
203645f6f265b5f6fb85b3c0f59ea874d58c86e3917Behdad Esfahbod{
204645f6f265b5f6fb85b3c0f59ea874d58c86e3917Behdad Esfahbod  return ufuncs->immutable;
205645f6f265b5f6fb85b3c0f59ea874d58c86e3917Behdad Esfahbod}
206645f6f265b5f6fb85b3c0f59ea874d58c86e3917Behdad Esfahbod
207fb194b8794898f51eb596fa4092c26606889d376Behdad Esfahbodhb_unicode_funcs_t *
208fb194b8794898f51eb596fa4092c26606889d376Behdad Esfahbodhb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs)
209fb194b8794898f51eb596fa4092c26606889d376Behdad Esfahbod{
210c784c67a28f5b92d396eaa9529d57ef91a5cb9acBehdad Esfahbod  return ufuncs->parent ? ufuncs->parent : &_hb_unicode_funcs_nil;
211fb194b8794898f51eb596fa4092c26606889d376Behdad Esfahbod}
212fb194b8794898f51eb596fa4092c26606889d376Behdad Esfahbod
21304cc0a29ee1472c318c36efcd19b9c1a6657d9eaBehdad Esfahbod
214891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod#define HB_UNICODE_FUNC_IMPLEMENT(name)						\
2154b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod										\
2164b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbodvoid										\
2174b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbodhb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t		   *ufuncs,	\
218c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod				    hb_unicode_##name##_func_t	    func,	\
2194b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod				    void			   *user_data,	\
2204b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod				    hb_destroy_func_t		    destroy)	\
2214b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod{										\
2224b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod  if (ufuncs->immutable)							\
2234b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod    return;									\
2244b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod										\
2254b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod  if (ufuncs->destroy.name)							\
2264b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod    ufuncs->destroy.name (ufuncs->user_data.name);				\
2274b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod										\
2284b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod  if (func) {									\
229c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod    ufuncs->func.name = func;							\
2304b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod    ufuncs->user_data.name = user_data;						\
2314b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod    ufuncs->destroy.name = destroy;						\
2324b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod  } else {									\
233c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod    ufuncs->func.name = ufuncs->parent->func.name;				\
2344b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod    ufuncs->user_data.name = ufuncs->parent->user_data.name;			\
2354b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod    ufuncs->destroy.name = NULL;						\
2364b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod  }										\
237891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod}
238891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod
239891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
240891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod#undef HB_UNICODE_FUNC_IMPLEMENT
241891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod
242891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod
243891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name)				\
2444b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod										\
2454b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbodreturn_type									\
246c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbodhb_unicode_##name (hb_unicode_funcs_t *ufuncs,					\
247c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod		   hb_codepoint_t      unicode)					\
2484b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod{										\
249c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod  return ufuncs->func.name (ufuncs, unicode, ufuncs->user_data.name);		\
2504b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod}
251891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
2524b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod#undef HB_UNICODE_FUNC_IMPLEMENT
2535ceefa1d8dbd310570ea8d1c47107fe8d3dc96d9Behdad Esfahbod
254c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbodhb_bool_t
255c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbodhb_unicode_compose (hb_unicode_funcs_t *ufuncs,
256c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod		    hb_codepoint_t      a,
257c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod		    hb_codepoint_t      b,
258c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod		    hb_codepoint_t     *ab)
259c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod{
26022fdc66712464bdb02e45eed49e4be57e79b442fBehdad Esfahbod  *ab = 0;
261c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod  return ufuncs->func.compose (ufuncs, a, b, ab, ufuncs->user_data.compose);
262c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod}
263c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod
264c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbodhb_bool_t
265c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbodhb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
266c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod		      hb_codepoint_t      ab,
267c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod		      hb_codepoint_t     *a,
268c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod		      hb_codepoint_t     *b)
269c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod{
270ffd4a436f7baccb68a0c3602f94ea0246e32844fBehdad Esfahbod  *a = ab; *b = 0;
271c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod  return ufuncs->func.decompose (ufuncs, ab, a, b, ufuncs->user_data.decompose);
272c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod}
2735ceefa1d8dbd310570ea8d1c47107fe8d3dc96d9Behdad Esfahbod
2742db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod
2752db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod
2762db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbodunsigned int
2772db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod_hb_unicode_modified_combining_class (hb_unicode_funcs_t *ufuncs,
2782db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod				      hb_codepoint_t      unicode)
2792db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod{
2802db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod  int c = hb_unicode_combining_class (ufuncs, unicode);
2812db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod
2822db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod  if (unlikely (hb_in_range<int> (c, 27, 33)))
2832db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod  {
2842db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod    /* Modify the combining-class to suit Arabic better.  See:
2852db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     * http://unicode.org/faq/normalization.html#8
2862db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     * http://unicode.org/faq/normalization.html#9
2872db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     */
2882db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod    c = c == 33 ? 27 : c + 1;
2892db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod  }
2902db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod  else if (unlikely (hb_in_range<int> (c, 10, 25)))
2912db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod  {
2922db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod    /* The equivalent fix for Hebrew is more complex.
2932db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     *
2942db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     * We permute the "fixed-position" classes 10-25 into the order
2952db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     * described in the SBL Hebrew manual:
2962db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     *
2972db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     * http://www.sbl-site.org/Fonts/SBLHebrewUserManual1.5x.pdf
2982db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     *
2992db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     * (as recommended by:
3002db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     *  http://forum.fontlab.com/archive-old-microsoft-volt-group/vista-and-diacritic-ordering-t6751.0.html)
3012db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     *
3022db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     * More details here:
3032db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     * https://bugzilla.mozilla.org/show_bug.cgi?id=662055
3042db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     */
3052db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod    static const int permuted_hebrew_classes[25 - 10 + 1] = {
3062db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 10 sheva */        22,
3072db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 11 hataf segol */  15,
3082db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 12 hataf patah */  16,
3092db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 13 hataf qamats */ 17,
3102db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 14 hiriq */        23,
3112db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 15 tsere */        18,
3122db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 16 segol */        19,
3132db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 17 patah */        20,
3142db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 18 qamats */       21,
3152db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 19 holam */        14,
3162db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 20 qubuts */       24,
3172db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 21 dagesh */       12,
3182db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 22 meteg */        25,
3192db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 23 rafe */         13,
3202db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 24 shin dot */     10,
3212db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 25 sin dot */      11,
3222db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod    };
3232db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod    c = permuted_hebrew_classes[c - 10];
3242db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod  }
3252db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod
3262db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod  return c;
3272db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod}
3282db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod
329