comparison finch/libgnt/gntutils.c @ 15818:0e3a8505ebbe

renamed gaim-text to finch
author Sean Egan <seanegan@gmail.com>
date Sun, 18 Mar 2007 19:38:15 +0000
parents
children 2c81ebc7bf0b
comparison
equal deleted inserted replaced
15817:317e7613e581 15818:0e3a8505ebbe
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