[vte/wip/mosaic: 264/265] Revert "emulation: Remove 'separated mosaic' SGR"
- From: Christian Persch <chpe src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vte/wip/mosaic: 264/265] Revert "emulation: Remove 'separated mosaic' SGR"
- Date: Sat, 14 Nov 2020 21:47:00 +0000 (UTC)
commit 9bf650c7848562d8be046b8199371c8accd7d132
Author: Christian Persch <chpe src gnome org>
Date: Sat Nov 14 22:46:43 2020 +0100
Revert "emulation: Remove 'separated mosaic' SGR"
This reverts commit adedb9c5ef222d52c6f66e3140de4d3cd4b7bc3d.
src/attr.hh | 8 +++-
src/cell.hh | 1 +
src/minifont.cc | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/parser-sgr.hh | 2 +
src/vte.cc | 3 +-
src/vteseq.cc | 6 +++
6 files changed, 126 insertions(+), 2 deletions(-)
---
diff --git a/src/attr.hh b/src/attr.hh
index d3273afb..646d86d9 100644
--- a/src/attr.hh
+++ b/src/attr.hh
@@ -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 63b908c9..a1c6cebb 100644
--- a/src/cell.hh
+++ b/src/cell.hh
@@ -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/minifont.cc b/src/minifont.cc
index c963f42b..5d106200 100644
--- a/src/minifont.cc
+++ b/src/minifont.cc
@@ -25,6 +25,99 @@
#include "drawing-cairo.hh"
#include "minifont.hh"
+#ifdef WITH_SEPARATED_MOSAICS
+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);
+
+ /* It's not quite clear how the separated mosaics should be drawn.
+ *
+ * ITU-T T.101 Annex C, C.2.1.2, and Annex D, D.5.4, show the separation
+ * being done by blanking a line on the left and bottom parts only of each
+ * of the 3x2 blocks.
+ * The minitel specification STUM 1B, Schéma 2.7 also shows them drawn that
+ * way.
+ *
+ * On the other hand, ETS 300 706 §15.7.1, Table 47, shows the separation
+ * being done by blanking a line around all four sides of each of the
+ * 3x2 blocks.
+ * That is also how ITU-T T.100 §5.4.2.1, Figure 6, shows the separation.
+ *
+ * Each of these has its own drawbacks. The T.101 way makes the 3x2 blocks
+ * asymmetric, leaving differing amount of lit pixels for the smooth mosaics
+ * comparing a mosaic with its corresponding vertically mirrored mosaic. It
+ * keeps more lit pixels overall, which make it more suitable for low-resolution
+ * display, which is probably why minitel uses that.
+ * The ETS 300 706 way keeps symmetry, but removes even more lit pixels.
+ *
+ * Here we implement the T.101 way.
+ */
+
+ /* 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_SEPARATED_MOSAICS */
+
/* pixman data must have stride 0 mod 4 */
static unsigned char const hatching_pattern_lr_data[16] = {
0xff, 0x00, 0x00, 0x00,
@@ -184,6 +277,12 @@ Minifont::draw_graphic(DrawingContext const& context,
xright = x + width;
ybottom = y + height;
+#ifdef WITH_SEPARATED_MOSAICS
+ 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 */
@@ -1107,6 +1206,15 @@ Minifont::draw_graphic(DrawingContext const& context,
g_assert_not_reached();
}
+#ifdef WITH_SEPARATED_MOSAICS
+ 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);
}
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 deb64fc7..dc42d7b5 100644
--- a/src/vte.cc
+++ b/src/vte.cc
@@ -8817,7 +8817,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/vteseq.cc b/src/vteseq.cc
index 9826ce0f..3ae5d5e4 100644
--- a/src/vteseq.cc
+++ b/src/vteseq.cc
@@ -7425,6 +7425,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]