[vte/wip/drawing: 5/7] drawing: Special case drawing of Block Elements characters



commit 1508b53e07a4d6c25d4151f924920df3a8c8b231
Author: Christian Persch <chpe gnome org>
Date:   Wed Aug 22 00:55:31 2012 +0200

    drawing: Special case drawing of Block Elements characters
    
    https://bugzilla.gnome.org/show_bug.cgi?id=435000

 src/vte.c     |  174 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 src/vtedraw.c |   22 +++++---
 src/vtedraw.h |    6 ++
 3 files changed, 188 insertions(+), 14 deletions(-)
---
diff --git a/src/vte.c b/src/vte.c
index 9320ba8..27d4a83 100644
--- a/src/vte.c
+++ b/src/vte.c
@@ -9280,9 +9280,13 @@ vte_terminal_determine_cursor_colors (VteTerminal *terminal,
 static gboolean
 vte_unichar_is_local_graphic(vteunistr c)
 {
+        /* Box Drawing */
 	if ((c >= 0x2500) && (c <= 0x257f)) {
 		return TRUE;
 	}
+	/* Block Elements */
+	if (c >= 0x2580 && c <= 0x259f)
+                return TRUE;
 	switch (c) {
 	case 0x23ba: /* scanline 1/9 */
 	case 0x23bb: /* scanline 3/9 */
@@ -9371,9 +9375,10 @@ vte_terminal_draw_graphic(VteTerminal *terminal, vteunistr c,
 			  gboolean bold)
 {
 	gboolean ret;
-	gint xcenter, xright, ycenter, ybottom, i;
+	gint width, xcenter, xright, ycenter, ybottom, i;
 
-	xright = x + column_width * columns;
+        width = column_width * columns;
+	xright = x + width;
 	ybottom = y + row_height;
 	xcenter = (x + xright) / 2;
 	ycenter = (y + ybottom) / 2;
@@ -9935,10 +9940,167 @@ vte_terminal_draw_graphic(VteTerminal *terminal, vteunistr c,
 					    x, y,
 					    xright - x, ybottom - y);
 		break;
-	default:
-		ret = FALSE;
-		break;
-	}
+
+        default:
+                ret = FALSE;
+                break;
+        }
+
+        if (c >= 0x2580 && c <= 0x259f) {
+        int upper_half, lower_half, left_half, right_half;
+        cairo_t *cr = _vte_draw_get_context (terminal->pvt->draw);
+
+        cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
+        _vte_draw_set_source_color_alpha (terminal->pvt->draw, &terminal->pvt->palette[fore], VTE_DRAW_OPAQUE);
+
+        // FIXME wtf!?
+        x += terminal->pvt->inner_border.left;
+        y += terminal->pvt->inner_border.top;
+
+        ret = TRUE;
+
+        upper_half = row_height / 2;
+        lower_half = row_height - upper_half;
+        left_half = width / 2;
+        right_half = width - left_half;
+
+        switch (c) {
+        case 0x2580: /* upper half block */
+                cairo_rectangle(cr, x, y, width, upper_half);
+                cairo_fill (cr);
+                break;
+        case 0x2581: /* lower one eighth block */
+        case 0x2582: /* lower one quarter block */
+        case 0x2583: /* lower three eighths block */
+        case 0x2584: /* lower half block */
+        case 0x2585: /* lower five eighths block */
+        case 0x2586: /* lower three quarters block */
+        case 0x2587: /* lower seven eighths block */
+        {
+                guint v = c - 0x2580;
+                int h, half;
+
+                if (v & 4) {
+                        half = upper_half;
+                        h = lower_half;
+                } else {
+                        half = lower_half;
+                        h = 0;
+                }
+
+                half /= 2;
+                if (v & 2) h += half;
+                half /= 2;
+                if (v & 1) h += half;
+
+                cairo_rectangle(cr, x, y + row_height - h, width, h);
+                cairo_fill (cr);
+                break;
+        }
+        case 0x2588: /* full block */
+        case 0x2589: /* left seven eighths block */
+        case 0x258a: /* left three quarters block */
+        case 0x258b: /* left five eighths block */
+        case 0x258c: /* left half block */
+        case 0x258d: /* left three eighths block */
+        case 0x258e: /* left one quarter block */
+        case 0x258f: /* left one eighth block */
+        {
+                guint v = c - 0x2588;
+                int w, half;
+
+                if (v & 4) {
+                        w = half = left_half;
+                } else {
+                        w = width;
+                        half = right_half;
+                }
+
+                half /= 2;
+                if (v & 2) w -= half;
+                half /= 2;
+                if (v & 1) w -= half;
+
+                cairo_rectangle(cr, x, y, w, row_height);
+                cairo_fill (cr);
+                break;
+        }
+        case 0x2590: /* right half block */
+                cairo_rectangle(cr, x + left_half, y, right_half, row_height);
+                cairo_fill (cr);
+                break;
+        case 0x2591: /* light shade */
+        case 0x2592: /* medium shade */
+        case 0x2593: /* dark shade */
+                cairo_set_source_rgba (cr,
+                                       terminal->pvt->palette[fore].red / 65535.,
+                                       terminal->pvt->palette[fore].green / 65535.,
+                                       terminal->pvt->palette[fore].blue / 65535.,
+                                       (c - 0x2590) / 4.);
+                cairo_rectangle(cr, x, y, width, row_height);
+                cairo_fill (cr);
+                break;
+        case 0x2594: /* upper one eighth block */
+                cairo_rectangle(cr, x, y, width, upper_half / 4);
+                cairo_fill (cr);
+                break;
+        case 0x2595: /* right one eighth block */
+                cairo_rectangle(cr, x + width - right_half / 4, y, right_half / 4, row_height);
+                cairo_fill (cr);
+                break;
+        case 0x2596: /* quadrant lower left */
+                cairo_rectangle(cr, x, y + upper_half, left_half, lower_half);
+                cairo_fill (cr);
+                break;
+        case 0x2597: /* quadrant lower right */
+                cairo_rectangle(cr, x + left_half, y + upper_half, right_half, lower_half);
+                cairo_fill (cr);
+                break;
+        case 0x2598: /* quadrant upper left */
+                cairo_rectangle(cr, x, y, left_half, upper_half);
+                cairo_fill (cr);
+                break;
+        case 0x2599: /* quadrant upper left and lower left and lower right */
+                cairo_rectangle(cr, x, y, left_half, upper_half);
+                cairo_rectangle(cr, x, y + upper_half, left_half, lower_half);
+                cairo_rectangle(cr, x + left_half, y + upper_half, right_half, lower_half);
+                cairo_fill (cr);
+                break;
+        case 0x259a: /* quadrant upper left and lower right */
+                cairo_rectangle(cr, x, y, left_half, upper_half);
+                cairo_rectangle(cr, x + left_half, y + upper_half, right_half, lower_half);
+                cairo_fill (cr);
+                break;
+        case 0x259b: /* quadrant upper left and upper right and lower left */
+                cairo_rectangle(cr, x, y, left_half, upper_half);
+                cairo_rectangle(cr, x + left_half, y, right_half, upper_half);
+                cairo_rectangle(cr, x, y + upper_half, left_half, lower_half);
+                cairo_fill (cr);
+                break;
+        case 0x259c: /* quadrant upper left and upper right and lower right */
+                cairo_rectangle(cr, x, y, left_half, upper_half);
+                cairo_rectangle(cr, x + left_half, y, right_half, upper_half);
+                cairo_rectangle(cr, x + left_half, y + upper_half, right_half, lower_half);
+                cairo_fill (cr);
+                break;
+        case 0x259d: /* quadrant upper right */
+                cairo_rectangle(cr, x + left_half, y, right_half, upper_half);
+                cairo_fill (cr);
+                break;
+        case 0x259e: /* quadrant upper right and lower left */
+                cairo_rectangle(cr, x + left_half, y, right_half, upper_half);
+                cairo_rectangle(cr, x, y + upper_half, left_half, lower_half);
+                cairo_fill (cr);
+                break;
+        case 0x259f: /* quadrant upper right and lower left and lower right */
+                cairo_rectangle(cr, x + left_half, y, right_half, upper_half);
+                cairo_rectangle(cr, x, y + upper_half, left_half, lower_half);
+                cairo_rectangle(cr, x + left_half, y + upper_half, right_half, lower_half);
+                cairo_fill (cr);
+                break;
+        }
+        }
+
 	return ret;
 }
 
diff --git a/src/vtedraw.c b/src/vtedraw.c
index ac7a060..051895a 100644
--- a/src/vtedraw.c
+++ b/src/vtedraw.c
@@ -770,6 +770,12 @@ _vte_draw_new (GtkWidget *widget)
 	return draw;
 }
 
+cairo_t *
+_vte_draw_get_context (struct _vte_draw *draw)
+{
+  return draw->cr;
+}
+
 void
 _vte_draw_free (struct _vte_draw *draw)
 {
@@ -974,12 +980,12 @@ _vte_draw_has_bold (struct _vte_draw *draw)
 	return (draw->font != draw->font_bold);
 }
 
-static void
-set_source_color_alpha (cairo_t        *cr,
-			const PangoColor *color,
-			guchar alpha)
+void
+_vte_draw_set_source_color_alpha (struct _vte_draw *draw,
+                                  const PangoColor *color,
+                                  guchar            alpha)
 {
-	cairo_set_source_rgba (cr,
+	cairo_set_source_rgba (draw->cr,
 			      color->red / 65535.,
 			      color->green / 65535.,
 			      color->blue / 65535.,
@@ -999,7 +1005,7 @@ _vte_draw_text_internal (struct _vte_draw *draw,
 
 	g_return_if_fail (font != NULL);
 
-	set_source_color_alpha (draw->cr, color, alpha);
+	_vte_draw_set_source_color_alpha (draw, color, alpha);
 	cairo_set_operator (draw->cr, CAIRO_OPERATOR_OVER);
 
 	for (i = 0; i < n_requests; i++) {
@@ -1141,7 +1147,7 @@ _vte_draw_draw_rectangle (struct _vte_draw *draw,
 
 	cairo_set_operator (draw->cr, CAIRO_OPERATOR_OVER);
 	cairo_rectangle (draw->cr, x+VTE_LINE_WIDTH/2., y+VTE_LINE_WIDTH/2., width-VTE_LINE_WIDTH, height-VTE_LINE_WIDTH);
-	set_source_color_alpha (draw->cr, color, alpha);
+	_vte_draw_set_source_color_alpha (draw, color, alpha);
 	cairo_set_line_width (draw->cr, VTE_LINE_WIDTH);
 	cairo_stroke (draw->cr);
 }
@@ -1161,6 +1167,6 @@ _vte_draw_fill_rectangle (struct _vte_draw *draw,
 
 	cairo_set_operator (draw->cr, CAIRO_OPERATOR_OVER);
 	cairo_rectangle (draw->cr, x, y, width, height);
-	set_source_color_alpha (draw->cr, color, alpha);
+	_vte_draw_set_source_color_alpha (draw, color, alpha);
 	cairo_fill (draw->cr);
 }
diff --git a/src/vtedraw.h b/src/vtedraw.h
index 4f65183..fb08b52 100644
--- a/src/vtedraw.h
+++ b/src/vtedraw.h
@@ -24,6 +24,7 @@
 
 #include <glib.h>
 #include <gtk/gtk.h>
+#include <cairo.h>
 #include "vtebg.h"
 #include "vte.h"
 #include "vteunistr.h"
@@ -64,6 +65,8 @@ struct _vte_draw_text_request {
 struct _vte_draw *_vte_draw_new(GtkWidget *widget);
 void _vte_draw_free(struct _vte_draw *draw);
 
+cairo_t *_vte_draw_get_context (struct _vte_draw *draw);
+
 /* Begin and end a drawing operation.  If anything is buffered locally, it is
    flushed to the window system when _end() is called. */
 void _vte_draw_start(struct _vte_draw *draw);
@@ -110,6 +113,9 @@ void _vte_draw_fill_rectangle(struct _vte_draw *draw,
 void _vte_draw_draw_rectangle(struct _vte_draw *draw,
 			      gint x, gint y, gint width, gint height,
 			      const PangoColor *color, guchar alpha);
+void _vte_draw_set_source_color_alpha (struct _vte_draw *draw,
+                                       const PangoColor *color,
+                                       guchar            alpha);
 
 G_END_DECLS
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]