1 /* decomp.c - Character decomposition.
3 * Copyright (C) 1999, 2000 Tom Tromey
4 * Copyright 2000 Red Hat, Inc.
6 * The Gnome Library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License as
8 * published by the Free Software Foundation; either version 2 of the
9 * License, or (at your option) any later version.
11 * The Gnome Library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with the Gnome Library; see the file COPYING.LIB. If not,
18 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 02111-1307, USA.
23 #include "gunidecomp.h"
29 /* We cheat a bit and cast type values to (char *). We detect these
30 using the &0xff trick. */
31 #define CC(Page, Char) \
32 (((((int) (combining_class_table[Page])) & 0xff) \
33 == ((int) combining_class_table[Page])) \
34 ? ((int) combining_class_table[Page]) \
35 : (combining_class_table[Page][Char]))
37 #define COMBINING_CLASS(Char) \
38 (((Char) > (UNICODE_LAST_CHAR)) ? 0 : CC((Char) >> 8, (Char) & 0xff))
40 /* Compute the canonical ordering of a string in-place. */
42 g_unicode_canonical_ordering (gunichar *string,
52 last = COMBINING_CLASS (string[0]);
53 for (i = 0; i < len - 1; ++i)
55 int next = COMBINING_CLASS (string[i + 1]);
56 if (next != 0 && last > next)
59 /* Percolate item leftward through string. */
60 for (j = i; j > 0; --j)
63 if (COMBINING_CLASS (string[j]) <= next)
66 string[j + 1] = string[j];
70 /* We're re-entering the loop looking at the old
80 g_unicode_canonical_decomposition (gunichar ch,
88 int end = G_N_ELEMENTS (decomp_table);
91 int half = (start + end) / 2;
92 if (ch == decomp_table[half].ch)
96 /* We store as a double-nul terminated string. */
97 for (len = 0; (decomp_table[half].expansion[len]
98 || decomp_table[half].expansion[len + 1]);
102 /* We've counted twice as many bytes as there are
104 *result_len = len / 2;
105 r = malloc (len / 2 * sizeof (gunichar));
107 for (i = 0; i < len; i += 2)
109 r[i / 2] = (decomp_table[half].expansion[i] << 8
110 | decomp_table[half].expansion[i + 1]);
114 else if (ch > decomp_table[half].ch)
123 /* Not in our table. */
124 r = malloc (sizeof (gunichar));
129 /* Supposedly following the Unicode 2.1.9 table means that the
130 decompositions come out in canonical order. I haven't tested
131 this, but we rely on it here. */