15817
|
1 #include "gntutils.h"
|
|
2
|
|
3 #include <stdlib.h>
|
|
4 #include <string.h>
|
|
5
|
|
6 #include "config.h"
|
|
7
|
|
8 void gnt_util_get_text_bound(const char *text, int *width, int *height)
|
|
9 {
|
|
10 const char *s = text, *last;
|
|
11 int count = 1, max = 0;
|
|
12 int len;
|
|
13
|
|
14 /* XXX: ew ... everyone look away */
|
|
15 last = s;
|
|
16 if (s)
|
|
17 {
|
|
18 while (*s)
|
|
19 {
|
|
20 if (*s == '\n' || *s == '\r')
|
|
21 {
|
|
22 count++;
|
|
23 len = gnt_util_onscreen_width(last, s);
|
|
24 if (max < len)
|
|
25 max = len;
|
|
26 last = s + 1;
|
|
27 }
|
|
28 s = g_utf8_next_char(s);
|
|
29 }
|
|
30
|
|
31 len = gnt_util_onscreen_width(last, s);
|
|
32 if (max < len)
|
|
33 max = len;
|
|
34 }
|
|
35
|
|
36 if (height)
|
|
37 *height = count;
|
|
38 if (width)
|
|
39 *width = max + (count > 1);
|
|
40 }
|
|
41
|
|
42 int gnt_util_onscreen_width(const char *start, const char *end)
|
|
43 {
|
|
44 int width = 0;
|
|
45
|
|
46 if (end == NULL)
|
|
47 end = start + strlen(start);
|
|
48
|
|
49 while (start < end) {
|
|
50 width += g_unichar_iswide(g_utf8_get_char(start)) ? 2 : 1;
|
|
51 start = g_utf8_next_char(start);
|
|
52 }
|
|
53 return width;
|
|
54 }
|
|
55
|
|
56 const char *gnt_util_onscreen_width_to_pointer(const char *string, int len, int *w)
|
|
57 {
|
|
58 int size;
|
|
59 int width = 0;
|
|
60 const char *str = string;
|
|
61
|
|
62 if (len <= 0) {
|
|
63 len = gnt_util_onscreen_width(string, NULL);
|
|
64 }
|
|
65
|
|
66 while (width < len && *str) {
|
|
67 size = g_unichar_iswide(g_utf8_get_char(str)) ? 2 : 1;
|
|
68 if (width + size > len)
|
|
69 break;
|
|
70 str = g_utf8_next_char(str);
|
|
71 width += size;
|
|
72 }
|
|
73 if (w)
|
|
74 *w = width;
|
|
75 return str;
|
|
76 }
|
|
77
|
|
78 char *gnt_util_onscreen_fit_string(const char *string, int maxw)
|
|
79 {
|
|
80 const char *start, *end;
|
|
81 GString *str;
|
|
82
|
|
83 if (maxw <= 0)
|
|
84 maxw = getmaxx(stdscr) - 4;
|
|
85
|
|
86 start = string;
|
|
87 str = g_string_new(NULL);
|
|
88
|
|
89 while (*start) {
|
|
90 if ((end = strchr(start, '\n')) != NULL ||
|
|
91 (end = strchr(start, '\r')) != NULL) {
|
|
92 if (gnt_util_onscreen_width(start, end) > maxw)
|
|
93 end = NULL;
|
|
94 }
|
|
95 if (end == NULL)
|
|
96 end = gnt_util_onscreen_width_to_pointer(start, maxw, NULL);
|
|
97 str = g_string_append_len(str, start, end - start);
|
|
98 if (*end) {
|
|
99 str = g_string_append_c(str, '\n');
|
|
100 if (*end == '\n' || *end == '\r')
|
|
101 end++;
|
|
102 }
|
|
103 start = end;
|
|
104 }
|
|
105 return g_string_free(str, FALSE);
|
|
106 }
|
|
107
|
|
108 struct duplicate_fns
|
|
109 {
|
|
110 GDupFunc key_dup;
|
|
111 GDupFunc value_dup;
|
|
112 GHashTable *table;
|
|
113 };
|
|
114
|
|
115 static void
|
|
116 duplicate_values(gpointer key, gpointer value, gpointer data)
|
|
117 {
|
|
118 struct duplicate_fns *fns = data;
|
|
119 g_hash_table_insert(fns->table, fns->key_dup ? fns->key_dup(key) : key,
|
|
120 fns->value_dup ? fns->value_dup(value) : value);
|
|
121 }
|
|
122
|
|
123 GHashTable *g_hash_table_duplicate(GHashTable *src, GHashFunc hash,
|
|
124 GEqualFunc equal, GDestroyNotify key_d, GDestroyNotify value_d,
|
|
125 GDupFunc key_dup, GDupFunc value_dup)
|
|
126 {
|
|
127 GHashTable *dest = g_hash_table_new_full(hash, equal, key_d, value_d);
|
|
128 struct duplicate_fns fns = {key_dup, value_dup, dest};
|
|
129 g_hash_table_foreach(src, duplicate_values, &fns);
|
|
130 return dest;
|
|
131 }
|
|
132
|
|
133 gboolean gnt_boolean_handled_accumulator(GSignalInvocationHint *ihint,
|
|
134 GValue *return_accu,
|
|
135 const GValue *handler_return,
|
|
136 gpointer dummy)
|
|
137 {
|
|
138 gboolean continue_emission;
|
|
139 gboolean signal_handled;
|
|
140
|
|
141 signal_handled = g_value_get_boolean (handler_return);
|
|
142 g_value_set_boolean (return_accu, signal_handled);
|
|
143 continue_emission = !signal_handled;
|
|
144
|
|
145 return continue_emission;
|
|
146 }
|
|
147
|