--- a/window-copy.c
+++ b/window-copy.c
@@ -908,24 +908,16 @@
     struct grid *gd, u_int px, u_int py, struct grid *sgd, u_int spx)
 {
 	const struct grid_cell	*gc, *sgc;
-	const struct grid_utf8	*gu, *sgu;
+	struct utf8_data	 ud, sud;
 
 	gc = grid_peek_cell(gd, px, py);
+	grid_cell_get(gc, &ud);
 	sgc = grid_peek_cell(sgd, spx, 0);
-
-	if ((gc->flags & GRID_FLAG_UTF8) != (sgc->flags & GRID_FLAG_UTF8))
+	grid_cell_get(sgc, &sud);
+
+	if (ud.size != sud.size || ud.width != sud.width)
 		return (0);
-
-	if (gc->flags & GRID_FLAG_UTF8) {
-		gu = grid_peek_utf8(gd, px, py);
-		sgu = grid_peek_utf8(sgd, spx, 0);
-		if (grid_utf8_compare(gu, sgu))
-			return (1);
-	} else {
-		if (gc->data == sgc->data)
-			return (1);
-	}
-	return (0);
+	return (memcmp(ud.data, sud.data, ud.size) == 0);
 }
 
 int
@@ -1395,10 +1387,9 @@
 	struct window_copy_mode_data	*data = wp->modedata;
 	struct grid			*gd = data->backing->grid;
 	const struct grid_cell		*gc;
-	const struct grid_utf8		*gu;
 	struct grid_line		*gl;
+	struct utf8_data		 ud;
 	u_int				 i, xx, wrapped = 0;
-	size_t				 size;
 
 	if (sx > ex)
 		return;
@@ -1426,15 +1417,11 @@
 			gc = grid_peek_cell(gd, i, sy);
 			if (gc->flags & GRID_FLAG_PADDING)
 				continue;
-			if (!(gc->flags & GRID_FLAG_UTF8)) {
-				*buf = xrealloc(*buf, 1, (*off) + 1);
-				(*buf)[(*off)++] = gc->data;
-			} else {
-				gu = grid_peek_utf8(gd, i, sy);
-				size = grid_utf8_size(gu);
-				*buf = xrealloc(*buf, 1, (*off) + size);
-				*off += grid_utf8_copy(gu, *buf + *off, size);
-			}
+			grid_cell_get(gc, &ud);
+
+			*buf = xrealloc(*buf, 1, (*off) + ud.size);
+			memcpy(*buf + *off, ud.data, ud.size);
+			*off += ud.size;
 		}
 	}
 
@@ -1464,13 +1451,15 @@
 {
 	struct window_copy_mode_data	*data = wp->modedata;
 	const struct grid_cell		*gc;
+	struct utf8_data		 ud;
 
 	gc = grid_peek_cell(data->backing->grid, px, py);
-	if (gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8))
+	grid_cell_get(gc, &ud);
+	if (ud.size != 1 || gc->flags & GRID_FLAG_PADDING)
 		return (0);
-	if (gc->data == 0x00 || gc->data == 0x7f)
+	if (*ud.data == 0x00 || *ud.data == 0x7f)
 		return (0);
-	return (strchr(set, gc->data) != NULL);
+	return (strchr(set, *ud.data) != NULL);
 }
 
 u_int
@@ -1479,6 +1468,7 @@
 	struct window_copy_mode_data	*data = wp->modedata;
 	struct screen			*s = data->backing;
 	const struct grid_cell		*gc;
+	struct utf8_data		 ud;
 	u_int				 px;
 
 	/*
@@ -1492,9 +1482,8 @@
 		px = screen_size_x(s);
 	while (px > 0) {
 		gc = grid_peek_cell(s->grid, px - 1, py);
-		if (gc->flags & GRID_FLAG_UTF8)
-			break;
-		if (gc->data != ' ')
+		grid_cell_get(gc, &ud);
+		if (ud.size != 1 || *ud.data != ' ')
 			break;
 		px--;
 	}
@@ -1527,6 +1516,7 @@
 	struct window_copy_mode_data	*data = wp->modedata;
 	u_int				 px, py, xx;
 	const struct grid_cell		*gc;
+	struct utf8_data		 ud;
 
 	px = 0;
 	py = screen_hsize(data->backing) + data->cy - data->oy;
@@ -1534,9 +1524,8 @@
 
 	while (px < xx) {
 		gc = grid_peek_cell(data->backing->grid, px, py);
-		if (gc->flags & GRID_FLAG_UTF8)
-			break;
-		if (gc->data != ' ')
+		grid_cell_get(gc, &ud);
+		if (ud.size != 1 || *ud.data != ' ')
 			break;
 		px++;
 	}
@@ -1696,6 +1685,7 @@
 	struct window_copy_mode_data	*data = wp->modedata;
 	struct screen			*back_s = data->backing;
 	const struct grid_cell		*gc;
+	struct utf8_data		 ud;
 	u_int				 px, py, xx;
 
 	px = data->cx + 1;
@@ -1704,9 +1694,9 @@
 
 	while (px < xx) {
 		gc = grid_peek_cell(back_s->grid, px, py);
-		if ((gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8)) == 0
-		    && gc->data == data->jumpchar) {
-
+		grid_cell_get(gc, &ud);
+		if (!(gc->flags & GRID_FLAG_PADDING) &&
+		    ud.size == 1 && *ud.data == data->jumpchar) {
 			window_copy_update_cursor(wp, px, data->cy);
 			if (window_copy_update_selection(wp))
 				window_copy_redraw_lines(wp, data->cy, 1);
@@ -1722,6 +1712,7 @@
 	struct window_copy_mode_data	*data = wp->modedata;
 	struct screen			*back_s = data->backing;
 	const struct grid_cell		*gc;
+	struct utf8_data		 ud;
 	u_int				 px, py;
 
 	px = data->cx;
@@ -1732,9 +1723,9 @@
 
 	for (;;) {
 		gc = grid_peek_cell(back_s->grid, px, py);
-		if ((gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8)) == 0
-		    && gc->data == data->jumpchar) {
-
+		grid_cell_get(gc, &ud);
+		if (!(gc->flags & GRID_FLAG_PADDING) &&
+		    ud.size == 1 && *ud.data == data->jumpchar) {
 			window_copy_update_cursor(wp, px, data->cy);
 			if (window_copy_update_selection(wp))
 				window_copy_redraw_lines(wp, data->cy, 1);
@@ -1752,6 +1743,7 @@
 	struct window_copy_mode_data	*data = wp->modedata;
 	struct screen			*back_s = data->backing;
 	const struct grid_cell		*gc;
+	struct utf8_data		 ud;
 	u_int				 px, py, xx;
 
 	px = data->cx + 1;
@@ -1760,9 +1752,9 @@
 
 	while (px < xx) {
 		gc = grid_peek_cell(back_s->grid, px, py);
-		if ((gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8)) == 0
-		    && gc->data == data->jumpchar) {
-
+		grid_cell_get(gc, &ud);
+		if (!(gc->flags & GRID_FLAG_PADDING) &&
+		    ud.size == 1 && *ud.data == data->jumpchar) {
 			window_copy_update_cursor(wp, px - 1, data->cy);
 			if (window_copy_update_selection(wp))
 				window_copy_redraw_lines(wp, data->cy, 1);
@@ -1778,6 +1770,7 @@
 	struct window_copy_mode_data	*data = wp->modedata;
 	struct screen			*back_s = data->backing;
 	const struct grid_cell		*gc;
+	struct utf8_data		 ud;
 	u_int				 px, py;
 
 	px = data->cx;
@@ -1788,9 +1781,9 @@
 
 	for (;;) {
 		gc = grid_peek_cell(back_s->grid, px, py);
-		if ((gc->flags & (GRID_FLAG_PADDING|GRID_FLAG_UTF8)) == 0
-		    && gc->data == data->jumpchar) {
-
+		grid_cell_get(gc, &ud);
+		if (!(gc->flags & GRID_FLAG_PADDING) &&
+		    ud.size == 1 && *ud.data == data->jumpchar) {
 			window_copy_update_cursor(wp, px + 1, data->cy);
 			if (window_copy_update_selection(wp))
 				window_copy_redraw_lines(wp, data->cy, 1);