[vte/wip/mosaic: 2/8] draw: Implement separated mosaic graphics
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte/wip/mosaic: 2/8] draw: Implement separated mosaic graphics
- Date: Thu, 14 Nov 2019 22:09:42 +0000 (UTC)
commit 9b52b277ac9b43553c4f8f867e08ce76925a8710
Author: Christian Persch <chpe src gnome org>
Date: Thu Nov 14 23:09:22 2019 +0100
draw: Implement separated mosaic graphics
https://gitlab.gnome.org/GNOME/vte/issues/189
src/attr.hh | 10 ++++-
src/cell.hh | 3 +-
src/parser-sgr.hh | 2 +
src/vte.cc | 4 +-
src/vtedraw.cc | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
src/vtedraw.hh | 2 +
src/vteseq.cc | 6 +++
7 files changed, 128 insertions(+), 8 deletions(-)
---
diff --git a/src/attr.hh b/src/attr.hh
index 20d82bf1..646d86d9 100644
--- a/src/attr.hh
+++ b/src/attr.hh
@@ -1,5 +1,5 @@
/*
- * Copyright © 2018 Christian Persch
+ * Copyright © 2018, 2019 Christian Persch
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -85,6 +85,11 @@
#define VTE_ATTR_INVISIBLE_MASK (VTE_ATTR_MASK(VTE_ATTR_INVISIBLE_SHIFT, VTE_ATTR_INVISIBLE_BITS))
#define VTE_ATTR_INVISIBLE (1U << VTE_ATTR_INVISIBLE_SHIFT)
+#define VTE_ATTR_SEPARATED_MOSAIC_SHIFT (VTE_ATTR_INVISIBLE_SHIFT + VTE_ATTR_INVISIBLE_BITS)
+#define VTE_ATTR_SEPARATED_MOSAIC_BITS (1)
+#define VTE_ATTR_SEPARATED_MOSAIC_MASK (VTE_ATTR_MASK(VTE_ATTR_SEPARATED_MOSAIC_SHIFT,
VTE_ATTR_SEPARATED_MOSAIC_BITS))
+#define VTE_ATTR_SEPARATED_MOSAIC (1U << VTE_ATTR_SEPARATED_MOSAIC_SHIFT)
+
/* Used internally only */
#define VTE_ATTR_BOXED_SHIFT (31)
#define VTE_ATTR_BOXED_BITS (1)
@@ -99,7 +104,8 @@
VTE_ATTR_OVERLINE_MASK | \
VTE_ATTR_REVERSE_MASK | \
VTE_ATTR_BLINK_MASK | \
- VTE_ATTR_INVISIBLE_MASK)
+ VTE_ATTR_INVISIBLE_MASK | \
+ VTE_ATTR_SEPARATED_MOSAIC_MASK)
#define VTE_ATTR_NONE (0U)
#define VTE_ATTR_DEFAULT (VTE_ATTR_COLUMNS(1))
diff --git a/src/cell.hh b/src/cell.hh
index 06960862..a1c6cebb 100644
--- a/src/cell.hh
+++ b/src/cell.hh
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002 Red Hat, Inc.
- * Copyright © 2018 Christian Persch
+ * Copyright © 2018, 2019 Christian Persch
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -146,6 +146,7 @@ typedef struct _VTE_GNUC_PACKED VteCellAttr {
CELL_ATTR_BOOL(blink, BLINK)
CELL_ATTR_BOOL(dim, DIM)
CELL_ATTR_BOOL(invisible, INVISIBLE)
+ CELL_ATTR_BOOL(separated_mosaic, SEPARATED_MOSAIC)
/* ATTR_BOOL(boxed, BOXED) */
} VteCellAttr;
static_assert(sizeof (VteCellAttr) == 16, "VteCellAttr has wrong size");
diff --git a/src/parser-sgr.hh b/src/parser-sgr.hh
index c12e5ade..afa15266 100644
--- a/src/parser-sgr.hh
+++ b/src/parser-sgr.hh
@@ -40,6 +40,7 @@ SGR(SET, BACK_LEGACY_END, 47)
SGR(SET, BACK_SPEC, 48)
SGR(SET, OVERLINE, 53)
SGR(SET, DECO_SPEC, 58)
+SGR(SET, SEPARATED_MOSAIC, 71)
SGR(SET, FORE_LEGACY_BRIGHT_START, 90)
SGR(SET, FORE_LEGACY_BRIGHT_END, 97)
SGR(SET, BACK_LEGACY_BRIGHT_START, 100)
@@ -56,6 +57,7 @@ SGR(RESET, FORE, 39)
SGR(RESET, BACK, 49)
SGR(RESET, OVERLINE, 55)
SGR(RESET, DECO, 59)
+SGR(RESET, SEPARATED_MOSAIC, 72)
NGR(SET, FONT_FIRST, 10)
NGR(SET, FONT_LAST, 19)
diff --git a/src/vte.cc b/src/vte.cc
index 54e8a587..2dbf0f7f 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -8558,6 +8558,7 @@ Terminal::draw_cells(struct _vte_draw_text_request *items,
_vte_draw_text(m_draw,
items, n,
+ attr,
&fg, VTE_DRAW_OPAQUE,
_vte_draw_get_style(attr & VTE_ATTR_BOLD,
attr & VTE_ATTR_ITALIC));
@@ -9064,7 +9065,8 @@ Terminal::draw_rows(VteScreen *screen_,
VTE_ATTR_STRIKETHROUGH_MASK |
VTE_ATTR_OVERLINE_MASK |
VTE_ATTR_BLINK_MASK |
- VTE_ATTR_INVISIBLE_MASK)) || // FIXME or just simply
"attr != nattr"?
+ VTE_ATTR_INVISIBLE_MASK |
+ VTE_ATTR_SEPARATED_MOSAIC_MASK)) || // FIXME or just
simply "attr != nattr"?
fore != nfore ||
back != nback ||
deco != ndeco ||
diff --git a/src/vtedraw.cc b/src/vtedraw.cc
index f60ee412..ea9bdf84 100644
--- a/src/vtedraw.cc
+++ b/src/vtedraw.cc
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2003,2008 Red Hat, Inc.
+ * Copyright © 2019 Christian Persch
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -26,6 +27,7 @@
#include <glib.h>
#include <gtk/gtk.h>
+#include "attr.hh"
#include "bidi.hh"
#include "vtedraw.hh"
#include "vtedefines.hh"
@@ -1031,12 +1033,91 @@ _vte_draw_get_char_edges (struct _vte_draw *draw, vteunistr c, int columns, guin
*right = l + w;
}
+#ifdef WITH_UNICODE_NEXT
+
+static bool
+_vte_draw_is_separable_mosaic(vteunistr c)
+{
+ // FIXMEchpe check from T.101 which characters should be separable
+ return ((c >= 0x1fb00 && c <= 0x1fb9f)||
+ (c >= 0x25e2 && c <= 0x25e5) ||
+ (c >= 0x2580 && c <= 0x259f));
+}
+
+/* Create separated mosaic pattern.
+ * Transparent pixels will not be drawn; opaque pixels will draw that part of the
+ * mosaic onto the target surface.
+ */
+static cairo_pattern_t*
+create_mosaic_separation_pattern(int width,
+ int height,
+ int line_thickness)
+{
+ auto surface = cairo_image_surface_create(CAIRO_FORMAT_A1, width, height);
+ // or CAIRO_FORMAT_A8, whichever is better/faster?
+
+ auto cr = cairo_create(surface);
+
+ /* ITU-T T.101 Annex C, C.2.1.2, and Annex D, D.5.4, show and describe how the
+ * separated mosaics should be drawn.
+ */
+
+ /* FIXMEchpe: Check that this fulfills [T.101 Appendix IV]:
+ * "All separated and contiguous mosaics shall be uniquely presented for character
+ * field sizes greater than or equal to dx = 6/256, dy = 8/256 [see D.8.3.3, item 7)]."
+ */
+
+ /* First, fill completely with transparent pixels */
+ cairo_set_source_rgba(cr, 0., 0., 0., 0.);
+ cairo_rectangle(cr, 0, 0, width, height);
+ cairo_fill(cr);
+
+ /* Now, fill the reduced blocks with opaque pixels */
+
+ auto const pel = line_thickness; /* see T.101 D.5.3.2.2.6 for definition of 'logical pel' */
+
+ if (width > 2 * pel && height > 3 * pel) {
+
+ auto const width_half = width / 2;
+ auto const height_thirds = height / 3;
+ auto const remaining_height = height - 3 * height_thirds;
+
+ int const y[4] = { 0, height_thirds, 2 * height_thirds + (remaining_height ? 1 : 0), height
};
+ int const x[3] = { 0, width_half, width };
+ // FIXMEchpe: or use 2 * width_half instead of width, so that for width odd,
+ // the extra row of pixels is unlit, and the lit blocks have equal width?
+
+ cairo_set_source_rgba(cr, 0., 0., 0., 1.);
+ for (auto yi = 0; yi < 3; ++yi) {
+ for (auto xi = 0; xi < 2; xi++) {
+ cairo_rectangle(cr, x[xi] + pel, y[yi], x[xi+1] - x[xi] - pel, y[yi+1] -
y[yi] - pel);
+ cairo_fill(cr);
+ }
+ }
+ }
+
+ cairo_destroy(cr);
+
+ auto pattern = cairo_pattern_create_for_surface(surface);
+ cairo_surface_destroy(surface);
+
+ cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);
+ cairo_pattern_set_filter(pattern, CAIRO_FILTER_NEAREST);
+
+ return pattern;
+}
+
+#endif /* WITH_UNICODE_NEXT */
+
#include "box_drawing.h"
/* Draw the graphic representation of a line-drawing or special graphics
* character. */
static void
-_vte_draw_terminal_draw_graphic(struct _vte_draw *draw, vteunistr c, vte::color::rgb const* fg,
+_vte_draw_terminal_draw_graphic(struct _vte_draw *draw,
+ vteunistr c,
+ uint32_t attr,
+ vte::color::rgb const* fg,
gint x, gint y,
gint font_width, gint columns, gint font_height)
{
@@ -1094,6 +1175,12 @@ _vte_draw_terminal_draw_graphic(struct _vte_draw *draw, vteunistr c, vte::color:
xright = x + width;
ybottom = y + height;
+#ifdef WITH_UNICODE_NEXT
+ auto const separated = vte_attr_get_bool(attr, VTE_ATTR_SEPARATED_MOSAIC_SHIFT)
&&_vte_draw_is_separable_mosaic(c);
+ if (separated)
+ cairo_push_group(cr);
+#endif
+
switch (c) {
/* Box Drawing */
@@ -2006,12 +2093,22 @@ _vte_draw_terminal_draw_graphic(struct _vte_draw *draw, vteunistr c, vte::color:
#undef RECTANGLE
#undef POLYGON
+#ifdef WITH_UNICODE_NEXT
+ if (separated) {
+ cairo_pop_group_to_source(cr);
+ auto pattern = create_mosaic_separation_pattern(width, height, light_line_width);
+ cairo_mask(cr, pattern);
+ cairo_pattern_destroy(pattern);
+ }
+#endif
+
cairo_restore(cr);
}
static void
_vte_draw_text_internal (struct _vte_draw *draw,
struct _vte_draw_text_request *requests, gsize n_requests,
+ uint32_t attr,
vte::color::rgb const* color, double alpha, guint style)
{
gsize i;
@@ -2034,7 +2131,9 @@ _vte_draw_text_internal (struct _vte_draw *draw,
}
if (_vte_draw_unichar_is_local_graphic(c)) {
- _vte_draw_terminal_draw_graphic(draw, c, color,
+ _vte_draw_terminal_draw_graphic(draw, c,
+ attr,
+ color,
requests[i].x, requests[i].y,
font->width, requests[i].columns, font->height);
continue;
@@ -2096,6 +2195,7 @@ _vte_draw_text_internal (struct _vte_draw *draw,
void
_vte_draw_text (struct _vte_draw *draw,
struct _vte_draw_text_request *requests, gsize n_requests,
+ uint32_t attr,
vte::color::rgb const* color, double alpha, guint style)
{
g_assert(draw->cr);
@@ -2115,7 +2215,7 @@ _vte_draw_text (struct _vte_draw *draw,
g_free (str);
}
- _vte_draw_text_internal (draw, requests, n_requests, color, alpha, style);
+ _vte_draw_text_internal (draw, requests, n_requests, attr, color, alpha, style);
}
/* The following two functions are unused since commit 154abade902850afb44115cccf8fcac51fc082f0,
@@ -2139,6 +2239,7 @@ _vte_draw_has_char (struct _vte_draw *draw, vteunistr c, guint style)
gboolean
_vte_draw_char (struct _vte_draw *draw,
struct _vte_draw_text_request *request,
+ uint32_t attr,
vte::color::rgb const* color, double alpha, guint style)
{
gboolean has_char;
@@ -2153,7 +2254,7 @@ _vte_draw_char (struct _vte_draw *draw,
has_char =_vte_draw_has_char (draw, request->c, style);
if (has_char)
- _vte_draw_text (draw, request, 1, color, alpha, style);
+ _vte_draw_text (draw, request, 1, attr, color, alpha, style);
return has_char;
}
diff --git a/src/vtedraw.hh b/src/vtedraw.hh
index 0797b564..dc64b84d 100644
--- a/src/vtedraw.hh
+++ b/src/vtedraw.hh
@@ -79,9 +79,11 @@ void _vte_draw_get_char_edges (struct _vte_draw *draw, vteunistr c, int columns,
void _vte_draw_text(struct _vte_draw *draw,
struct _vte_draw_text_request *requests, gsize n_requests,
+ uint32_t attr,
vte::color::rgb const* color, double alpha, guint style);
gboolean _vte_draw_char(struct _vte_draw *draw,
struct _vte_draw_text_request *request,
+ uint32_t attr,
vte::color::rgb const* color, double alpha, guint style);
gboolean _vte_draw_has_char(struct _vte_draw *draw, vteunistr c, guint style);
diff --git a/src/vteseq.cc b/src/vteseq.cc
index 10cbfdf8..d5562436 100644
--- a/src/vteseq.cc
+++ b/src/vteseq.cc
@@ -7257,6 +7257,12 @@ Terminal::SGR(vte::parser::Sequence const& seq)
m_defaults.attr.set_deco(deco);
break;
}
+ case VTE_SGR_SET_SEPARATED_MOSAIC:
+ m_defaults.attr.set_separated_mosaic(true);
+ break;
+ case VTE_SGR_RESET_SEPARATED_MOSAIC:
+ m_defaults.attr.set_separated_mosaic(false);
+ break;
case VTE_SGR_RESET_DECO:
/* default decoration color, that is, same as the cell's foreground */
m_defaults.attr.set_deco(VTE_DEFAULT_FG);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]