+struct size
+{
+ int w, h;
+};
+
+
+static struct size gui_measure(const char *text, TTF_Font *font)
+{
+ struct size size = { 0, 0 };
+ TTF_SizeUTF8(font, text, &size.w, &size.h);
+ return size;
+}
+
+static char *gui_trunc_head(const char *text,
+ const int maxwidth,
+ TTF_Font *font)
+{
+ int left, right, mid;
+ char *str = NULL;
+
+ left = 0;
+ right = strlen(text);
+
+ while (right - left > 1)
+ {
+ mid = (left + right) / 2;
+
+ str = concat_string("...", text + mid, NULL);
+
+ if (gui_measure(str, font).w <= maxwidth)
+ right = mid;
+ else
+ left = mid;
+
+ free(str);
+ }
+
+ return concat_string("...", text + right, NULL);
+}
+
+static char *gui_trunc_tail(const char *text,
+ const int maxwidth,
+ TTF_Font *font)
+{
+ int left, right, mid;
+ char *str = NULL;
+
+ left = 0;
+ right = strlen(text);
+
+ while (right - left > 1)
+ {
+ mid = (left + right) / 2;
+
+ str = malloc(mid + sizeof ("..."));
+
+ memcpy(str, text, mid);
+ memcpy(str + mid, "...", sizeof ("..."));
+
+ if (gui_measure(str, font).w <= maxwidth)
+ left = mid;
+ else
+ right = mid;
+
+ free(str);
+ }
+
+ str = malloc(left + sizeof ("..."));
+
+ memcpy(str, text, left);
+ memcpy(str + left, "...", sizeof ("..."));
+
+ return str;
+}
+
+static char *gui_truncate(const char *text,
+ const int maxwidth,
+ TTF_Font *font,
+ enum trunc trunc)
+{
+ if (gui_measure(text, font).w <= maxwidth)
+ return strdup(text);
+
+ switch (trunc)
+ {
+ case TRUNC_NONE: return strdup(text); break;
+ case TRUNC_HEAD: return gui_trunc_head(text, maxwidth, font); break;
+ case TRUNC_TAIL: return gui_trunc_tail(text, maxwidth, font); break;
+ }
+
+ return NULL;
+}
+
+/*---------------------------------------------------------------------------*/
+