hb-unicode.cc revision 21fdcee00125b6e1c09f0bed3064d16ccd3a7a5d
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
4121fdcee00125b6e1c09f0bed3064d16ccd3a7a5dBehdad Esfahbodstatic hb_unicode_combining_class_t
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{
4621fdcee00125b6e1c09f0bed3064d16ccd3a7a5dBehdad Esfahbod  return HB_UNICODE_COMBINING_CLASS_NOT_REORDERED;
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{
880594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  return false;
89c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod}
90c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod
91c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbodstatic hb_bool_t
9222fdc66712464bdb02e45eed49e4be57e79b442fBehdad Esfahbodhb_unicode_decompose_nil (hb_unicode_funcs_t *ufuncs    HB_UNUSED,
93c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod			  hb_codepoint_t      ab        HB_UNUSED,
94c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod			  hb_codepoint_t     *a         HB_UNUSED,
95c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod			  hb_codepoint_t     *b         HB_UNUSED,
96c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod			  void               *user_data HB_UNUSED)
97c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod{
980594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  return false;
99c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod}
100c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod
10148910f8f0034c54b4e11cef3d08aa40e52c06b28Behdad Esfahbod
102378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbodstatic unsigned int
103378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbodhb_unicode_decompose_compatibility_nil (hb_unicode_funcs_t *ufuncs     HB_UNUSED,
104378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod					hb_codepoint_t      u          HB_UNUSED,
105378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod					hb_codepoint_t     *decomposed HB_UNUSED,
106378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod					void               *user_data  HB_UNUSED)
107378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod{
108378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod  return 0;
109378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod}
110378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod
111fb194b8794898f51eb596fa4092c26606889d376Behdad Esfahbod
1125c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbodhb_unicode_funcs_t *
113d4bee9f813bb299b1c4aab7c33d588be2a7d354bBehdad Esfahbodhb_unicode_funcs_get_default (void)
114d4bee9f813bb299b1c4aab7c33d588be2a7d354bBehdad Esfahbod{
115be4560a3b5e8599cbe2b29a01a60c21c9e2b194fBehdad Esfahbod  return const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_default);
116d4bee9f813bb299b1c4aab7c33d588be2a7d354bBehdad Esfahbod}
117d4bee9f813bb299b1c4aab7c33d588be2a7d354bBehdad Esfahbod
118d4bee9f813bb299b1c4aab7c33d588be2a7d354bBehdad Esfahbodhb_unicode_funcs_t *
1192fd0c577e322ccbf762927bc4600b3ea31db4c80Ryan Lortiehb_unicode_funcs_create (hb_unicode_funcs_t *parent)
1205c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod{
1215c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod  hb_unicode_funcs_t *ufuncs;
1225c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod
12347e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod  if (!(ufuncs = hb_object_create<hb_unicode_funcs_t> ()))
124f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod    return hb_unicode_funcs_get_empty ();
1255c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod
126c784c67a28f5b92d396eaa9529d57ef91a5cb9acBehdad Esfahbod  if (!parent)
127f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod    parent = hb_unicode_funcs_get_empty ();
128fb194b8794898f51eb596fa4092c26606889d376Behdad Esfahbod
129c784c67a28f5b92d396eaa9529d57ef91a5cb9acBehdad Esfahbod  hb_unicode_funcs_make_immutable (parent);
130c784c67a28f5b92d396eaa9529d57ef91a5cb9acBehdad Esfahbod  ufuncs->parent = hb_unicode_funcs_reference (parent);
131fb194b8794898f51eb596fa4092c26606889d376Behdad Esfahbod
132c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod  ufuncs->func = parent->func;
133c784c67a28f5b92d396eaa9529d57ef91a5cb9acBehdad Esfahbod
134c784c67a28f5b92d396eaa9529d57ef91a5cb9acBehdad Esfahbod  /* We can safely copy user_data from parent since we hold a reference
135c784c67a28f5b92d396eaa9529d57ef91a5cb9acBehdad Esfahbod   * onto it and it's immutable.  We should not copy the destroy notifiers
136c784c67a28f5b92d396eaa9529d57ef91a5cb9acBehdad Esfahbod   * though. */
137c784c67a28f5b92d396eaa9529d57ef91a5cb9acBehdad Esfahbod  ufuncs->user_data = parent->user_data;
13848910f8f0034c54b4e11cef3d08aa40e52c06b28Behdad Esfahbod
1395c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod  return ufuncs;
1405c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod}
1415c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod
142f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod
143be4560a3b5e8599cbe2b29a01a60c21c9e2b194fBehdad Esfahbodextern HB_INTERNAL const hb_unicode_funcs_t _hb_unicode_funcs_nil;
144be4560a3b5e8599cbe2b29a01a60c21c9e2b194fBehdad Esfahbodconst hb_unicode_funcs_t _hb_unicode_funcs_nil = {
145be4560a3b5e8599cbe2b29a01a60c21c9e2b194fBehdad Esfahbod  HB_OBJECT_HEADER_STATIC,
146be4560a3b5e8599cbe2b29a01a60c21c9e2b194fBehdad Esfahbod
147be4560a3b5e8599cbe2b29a01a60c21c9e2b194fBehdad Esfahbod  NULL, /* parent */
1480594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  true, /* immutable */
149be4560a3b5e8599cbe2b29a01a60c21c9e2b194fBehdad Esfahbod  {
150f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod#define HB_UNICODE_FUNC_IMPLEMENT(name) hb_unicode_##name##_nil,
151be4560a3b5e8599cbe2b29a01a60c21c9e2b194fBehdad Esfahbod    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
152f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod#undef HB_UNICODE_FUNC_IMPLEMENT
153be4560a3b5e8599cbe2b29a01a60c21c9e2b194fBehdad Esfahbod  }
154be4560a3b5e8599cbe2b29a01a60c21c9e2b194fBehdad Esfahbod};
155f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod
156be4560a3b5e8599cbe2b29a01a60c21c9e2b194fBehdad Esfahbodhb_unicode_funcs_t *
157be4560a3b5e8599cbe2b29a01a60c21c9e2b194fBehdad Esfahbodhb_unicode_funcs_get_empty (void)
158be4560a3b5e8599cbe2b29a01a60c21c9e2b194fBehdad Esfahbod{
159f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod  return const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil);
16080a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbod}
16180a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbod
16280a6833b032bc63b4e8c3da6489d3767af1168f3Behdad Esfahbodhb_unicode_funcs_t *
1635c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbodhb_unicode_funcs_reference (hb_unicode_funcs_t *ufuncs)
1645c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod{
16547e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod  return hb_object_reference (ufuncs);
1665c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod}
1675c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod
1685c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbodvoid
1695c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbodhb_unicode_funcs_destroy (hb_unicode_funcs_t *ufuncs)
1705c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod{
17147e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod  if (!hb_object_destroy (ufuncs)) return;
1725c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod
173891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod#define HB_UNICODE_FUNC_IMPLEMENT(name) \
1744b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod  if (ufuncs->destroy.name) ufuncs->destroy.name (ufuncs->user_data.name);
1754b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
1764b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod#undef HB_UNICODE_FUNC_IMPLEMENT
177fb194b8794898f51eb596fa4092c26606889d376Behdad Esfahbod
178c784c67a28f5b92d396eaa9529d57ef91a5cb9acBehdad Esfahbod  hb_unicode_funcs_destroy (ufuncs->parent);
1792fd0c577e322ccbf762927bc4600b3ea31db4c80Ryan Lortie
1805c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod  free (ufuncs);
1815c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod}
1825c44188455ca1b696aa24b20c3a83877dfae2fb2Behdad Esfahbod
1835fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_bool_t
1845fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_unicode_funcs_set_user_data (hb_unicode_funcs_t *ufuncs,
1855fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod			        hb_user_data_key_t *key,
1865fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod			        void *              data,
18733ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod			        hb_destroy_func_t   destroy,
18833ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod				hb_bool_t           replace)
1895fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod{
19033ccc77902660ed4b49184e5ec99f4fd0ef63175Behdad Esfahbod  return hb_object_set_user_data (ufuncs, key, data, destroy, replace);
1915fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod}
1925fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod
1935fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodvoid *
1945fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbodhb_unicode_funcs_get_user_data (hb_unicode_funcs_t *ufuncs,
1955fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod			        hb_user_data_key_t *key)
1965fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod{
1975fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod  return hb_object_get_user_data (ufuncs, key);
1985fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod}
1995fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod
2005fa849b77d49da2212825ebb1bea9145713b8449Behdad Esfahbod
201eb27ec0cef0d92740875ab5035b53acc639e5faeBehdad Esfahbodvoid
202eb27ec0cef0d92740875ab5035b53acc639e5faeBehdad Esfahbodhb_unicode_funcs_make_immutable (hb_unicode_funcs_t *ufuncs)
203eb27ec0cef0d92740875ab5035b53acc639e5faeBehdad Esfahbod{
20447e71d9661946a4ffb96026bf1d697d788414ab5Behdad Esfahbod  if (hb_object_is_inert (ufuncs))
205eb27ec0cef0d92740875ab5035b53acc639e5faeBehdad Esfahbod    return;
206eb27ec0cef0d92740875ab5035b53acc639e5faeBehdad Esfahbod
2070594a2448440208efa0acac9a5d8d52d43108289Behdad Esfahbod  ufuncs->immutable = true;
208eb27ec0cef0d92740875ab5035b53acc639e5faeBehdad Esfahbod}
209eb27ec0cef0d92740875ab5035b53acc639e5faeBehdad Esfahbod
210645f6f265b5f6fb85b3c0f59ea874d58c86e3917Behdad Esfahbodhb_bool_t
211645f6f265b5f6fb85b3c0f59ea874d58c86e3917Behdad Esfahbodhb_unicode_funcs_is_immutable (hb_unicode_funcs_t *ufuncs)
212645f6f265b5f6fb85b3c0f59ea874d58c86e3917Behdad Esfahbod{
213645f6f265b5f6fb85b3c0f59ea874d58c86e3917Behdad Esfahbod  return ufuncs->immutable;
214645f6f265b5f6fb85b3c0f59ea874d58c86e3917Behdad Esfahbod}
215645f6f265b5f6fb85b3c0f59ea874d58c86e3917Behdad Esfahbod
216fb194b8794898f51eb596fa4092c26606889d376Behdad Esfahbodhb_unicode_funcs_t *
217fb194b8794898f51eb596fa4092c26606889d376Behdad Esfahbodhb_unicode_funcs_get_parent (hb_unicode_funcs_t *ufuncs)
218fb194b8794898f51eb596fa4092c26606889d376Behdad Esfahbod{
219f06ab8a4262c759b4723614fd28f55ee77aa8466Behdad Esfahbod  return ufuncs->parent ? ufuncs->parent : hb_unicode_funcs_get_empty ();
220fb194b8794898f51eb596fa4092c26606889d376Behdad Esfahbod}
221fb194b8794898f51eb596fa4092c26606889d376Behdad Esfahbod
22204cc0a29ee1472c318c36efcd19b9c1a6657d9eaBehdad Esfahbod
223891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod#define HB_UNICODE_FUNC_IMPLEMENT(name)						\
2244b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod										\
2254b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbodvoid										\
2264b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbodhb_unicode_funcs_set_##name##_func (hb_unicode_funcs_t		   *ufuncs,	\
227c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod				    hb_unicode_##name##_func_t	    func,	\
2284b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod				    void			   *user_data,	\
2294b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod				    hb_destroy_func_t		    destroy)	\
2304b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod{										\
2314b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod  if (ufuncs->immutable)							\
2324b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod    return;									\
2334b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod										\
2344b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod  if (ufuncs->destroy.name)							\
2354b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod    ufuncs->destroy.name (ufuncs->user_data.name);				\
2364b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod										\
2374b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod  if (func) {									\
238c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod    ufuncs->func.name = func;							\
2394b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod    ufuncs->user_data.name = user_data;						\
2404b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod    ufuncs->destroy.name = destroy;						\
2414b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod  } else {									\
242c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod    ufuncs->func.name = ufuncs->parent->func.name;				\
2434b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod    ufuncs->user_data.name = ufuncs->parent->user_data.name;			\
2444b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod    ufuncs->destroy.name = NULL;						\
2454b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod  }										\
246891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod}
247891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod
248891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS
249891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod#undef HB_UNICODE_FUNC_IMPLEMENT
250891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod
251891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod
252891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod#define HB_UNICODE_FUNC_IMPLEMENT(return_type, name)				\
2534b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod										\
2544b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbodreturn_type									\
255c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbodhb_unicode_##name (hb_unicode_funcs_t *ufuncs,					\
256c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod		   hb_codepoint_t      unicode)					\
2574b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod{										\
258c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod  return ufuncs->func.name (ufuncs, unicode, ufuncs->user_data.name);		\
2594b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod}
260891c4755baae6cd59fad59d27fd8933e5f548a74Behdad Esfahbod    HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
2614b6317c4f426cfaf21e509dbf6ee6d4e0422cdacBehdad Esfahbod#undef HB_UNICODE_FUNC_IMPLEMENT
2625ceefa1d8dbd310570ea8d1c47107fe8d3dc96d9Behdad Esfahbod
263c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbodhb_bool_t
264c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbodhb_unicode_compose (hb_unicode_funcs_t *ufuncs,
265c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod		    hb_codepoint_t      a,
266c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod		    hb_codepoint_t      b,
267c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod		    hb_codepoint_t     *ab)
268c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod{
26922fdc66712464bdb02e45eed49e4be57e79b442fBehdad Esfahbod  *ab = 0;
2704c450c703f8e4618c587bcd7ef46dcc1f2c7947bBehdad Esfahbod  /* XXX, this belongs to indic normalizer. */
2714c450c703f8e4618c587bcd7ef46dcc1f2c7947bBehdad Esfahbod  if ((FLAG (hb_unicode_general_category (ufuncs, a)) &
2724c450c703f8e4618c587bcd7ef46dcc1f2c7947bBehdad Esfahbod       (FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) |
2734c450c703f8e4618c587bcd7ef46dcc1f2c7947bBehdad Esfahbod        FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) |
2744c450c703f8e4618c587bcd7ef46dcc1f2c7947bBehdad Esfahbod        FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK))))
2754c450c703f8e4618c587bcd7ef46dcc1f2c7947bBehdad Esfahbod    return false;
2764c450c703f8e4618c587bcd7ef46dcc1f2c7947bBehdad Esfahbod  /* XXX, add composition-exclusion exceptions to Indic shaper. */
2774c450c703f8e4618c587bcd7ef46dcc1f2c7947bBehdad Esfahbod  if (a == 0x09AF && b == 0x09BC) { *ab = 0x09DF; return true; }
278c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod  return ufuncs->func.compose (ufuncs, a, b, ab, ufuncs->user_data.compose);
279c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod}
280c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod
281c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbodhb_bool_t
282c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbodhb_unicode_decompose (hb_unicode_funcs_t *ufuncs,
283c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod		      hb_codepoint_t      ab,
284c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod		      hb_codepoint_t     *a,
285c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod		      hb_codepoint_t     *b)
286c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod{
287d487fff266258eb1af056e9704cfb09d04251ddcBehdad Esfahbod  /* XXX FIXME, move these to complex shapers and propagage to normalizer.*/
288d487fff266258eb1af056e9704cfb09d04251ddcBehdad Esfahbod  switch (ab) {
2892e193b240ec85cab0d4e2f8a375c5a7f0ef99985Behdad Esfahbod    case 0x0AC9  : return false;
29091cade755534c42bb826a6aefcbca8a543d94387Behdad Esfahbod
291b01d9b3d90e892341ee4463f2eda4600850b97d8Behdad Esfahbod    case 0x0931  : return false;
2928c973ebf0f59abb5ee920edd5d64e23d8e47ad75Behdad Esfahbod    case 0x0B94  : return false;
293b01d9b3d90e892341ee4463f2eda4600850b97d8Behdad Esfahbod
29491cade755534c42bb826a6aefcbca8a543d94387Behdad Esfahbod    /* These ones have Unicode decompositions, but we do it
29591cade755534c42bb826a6aefcbca8a543d94387Behdad Esfahbod     * this way to be close to what Uniscribe does. */
29691cade755534c42bb826a6aefcbca8a543d94387Behdad Esfahbod    case 0x0DDA  : *a = 0x0DD9; *b= 0x0DDA; return true;
29791cade755534c42bb826a6aefcbca8a543d94387Behdad Esfahbod    case 0x0DDC  : *a = 0x0DD9; *b= 0x0DDC; return true;
29891cade755534c42bb826a6aefcbca8a543d94387Behdad Esfahbod    case 0x0DDD  : *a = 0x0DD9; *b= 0x0DDD; return true;
29991cade755534c42bb826a6aefcbca8a543d94387Behdad Esfahbod    case 0x0DDE  : *a = 0x0DD9; *b= 0x0DDE; return true;
30091cade755534c42bb826a6aefcbca8a543d94387Behdad Esfahbod
301d487fff266258eb1af056e9704cfb09d04251ddcBehdad Esfahbod    case 0x0F77  : *a = 0x0FB2; *b= 0x0F81; return true;
302d487fff266258eb1af056e9704cfb09d04251ddcBehdad Esfahbod    case 0x0F79  : *a = 0x0FB3; *b= 0x0F81; return true;
303d487fff266258eb1af056e9704cfb09d04251ddcBehdad Esfahbod    case 0x17BE  : *a = 0x17C1; *b= 0x17BE; return true;
304d487fff266258eb1af056e9704cfb09d04251ddcBehdad Esfahbod    case 0x17BF  : *a = 0x17C1; *b= 0x17BF; return true;
305d487fff266258eb1af056e9704cfb09d04251ddcBehdad Esfahbod    case 0x17C0  : *a = 0x17C1; *b= 0x17C0; return true;
306d487fff266258eb1af056e9704cfb09d04251ddcBehdad Esfahbod    case 0x17C4  : *a = 0x17C1; *b= 0x17C4; return true;
307d487fff266258eb1af056e9704cfb09d04251ddcBehdad Esfahbod    case 0x17C5  : *a = 0x17C1; *b= 0x17C5; return true;
308d487fff266258eb1af056e9704cfb09d04251ddcBehdad Esfahbod    case 0x1925  : *a = 0x1920; *b= 0x1923; return true;
309d487fff266258eb1af056e9704cfb09d04251ddcBehdad Esfahbod    case 0x1926  : *a = 0x1920; *b= 0x1924; return true;
310d487fff266258eb1af056e9704cfb09d04251ddcBehdad Esfahbod    case 0x1B3C  : *a = 0x1B42; *b= 0x1B3C; return true;
311d487fff266258eb1af056e9704cfb09d04251ddcBehdad Esfahbod    case 0x1112E  : *a = 0x11127; *b= 0x11131; return true;
312d487fff266258eb1af056e9704cfb09d04251ddcBehdad Esfahbod    case 0x1112F  : *a = 0x11127; *b= 0x11132; return true;
313d487fff266258eb1af056e9704cfb09d04251ddcBehdad Esfahbod#if 0
314d487fff266258eb1af056e9704cfb09d04251ddcBehdad Esfahbod    case 0x0B57  : *a = 0xno decomp, -> RIGHT; return true;
315d487fff266258eb1af056e9704cfb09d04251ddcBehdad Esfahbod    case 0x1C29  : *a = 0xno decomp, -> LEFT; return true;
316d487fff266258eb1af056e9704cfb09d04251ddcBehdad Esfahbod    case 0xA9C0  : *a = 0xno decomp, -> RIGHT; return true;
317d487fff266258eb1af056e9704cfb09d04251ddcBehdad Esfahbod    case 0x111BF  : *a = 0xno decomp, -> ABOVE; return true;
318d487fff266258eb1af056e9704cfb09d04251ddcBehdad Esfahbod#endif
319d487fff266258eb1af056e9704cfb09d04251ddcBehdad Esfahbod  }
320ffd4a436f7baccb68a0c3602f94ea0246e32844fBehdad Esfahbod  *a = ab; *b = 0;
321c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod  return ufuncs->func.decompose (ufuncs, ab, a, b, ufuncs->user_data.decompose);
322c4641723fbf6532b2e80a662e15573b31276bc73Behdad Esfahbod}
3235ceefa1d8dbd310570ea8d1c47107fe8d3dc96d9Behdad Esfahbod
324378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbodunsigned int
325378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbodhb_unicode_decompose_compatibility (hb_unicode_funcs_t *ufuncs,
326378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod				    hb_codepoint_t      u,
327378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod				    hb_codepoint_t     *decomposed)
328378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod{
329378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod  unsigned int ret = ufuncs->func.decompose_compatibility (ufuncs, u,
330378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod							   decomposed,
331378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod							   ufuncs->user_data.decompose_compatibility);
332378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod  if (ret == 1 && u == decomposed[0]) {
333378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod    decomposed[0] = 0;
334378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod    return 0;
335378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod  }
336378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod
337378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod  decomposed[ret] = 0;
338378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod
339378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod  return ret;
340378d279bbf692195c4654e312dae854ab3be04cfBehdad Esfahbod}
3412db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod
3422db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod
3432db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbodunsigned int
3442db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod_hb_unicode_modified_combining_class (hb_unicode_funcs_t *ufuncs,
3452db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod				      hb_codepoint_t      unicode)
3462db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod{
3472db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod  int c = hb_unicode_combining_class (ufuncs, unicode);
3482db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod
3492db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod  if (unlikely (hb_in_range<int> (c, 27, 33)))
3502db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod  {
3512db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod    /* Modify the combining-class to suit Arabic better.  See:
3522db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     * http://unicode.org/faq/normalization.html#8
3532db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     * http://unicode.org/faq/normalization.html#9
3542db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     */
3552db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod    c = c == 33 ? 27 : c + 1;
3562db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod  }
35721fdcee00125b6e1c09f0bed3064d16ccd3a7a5dBehdad Esfahbod  else if (unlikely (hb_in_range<int> (c, 10, 26)))
3582db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod  {
3592db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod    /* The equivalent fix for Hebrew is more complex.
3602db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     *
36121fdcee00125b6e1c09f0bed3064d16ccd3a7a5dBehdad Esfahbod     * We permute the "fixed-position" classes 10-26 into the order
3622db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     * described in the SBL Hebrew manual:
3632db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     *
3642db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     * http://www.sbl-site.org/Fonts/SBLHebrewUserManual1.5x.pdf
3652db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     *
3662db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     * (as recommended by:
3672db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     *  http://forum.fontlab.com/archive-old-microsoft-volt-group/vista-and-diacritic-ordering-t6751.0.html)
3682db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     *
3692db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     * More details here:
3702db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     * https://bugzilla.mozilla.org/show_bug.cgi?id=662055
3712db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod     */
37221fdcee00125b6e1c09f0bed3064d16ccd3a7a5dBehdad Esfahbod    static const int permuted_hebrew_classes[26 - 10 + 1] = {
3732db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 10 sheva */        22,
3742db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 11 hataf segol */  15,
3752db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 12 hataf patah */  16,
3762db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 13 hataf qamats */ 17,
3772db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 14 hiriq */        23,
3782db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 15 tsere */        18,
3792db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 16 segol */        19,
3802db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 17 patah */        20,
3812db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 18 qamats */       21,
3822db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 19 holam */        14,
3832db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 20 qubuts */       24,
3842db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 21 dagesh */       12,
3852db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 22 meteg */        25,
3862db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 23 rafe */         13,
3872db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 24 shin dot */     10,
3882db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod      /* 25 sin dot */      11,
38921fdcee00125b6e1c09f0bed3064d16ccd3a7a5dBehdad Esfahbod      /* 26 point varika */ 26,
3902db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod    };
3912db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod    c = permuted_hebrew_classes[c - 10];
3922db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod  }
39342848453bf260b456b46a07f066e31b8c3aac2f1Behdad Esfahbod  else if (unlikely (unicode == 0x0E3A)) /* THAI VOWEL SIGN PHINTHU */
39442848453bf260b456b46a07f066e31b8c3aac2f1Behdad Esfahbod  {
39542848453bf260b456b46a07f066e31b8c3aac2f1Behdad Esfahbod    /* Assign 104, so it reorders after the THAI ccc=103 marks.
39642848453bf260b456b46a07f066e31b8c3aac2f1Behdad Esfahbod     * Uniscribe does this. */
39742848453bf260b456b46a07f066e31b8c3aac2f1Behdad Esfahbod    c = 104;
39842848453bf260b456b46a07f066e31b8c3aac2f1Behdad Esfahbod  }
3997afb14407e59dfeaa79c33aca1ffa60e7982e349Behdad Esfahbod  else if (unlikely (hb_in_range<hb_codepoint_t> (unicode, 0x0C55, 0x0C56)))
4007afb14407e59dfeaa79c33aca1ffa60e7982e349Behdad Esfahbod  {
4017afb14407e59dfeaa79c33aca1ffa60e7982e349Behdad Esfahbod    /* Telugu length marks.
4027afb14407e59dfeaa79c33aca1ffa60e7982e349Behdad Esfahbod     * These are the only matras in the main Indic script range that have
4037afb14407e59dfeaa79c33aca1ffa60e7982e349Behdad Esfahbod     * a non-zero ccc.  That makes them reorder with the Halant that is
4047afb14407e59dfeaa79c33aca1ffa60e7982e349Behdad Esfahbod     * ccc=9.  Just zero them, we don't need them in our Indic shaper. */
4057afb14407e59dfeaa79c33aca1ffa60e7982e349Behdad Esfahbod    c = 0;
4067afb14407e59dfeaa79c33aca1ffa60e7982e349Behdad Esfahbod  }
4072db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod
4082db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod  return c;
4092db2a566826ed4763ce69629194ec656bd48b0bdBehdad Esfahbod}
410