]> Pileus Git - ~andy/gtk/blob - gtk/gtktexttypes.c
cf215af298b4f7f61e3ee6392e8e8a89d80f06b9
[~andy/gtk] / gtk / gtktexttypes.c
1 #include "gtktexttypes.h"
2
3
4 /*
5  * Tab array
6  */
7
8 GtkTextTabArray*
9 gtk_text_view_tab_array_new(guint size)
10 {
11   GtkTextTabArray *array;
12
13   array = g_new0(GtkTextTabArray, 1);
14
15   array->refcount = 1;
16   array->numTabs = size;
17   array->tabs = g_new0(GtkTextTab, size);
18
19   return array;
20 }
21
22 void
23 gtk_text_view_tab_array_ref(GtkTextTabArray *tab_array)
24 {
25   g_return_if_fail(tab_array != NULL);
26
27   tab_array->refcount += 1;
28 }
29
30 void
31 gtk_text_view_tab_array_unref(GtkTextTabArray *tab_array)
32 {
33   g_return_if_fail(tab_array != NULL);
34   g_return_if_fail(tab_array->refcount > 0);
35
36   tab_array->refcount -= 1;
37
38   if (tab_array->refcount == 0)
39     {
40       g_free(tab_array->tabs);
41       g_free(tab_array);
42     }
43 }
44
45 /*
46  * Unicode stubs (these are wrappers to make libunicode match the Tcl/Tk
47  * API, eventually should just use libunicode/Pango directly)
48  */
49
50 #include <unicode.h>
51
52 #if 0
53 static void
54 trigger_efence(const gchar *str, gint len)
55 {
56   gchar ch;
57   gint i = 0;
58   while (i < len)
59     {
60       ch = str[i];
61       ((gchar*)str)[i] = ch;
62       ++i;
63     }
64 }
65 #else
66 #define trigger_efence(foo,bar)
67 #endif
68
69 const GtkTextUniChar gtk_text_unknown_char = 0xFFFD;
70 const gchar gtk_text_unknown_char_utf8[] = { 0xEF, 0xBF, 0xBD, '\0' };
71
72 gint
73 gtk_text_view_num_utf_chars(const gchar *str, gint len)
74 {
75   trigger_efence(str, len);
76   return unicode_strlen(str, len);
77 }
78
79 /* FIXME we need a version of this function with error handling, so we
80    can screen incoming UTF8 for validity. */
81
82 gint
83 gtk_text_utf_to_unichar(const gchar *str, GtkTextUniChar *chPtr)
84 {
85   unicode_char_t ch;
86   gchar *end;
87
88   end = unicode_get_utf8(str, &ch);
89
90   if (end == NULL)
91     g_error("Bad UTF8, need to add some error checking so this doesn't crash the program");
92
93   *chPtr = ch;
94
95   trigger_efence(str, end - str);
96   
97   return end - str;
98 }
99
100 gchar*
101 gtk_text_utf_prev(const gchar *str, const gchar *start)
102 {
103   gchar *retval;
104
105   trigger_efence(start, str - start);
106   
107   retval = unicode_previous_utf8(start, str);
108
109   return retval;
110 }
111
112 static inline gboolean
113 inline_byte_begins_utf8_char(const gchar *byte)
114 {
115   return ((*byte & 0xC0) != 0x80);
116 }
117
118 gboolean
119 gtk_text_byte_begins_utf8_char(const gchar *byte)
120 {
121   trigger_efence(byte, 1);
122   return inline_byte_begins_utf8_char(byte);
123 }
124
125 guint
126 gtk_text_utf_to_latin1_char(const gchar *p, guchar *l1_ch)
127 {
128   guint charlen;
129   GtkTextUniChar ch;
130
131   g_assert(inline_byte_begins_utf8_char(p));
132   
133   charlen = gtk_text_utf_to_unichar(p, &ch);
134   
135   g_assert(ch != '\0');
136   
137   if (ch > 0xff)
138     *l1_ch = '?';
139   else
140     *l1_ch = ch;
141
142   return charlen;
143 }
144
145 gchar*
146 gtk_text_utf_to_latin1(const gchar *p, gint len)
147 {
148   GString *str;
149   guint i;
150   gchar *retval;
151
152   trigger_efence(p, len);
153   
154   str = g_string_new("");
155
156   i = 0;
157   while (i < len)
158     {
159       guchar ch;
160       guint charlen;
161
162       charlen = gtk_text_utf_to_latin1_char(p+i, &ch);
163       
164       g_string_append_c(str, ch);
165         
166       i += charlen;
167     }
168
169   retval = str->str;
170   g_string_free(str, FALSE);
171   
172   return retval;
173 }
174
175 static int
176 gtk_text_view_unichar_to_utf(GtkTextUniChar c, char *outbuf)
177 {
178   size_t len = 0;
179   int first;
180   int i;
181
182   if (c < 0x80)
183     {
184       first = 0;
185       len = 1;
186     }
187   else if (c < 0x800)
188     {
189       first = 0xc0;
190       len = 2;
191     }
192   else if (c < 0x10000)
193     {
194       first = 0xe0;
195       len = 3;
196     }
197    else if (c < 0x200000)
198     {
199       first = 0xf0;
200       len = 4;
201     }
202   else if (c < 0x4000000)
203     {
204       first = 0xf8;
205       len = 5;
206     }
207   else
208     {
209       first = 0xfc;
210       len = 6;
211     }
212
213   for (i = len - 1; i > 0; --i)
214     {
215       outbuf[i] = (c & 0x3f) | 0x80;
216       c >>= 6;
217     }
218   outbuf[0] = c | first;
219
220   return len;
221 }
222
223 gchar*
224 gtk_text_latin1_to_utf (const gchar *latin1, gint len)
225 {
226   gint i;
227   GString *retval;
228   gchar *str;
229   
230   retval = g_string_new("");
231
232   i = 0;
233   while (i < len)
234     {
235       gchar utf[7];
236       gint count;
237
238       count = gtk_text_view_unichar_to_utf((guchar)latin1[i], utf);
239       
240       utf[count] = '\0';
241       
242       g_string_append(retval, utf);
243
244       ++i;
245     }
246
247   str = retval->str;
248   g_string_free(retval, FALSE);
249   return str;
250 }