]> git.sur5r.net Git - i3/i3/blob - libi3/string.c
Ensure all *.[ch] files include config.h
[i3/i3] / libi3 / string.c
1 /*
2  * vim:ts=4:sw=4:expandtab
3  *
4  * i3 - an improved dynamic tiling window manager
5  * © 2009 Michael Stapelberg and contributors (see also: LICENSE)
6  *
7  * string.c: Define an i3String type to automagically handle UTF-8/UCS-2
8  *           conversions. Some font backends need UCS-2 (X core fonts),
9  *           others want UTF-8 (Pango).
10  *
11  */
12 #include "libi3.h"
13
14 #include <stdlib.h>
15 #include <string.h>
16
17 #include <glib.h>
18
19 struct _i3String {
20     char *utf8;
21     xcb_char2b_t *ucs2;
22     size_t num_glyphs;
23     size_t num_bytes;
24     bool pango_markup;
25 };
26
27 /*
28  * Build an i3String from an UTF-8 encoded string.
29  * Returns the newly-allocated i3String.
30  *
31  */
32 i3String *i3string_from_utf8(const char *from_utf8) {
33     i3String *str = scalloc(1, sizeof(i3String));
34
35     /* Get the text */
36     str->utf8 = sstrdup(from_utf8);
37
38     /* Compute and store the length */
39     str->num_bytes = strlen(str->utf8);
40
41     return str;
42 }
43
44 /*
45  * Build an i3String from an UTF-8 encoded string in Pango markup.
46  *
47  */
48 i3String *i3string_from_markup(const char *from_markup) {
49     i3String *str = i3string_from_utf8(from_markup);
50
51     /* Set the markup flag */
52     str->pango_markup = true;
53
54     return str;
55 }
56
57 /*
58  * Build an i3String from an UTF-8 encoded string with fixed length.
59  * To be used when no proper NUL-terminaison is available.
60  * Returns the newly-allocated i3String.
61  *
62  */
63 i3String *i3string_from_utf8_with_length(const char *from_utf8, size_t num_bytes) {
64     i3String *str = scalloc(1, sizeof(i3String));
65
66     /* Copy the actual text to our i3String */
67     str->utf8 = scalloc(num_bytes + 1, 1);
68     strncpy(str->utf8, from_utf8, num_bytes);
69     str->utf8[num_bytes] = '\0';
70
71     /* Store the length */
72     str->num_bytes = num_bytes;
73
74     return str;
75 }
76
77 /*
78  * Build an i3String from an UTF-8 encoded string in Pango markup with fixed
79  * length.
80  *
81  */
82 i3String *i3string_from_markup_with_length(const char *from_markup, size_t num_bytes) {
83     i3String *str = i3string_from_utf8_with_length(from_markup, num_bytes);
84
85     /* set the markup flag */
86     str->pango_markup = true;
87
88     return str;
89 }
90
91 /*
92  * Build an i3String from an UCS-2 encoded string.
93  * Returns the newly-allocated i3String.
94  *
95  */
96 i3String *i3string_from_ucs2(const xcb_char2b_t *from_ucs2, size_t num_glyphs) {
97     i3String *str = scalloc(1, sizeof(i3String));
98
99     /* Copy the actual text to our i3String */
100     str->ucs2 = scalloc(num_glyphs, sizeof(xcb_char2b_t));
101     memcpy(str->ucs2, from_ucs2, num_glyphs * sizeof(xcb_char2b_t));
102
103     /* Store the length */
104     str->num_glyphs = num_glyphs;
105
106     str->utf8 = NULL;
107     str->num_bytes = 0;
108
109     return str;
110 }
111
112 /**
113  * Copies the given i3string.
114  * Note that this will not free the source string.
115  */
116 i3String *i3string_copy(i3String *str) {
117     i3String *copy = i3string_from_utf8(i3string_as_utf8(str));
118     copy->pango_markup = str->pango_markup;
119     return copy;
120 }
121
122 /*
123  * Free an i3String.
124  *
125  */
126 void i3string_free(i3String *str) {
127     if (str == NULL)
128         return;
129     free(str->utf8);
130     free(str->ucs2);
131     free(str);
132 }
133
134 static void i3string_ensure_utf8(i3String *str) {
135     if (str->utf8 != NULL)
136         return;
137     if ((str->utf8 = convert_ucs2_to_utf8(str->ucs2, str->num_glyphs)) != NULL)
138         str->num_bytes = strlen(str->utf8);
139 }
140
141 static void i3string_ensure_ucs2(i3String *str) {
142     if (str->ucs2 != NULL)
143         return;
144     str->ucs2 = convert_utf8_to_ucs2(str->utf8, &str->num_glyphs);
145 }
146
147 /*
148  * Returns the UTF-8 encoded version of the i3String.
149  *
150  */
151 const char *i3string_as_utf8(i3String *str) {
152     i3string_ensure_utf8(str);
153     return str->utf8;
154 }
155
156 /*
157  * Returns the UCS-2 encoded version of the i3String.
158  *
159  */
160 const xcb_char2b_t *i3string_as_ucs2(i3String *str) {
161     i3string_ensure_ucs2(str);
162     return str->ucs2;
163 }
164
165 /*
166  * Returns the number of bytes (UTF-8 encoded) in an i3String.
167  *
168  */
169 size_t i3string_get_num_bytes(i3String *str) {
170     i3string_ensure_utf8(str);
171     return str->num_bytes;
172 }
173
174 /*
175  * Whether the given i3String is in Pango markup.
176  */
177 bool i3string_is_markup(i3String *str) {
178     return str->pango_markup;
179 }
180
181 /*
182  * Set whether the i3String should use Pango markup.
183  */
184 void i3string_set_markup(i3String *str, bool pango_markup) {
185     str->pango_markup = pango_markup;
186 }
187
188 /*
189  * Escape pango markup characters in the given string.
190  */
191 i3String *i3string_escape_markup(i3String *str) {
192     const char *text = i3string_as_utf8(str);
193     char *escaped = g_markup_escape_text(text, -1);
194     i3String *result = i3string_from_utf8(escaped);
195     free(escaped);
196     return result;
197 }
198
199 /*
200  * Returns the number of glyphs in an i3String.
201  *
202  */
203 size_t i3string_get_num_glyphs(i3String *str) {
204     i3string_ensure_ucs2(str);
205     return str->num_glyphs;
206 }