aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2014-04-19 00:04:34 -0400
committerJesse Luehrs <doy@tozt.net>2014-04-19 00:04:34 -0400
commit43db8d1e88cfb95e32f554fe3cc0004803a3fe55 (patch)
treec93e515d57ddeca3f67c5206b411da1fe2a521c0
parent399553556704a9997b07e7527d1038e6393a40d8 (diff)
downloadrunes-43db8d1e88cfb95e32f554fe3cc0004803a3fe55.tar.gz
runes-43db8d1e88cfb95e32f554fe3cc0004803a3fe55.zip
better implementation of non-ascii text drawing
-rw-r--r--display.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/display.c b/display.c
index 242b330..866a5d4 100644
--- a/display.c
+++ b/display.c
@@ -1,4 +1,5 @@
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include "runes.h"
@@ -163,10 +164,46 @@ void runes_display_show_string_ascii(RunesTerm *t, char *buf, size_t len)
}
}
+/* XXX this is gross and kind of slow, but i can't find a better way to do it.
+ * i need to be able to convert the string into clusters before laying it out,
+ * since i'm not going to be using the full layout anyway, but the only way i
+ * can see to do that is with pango_get_log_attrs, which only returns character
+ * (not byte) offsets, so i have to reparse the utf8 myself once i get the
+ * results. not ideal. */
void runes_display_show_string_utf8(RunesTerm *t, char *buf, size_t len)
{
- /* XXX */
- runes_display_show_string_ascii(t, buf, len);
+ size_t i, pos, char_len;
+ PangoLogAttr *attrs;
+
+ char_len = g_utf8_strlen(buf, len);
+ attrs = malloc(sizeof(PangoLogAttr) * (char_len + 1));
+ pango_get_log_attrs(buf, len, -1, NULL, attrs, char_len + 1);
+
+ pos = 0;
+ for (i = 1; i < char_len + 1; ++i) {
+ if (attrs[i].is_cursor_position) {
+ char *startpos;
+ size_t cluster_len;
+
+ runes_display_paint_rectangle(
+ t, t->cr, t->bgcolor, t->col, t->row, 1, 1);
+
+ startpos = g_utf8_offset_to_pointer(buf, pos);
+ cluster_len = g_utf8_offset_to_pointer(buf, i) - startpos;
+ pango_layout_set_text(t->layout, startpos, cluster_len);
+ pango_cairo_update_layout(t->cr, t->layout);
+ pango_cairo_show_layout(t->cr, t->layout);
+ if (t->col + 1 >= t->cols) {
+ runes_display_move_to(t, t->row + 1, 0);
+ }
+ else {
+ runes_display_move_to(t, t->row, t->col + 1);
+ }
+ pos = i;
+ }
+ }
+
+ free(attrs);
}
void runes_display_clear_screen(RunesTerm *t)