Rationalise mosaic graphics implementation

The "separated graphics" flag is now in the "flags" field, rather than
in the character data, and the bits specifying which cells are painted
are now contiguous.  Also the MOS flag is now called MOS6, to go with
MOS4.  This makes the specification of the ZVBI code points more
complex, but cleans up the Unicode ones, which I think is appropriate.

On the way, I found that 'palt' was being applied to 4-cell mosaic
graphics and fixed that.
This commit is contained in:
Ben Harris 2020-03-28 22:13:41 +00:00
parent eb3418be04
commit b779a48d68

View File

@ -230,8 +230,11 @@ static struct glyph {
int unicode;
char const *name;
unsigned int flags;
#define MOS 0x02 /* Mosaic graphics character */
#define SEP 0x01 /* Separated graphics */
#define MOS6 0x02 /* 6-cell mosaic graphics character */
#define MOS4 0x04 /* 4-cell mosaic graphics character */
#define SEP6 (SEP | MOS6)
#define SEP4 (SEP | MOS4)
char const *alias_of;
} const glyphs[] = {
/*
@ -1434,18 +1437,18 @@ static struct glyph {
{{012,012,012,033,000,033,012,012,012}, 0x256c, "SF440000" },
/* Block elements */
{{0x03}, 0x2580, "upblock", MOS4 }, {{0x23}, -1, "upblock.sep4", MOS4 },
{{0x0c}, 0x2584, "dnblock", MOS4 }, {{0x2c}, -1, "dnblock.sep4", MOS4 },
{{0x0f}, 0x2588, "block", MOS4 }, {{0x2f}, -1, "block.sep4", MOS4 },
{{0x7f}, -1, "block.sep6", MOS },
{{0x05}, 0x258c, "lfblock", MOS4 }, {{0x25}, -1, "lfblock.sep4", MOS4 },
{{0x35}, -1, "lfblock.sep6", MOS },
{{0x0a}, 0x2590, "rtblock", MOS4 }, {{0x2a}, -1, "rtblock.sep4", MOS4 },
{{0x6a}, -1, "rtblock.sep6", MOS },
{{0x03}, 0x2580, "upblock", MOS4 }, {{0x03}, -1, "upblock.sep4", SEP4 },
{{0x0c}, 0x2584, "dnblock", MOS4 }, {{0x0c}, -1, "dnblock.sep4", SEP4 },
{{0x0f}, 0x2588, "block", MOS4 }, {{0x0f}, -1, "block.sep4", SEP4 },
{{0x3f}, -1, "block.sep6", SEP6 },
{{0x05}, 0x258c, "lfblock", MOS4 }, {{0x05}, -1, "lfblock.sep4", SEP4 },
{{0x15}, -1, "lfblock.sep6", SEP6 },
{{0x0a}, 0x2590, "rtblock", MOS4 }, {{0x0a}, -1, "rtblock.sep4", SEP4 },
{{0x2a}, -1, "rtblock.sep6", SEP6 },
{{025,000,012,000,025,000,012,000,025}, 0x2591, "ltshade" },
{{022,011,004,022,011,004,022,011,004}, 0x2592, "shade" },
{{025,037,012,037,025,037,012,037,025}, 0x2593, "dkshade" },
#define M(x, u) { {(x)}, U(u), MOS }, { {(x)|0x20}, -1, "uni" #u ".sep4", MOS4 }
#define M(x, u) { {x}, U(u), MOS6 }, { {x}, -1, "uni" #u ".sep4", SEP4 }
M( 4, 2596), M( 8, 2597), M( 1, 2598), M(13, 2599),
M( 9, 259A), M( 7, 259B), M(11, 259C), M( 2, 259D),
M( 6, 259E), M(14, 259F),
@ -1550,7 +1553,8 @@ static struct glyph {
{{000,000,016,021,025,022,015,000,000}, U(A7AF) }, /* small cap Q */
/* Private use */
/* U+EE00--U+EE7F: zvbi mosaic graphics */
#define M(x) {{0x##x}, U(EE##x), MOS}
#define M(x) {{(0x##x & 0x1f)|((0x##x & 0x40)>>1)}, U(EE##x), \
(0x##x & 0x20 ? SEP6 : MOS6)}
M(00), M(01), M(02), M(03), M(04), M(05), M(06), M(07),
M(08), M(09), M(0A), M(0B), M(0C), M(0D), M(0E), M(0F),
M(10), M(11), M(12), M(13), M(14), M(15), M(16), M(17),
@ -1633,7 +1637,7 @@ static struct glyph {
{{000,007,017,027,037,011,000,000,000}, U(1F69A) }, /* deliverytruck */
/* Graphics for legacy computing */
#define M(x, u) { {(x)}, U(u), MOS }, { {(x)|0x20}, -1, "uni" #u ".sep6", MOS }
#define M(x, u) { {x}, U(u), MOS6 }, { {x}, -1, "uni" #u ".sep6", SEP6 }
/* space */ M(0x01, 1FB00), M(0x02, 1FB01), M(0x03, 1FB02),
M(0x04, 1FB03), M(0x05, 1FB04), M(0x06, 1FB05), M(0x07, 1FB06),
M(0x08, 1FB07), M(0x09, 1FB08), M(0x0a, 1FB09), M(0x0b, 1FB0A),
@ -1642,14 +1646,14 @@ static struct glyph {
M(0x14, 1FB13), /* lfblock */ M(0x16, 1FB14), M(0x17, 1FB15),
M(0x18, 1FB16), M(0x19, 1FB17), M(0x1a, 1FB18), M(0x1b, 1FB19),
M(0x1c, 1FB1A), M(0x1d, 1FB1B), M(0x1e, 1FB1C), M(0x1f, 1FB1D),
M(0x40, 1FB1E), M(0x41, 1FB1F), M(0x42, 1FB20), M(0x43, 1FB21),
M(0x44, 1FB22), M(0x45, 1FB23), M(0x46, 1FB24), M(0x47, 1FB25),
M(0x48, 1FB26), M(0x49, 1FB27), /* rtblock */ M(0x4b, 1FB28),
M(0x4c, 1FB29), M(0x4d, 1FB2A), M(0x4e, 1FB2B), M(0x4f, 1FB2C),
M(0x50, 1FB2D), M(0x51, 1FB2E), M(0x52, 1FB2F), M(0x53, 1FB30),
M(0x54, 1FB31), M(0x55, 1FB32), M(0x56, 1FB33), M(0x57, 1FB34),
M(0x58, 1FB35), M(0x59, 1FB36), M(0x5a, 1FB37), M(0x5b, 1FB38),
M(0x5c, 1FB39), M(0x5d, 1FB3A), M(0x5e, 1FB3B), /* block */
M(0x20, 1FB1E), M(0x21, 1FB1F), M(0x22, 1FB20), M(0x23, 1FB21),
M(0x24, 1FB22), M(0x25, 1FB23), M(0x26, 1FB24), M(0x27, 1FB25),
M(0x28, 1FB26), M(0x29, 1FB27), /* rtblock */ M(0x2b, 1FB28),
M(0x2c, 1FB29), M(0x2d, 1FB2A), M(0x2e, 1FB2B), M(0x2f, 1FB2C),
M(0x30, 1FB2D), M(0x31, 1FB2E), M(0x32, 1FB2F), M(0x33, 1FB30),
M(0x34, 1FB31), M(0x35, 1FB32), M(0x36, 1FB33), M(0x37, 1FB34),
M(0x38, 1FB35), M(0x39, 1FB36), M(0x3a, 1FB37), M(0x3b, 1FB38),
M(0x3c, 1FB39), M(0x3d, 1FB3A), M(0x3e, 1FB3B), /* block */
#undef M
{{030,024,022,021,027,030,000,000,000}, U(1FBB0) }, /* arrowheadptr */
{{000,012,033,000,033,012,000,000,000}, U(1FBBB) }, /* voided Greek cross */
@ -1949,7 +1953,7 @@ main(int argc, char **argv)
glyphs[i].unicode != -1 ? glyphs[i].unicode :
0x110000 + extraglyphs++, glyphs[i].unicode, i);
printf("Width: %g\n", (double)(XSIZE * XPIX));
if (glyphs[i].flags & (MOS|MOS4))
if (glyphs[i].flags & (MOS6|MOS4))
printf("Flags: W\n");
else
printf("Flags: HW\n");
@ -1957,12 +1961,12 @@ main(int argc, char **argv)
dolookups(&glyphs[i]);
if (glyphs[i].alias_of != NULL)
doalias(glyphs[i].alias_of);
else if (glyphs[i].flags & MOS)
else if (glyphs[i].flags & MOS6)
domosaic(glyphs[i].data[0],
(glyphs[i].data[0] & 0x20) != 0);
(glyphs[i].flags & SEP) != 0);
else if (glyphs[i].flags & MOS4)
domosaic4(glyphs[i].data[0],
(glyphs[i].data[0] & 0x20) != 0);
(glyphs[i].flags & SEP) != 0);
else {
if (plottermode)
dochar_plotter(glyphs[i].data, glyphs[i].flags);
@ -2096,7 +2100,7 @@ dopalt(struct glyph const *g)
while (g->alias_of != NULL)
g = get_glyph_by_name(g->alias_of);
if (g->flags & MOS) return;
if (g->flags & (MOS6|MOS4)) return;
/*
* For proportional layout, we'd like a left side-bearing of
* one pixel, and a right side-bearing of zero. Space
@ -2673,7 +2677,7 @@ domosaic(unsigned code, bool sep)
if (code & 4) tile(0 + sep, 4 + sep, 3, 8);
if (code & 8) tile(3 + sep, 4 + sep, 6, 8);
if (code & 16) tile(0 + sep, 1 + sep, 3, 4);
if (code & 64) tile(3 + sep, 1 + sep, 6, 4);
if (code & 32) tile(3 + sep, 1 + sep, 6, 4);
clean_path();
emit_path();
}