diff 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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/finch/libgnt/gntutils.c	Sun Mar 18 19:38:15 2007 +0000
@@ -0,0 +1,147 @@
+#include "gntutils.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "config.h"
+
+void gnt_util_get_text_bound(const char *text, int *width, int *height)
+{
+	const char *s = text, *last;
+	int count = 1, max = 0;
+	int len;
+
+	/* XXX: ew ... everyone look away */
+	last = s;
+	if (s)
+	{
+		while (*s)
+		{
+			if (*s == '\n' || *s == '\r')
+			{
+				count++;
+				len = gnt_util_onscreen_width(last, s);
+				if (max < len)
+					max = len;
+				last = s + 1;
+			}
+			s = g_utf8_next_char(s);
+		}
+
+		len = gnt_util_onscreen_width(last, s);
+		if (max < len)
+			max = len;
+	}
+
+	if (height)
+		*height = count;
+	if (width)
+		*width = max + (count > 1);
+}
+
+int gnt_util_onscreen_width(const char *start, const char *end)
+{
+	int width = 0;
+
+	if (end == NULL)
+		end = start + strlen(start);
+
+	while (start < end) {
+		width += g_unichar_iswide(g_utf8_get_char(start)) ? 2 : 1;
+		start = g_utf8_next_char(start);
+	}
+	return width;
+}
+
+const char *gnt_util_onscreen_width_to_pointer(const char *string, int len, int *w)
+{
+	int size;
+	int width = 0;
+	const char *str = string;
+
+	if (len <= 0) {
+		len = gnt_util_onscreen_width(string, NULL);
+	}
+
+	while (width < len && *str) {
+		size = g_unichar_iswide(g_utf8_get_char(str)) ? 2 : 1;
+		if (width + size > len)
+			break;
+		str = g_utf8_next_char(str);
+		width += size;
+	}
+	if (w)
+		*w = width;
+	return str;
+}
+
+char *gnt_util_onscreen_fit_string(const char *string, int maxw)
+{
+	const char *start, *end;
+	GString *str;
+
+	if (maxw <= 0)
+		maxw = getmaxx(stdscr) - 4;
+
+	start = string;
+	str = g_string_new(NULL);
+
+	while (*start) {
+		if ((end = strchr(start, '\n')) != NULL ||
+			(end = strchr(start, '\r')) != NULL) {
+			if (gnt_util_onscreen_width(start, end) > maxw)
+				end = NULL;
+		}
+		if (end == NULL)
+			end = gnt_util_onscreen_width_to_pointer(start, maxw, NULL);
+		str = g_string_append_len(str, start, end - start);
+		if (*end) {
+			str = g_string_append_c(str, '\n');
+			if (*end == '\n' || *end == '\r')
+				end++;
+		}
+		start = end;
+	}
+	return g_string_free(str, FALSE);
+}
+
+struct duplicate_fns
+{
+	GDupFunc key_dup;
+	GDupFunc value_dup;
+	GHashTable *table;
+};
+
+static void
+duplicate_values(gpointer key, gpointer value, gpointer data)
+{
+	struct duplicate_fns *fns = data;
+	g_hash_table_insert(fns->table, fns->key_dup ? fns->key_dup(key) : key,
+			fns->value_dup ? fns->value_dup(value) : value);
+}
+
+GHashTable *g_hash_table_duplicate(GHashTable *src, GHashFunc hash,
+		GEqualFunc equal, GDestroyNotify key_d, GDestroyNotify value_d,
+		GDupFunc key_dup, GDupFunc value_dup)
+{
+	GHashTable *dest = g_hash_table_new_full(hash, equal, key_d, value_d);
+	struct duplicate_fns fns = {key_dup, value_dup, dest};
+	g_hash_table_foreach(src, duplicate_values, &fns);
+	return dest;
+}
+
+gboolean gnt_boolean_handled_accumulator(GSignalInvocationHint *ihint,
+				  GValue                *return_accu,
+				  const GValue          *handler_return,
+				  gpointer               dummy)
+{
+	gboolean continue_emission;
+	gboolean signal_handled;
+
+	signal_handled = g_value_get_boolean (handler_return);
+	g_value_set_boolean (return_accu, signal_handled);
+	continue_emission = !signal_handled;
+
+	return continue_emission;
+}
+