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 ((((GPOINTER_TO_INT(combining_class_table[Page])) & 0xff) \
33 == GPOINTER_TO_INT(combining_class_table[Page])) \
34 ? GPOINTER_TO_INT(combining_class_table[Page]) \
35 : (combining_class_table[Page][Char]))
37 #define COMBINING_CLASS(Char) \
38 (((Char) > (G_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. */