9e73de10240413aa315dae16a94e27c8887ab89c
[rodin/chimara.git] / src / case.c
1 #include <gtk/gtk.h>
2 #include "glk.h"
3
4 /**
5  * glk_char_to_lower:
6  * @ch: A Latin-1 character.
7  *
8  * If @ch is an uppercase character in the Latin-1 character set, converts it
9  * to lowercase. Otherwise, leaves it unchanged.
10  *
11  * Returns: A lowercase or non-letter Latin-1 character.
12  */
13 unsigned char
14 glk_char_to_lower(unsigned char ch)
15 {
16         if( (ch >= 0x41 && ch <= 0x5A) || (ch >= 0xC0 && ch <= 0xD6) || (ch >= 0xD8 && ch <= 0xDE) )
17                 return ch + 0x20;
18         return ch;
19 }
20
21 /**
22  * glk_char_to_upper:
23  * @ch: A Latin-1 character.
24  *
25  * If @ch is a lowercase character in the Latin-1 character set, converts it to
26  * uppercase. Otherwise, leaves it unchanged.
27  *
28  * Returns: An uppercase or non-letter Latin-1 character.
29  */
30 unsigned char
31 glk_char_to_upper(unsigned char ch)
32 {
33         if( (ch >= 0x61 && ch <= 0x7A) || (ch >= 0xE0 && ch <= 0xF6) || (ch >= 0xF8 && ch <= 0xFE) )
34                 return ch - 0x20;
35         return ch;
36 }
37
38 /**
39  * glk_buffer_to_lower_case_uni:
40  * @buf: A character array in UCS-4.
41  * @len: Available length of @buf.
42  * @numchars: Number of characters in @buf.
43  *
44  * Converts the first @numchars characters of @buf to their lowercase 
45  * equivalents, if there is such a thing. These functions provide two length
46  * arguments because a string of Unicode characters may expand when its case
47  * changes. The @len argument is the available length of the buffer; @numchars
48  * is the number of characters in the buffer initially. (So @numchars must be
49  * less than or equal to @len. The contents of the buffer after @numchars do
50  * not affect the operation.)
51  *
52  * Returns: The number of characters after conversion. If this is greater than
53  * @len, the characters in the array will be safely truncated at len, but the
54  * true count will be returned. (The contents of the buffer after the returned
55  * count are undefined.)
56  */
57 glui32
58 glk_buffer_to_lower_case_uni(glui32 *buf, glui32 len, glui32 numchars)
59 {
60         g_return_val_if_fail(buf != NULL && (len > 0 || numchars > 0), 0);
61         g_return_val_if_fail(numchars <= len, 0);
62         
63         /* GLib has a function that converts _one_ UCS-4 character to _one_
64         lowercase UCS-4 character; so apparently we don't have to worry about the
65         string length changing... */
66         glui32 *ptr;
67         for(ptr = buf; ptr < buf + numchars; ptr++)
68                 *ptr = g_unichar_tolower(*ptr);
69         
70         return numchars;
71 }
72
73 /**
74  * glk_buffer_to_upper_case_uni:
75  * @buf: A character array in UCS-4.
76  * @len: Available length of @buf.
77  * @numchars: Number of characters in @buf.
78  *
79  * Converts the first @numchars characters of @buf to their uppercase 
80  * equivalents, if there is such a thing. See glk_buffer_to_lower_case_uni().
81  *
82  * Returns: The number of characters after conversion.
83  */
84 glui32
85 glk_buffer_to_upper_case_uni(glui32 *buf, glui32 len, glui32 numchars)
86 {
87         g_return_val_if_fail(buf != NULL && (len > 0 || numchars > 0), 0);
88         g_return_val_if_fail(numchars <= len, 0);
89         
90         /* GLib has a function that converts _one_ UCS-4 character to _one_
91         uppercase UCS-4 character; so apparently we don't have to worry about the
92         string length changing... */
93         glui32 *ptr;
94         for(ptr = buf; ptr < buf + numchars; ptr++)
95                 *ptr = g_unichar_toupper(*ptr);
96         
97         return numchars;
98 }
99
100 /**
101  * glk_buffer_to_title_case_uni:
102  * @buf: A character array in UCS-4.
103  * @len: Available length of @buf.
104  * @numchars: Number of characters in @buf.
105  * @lowerrest: %TRUE if the rest of @buf should be lowercased, %FALSE 
106  * otherwise.
107  *
108  * Converts the first character of @buf to uppercase, if there is such a thing.
109  * See glk_buffer_to_lower_case_uni(). If @lowerrest is %TRUE, then the
110  * remainder of @buf is lowercased.
111  *
112  * Returns: The number of characters after conversion.
113  */
114 glui32
115 glk_buffer_to_title_case_uni(glui32 *buf, glui32 len, glui32 numchars, glui32 lowerrest)
116 {
117         g_return_val_if_fail(buf != NULL && (len > 0 || numchars > 0), 0);
118         g_return_val_if_fail(numchars <= len, 0);
119         
120         /* GLib has a function that converts _one_ UCS-4 character to _one_
121         titlecase UCS-4 character; so apparently we don't have to worry about the
122         string length changing... */
123         *buf = g_unichar_totitle(*buf);
124         /* Call lowercase on the rest of the string */
125         if(lowerrest)
126                 return glk_buffer_to_lower_case_uni(buf + 1, len - 1, numchars - 1) + 1;
127         return numchars;
128 }
129