mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-neutrino.git
synced 2025-08-30 17:01:08 +02:00
Origin commit data
------------------
Commit: d4a5e87146
Author: Stefan Seyfried <seife@tuxbox-git.slipkontur.de>
Date: 2018-01-15 (Mon, 15 Jan 2018)
588 lines
16 KiB
C
588 lines
16 KiB
C
/* See LICENSE for licence details. */
|
|
/* function for dcs sequence */
|
|
#error must no longer be included
|
|
enum {
|
|
RGBMAX = 255,
|
|
HUEMAX = 360,
|
|
LSMAX = 100,
|
|
};
|
|
|
|
/*
|
|
static inline void split_rgb(uint32_t color, uint8_t *r, uint8_t *g, uint8_t *b)
|
|
{
|
|
*r = bit_mask[8] & (color >> 16);
|
|
*g = bit_mask[8] & (color >> 8);
|
|
*b = bit_mask[8] & (color >> 0);
|
|
}
|
|
*/
|
|
|
|
static inline int sixel_bitmap(struct terminal_t *term, struct sixel_canvas_t *sc, uint8_t bitmap)
|
|
{
|
|
int i, offset;
|
|
//uint8_t r, g, b;
|
|
|
|
logging(DEBUG, "sixel_bitmap()\nbitmap:%.2X point(%d, %d)\n",
|
|
bitmap, sc->point.x, sc->point.y);
|
|
|
|
if (sc->point.x >= term->width || sc->point.y >= term->height)
|
|
return 1;
|
|
|
|
offset = sc->point.x * BYTES_PER_PIXEL + sc->point.y * sc->line_length;
|
|
|
|
for (i = 0; i < BITS_PER_SIXEL; i++) {
|
|
if (offset >= BYTES_PER_PIXEL * term->width * term->height)
|
|
break;
|
|
|
|
if (bitmap & (0x01 << i)) {
|
|
memcpy(sc->pixmap + offset, &sc->color_table[sc->color_index], BYTES_PER_PIXEL);
|
|
/*
|
|
split_rgb(sc->color_table[sc->color_index], &r, &g, &b);
|
|
*(sc->pixmap + offset + 0) = b;
|
|
*(sc->pixmap + offset + 1) = g;
|
|
*(sc->pixmap + offset + 2) = r;
|
|
*/
|
|
}
|
|
|
|
offset += sc->line_length;
|
|
}
|
|
sc->point.x++;
|
|
|
|
if (sc->point.x > sc->width)
|
|
sc->width = sc->point.x;
|
|
|
|
return 1;
|
|
}
|
|
|
|
static inline int sixel_repeat(struct terminal_t *term, struct sixel_canvas_t *sc, char *buf)
|
|
{
|
|
int i, count;
|
|
size_t length;
|
|
char *cp, tmp[BUFSIZE];
|
|
uint8_t bitmap;
|
|
|
|
cp = buf + 1; /* skip '!' itself */
|
|
while (isdigit(*cp)) /* skip non sixel bitmap character */
|
|
cp++;
|
|
|
|
length = (cp - buf);
|
|
strncpy(tmp, buf + 1, length - 1);
|
|
*(tmp + length - 1) = '\0';
|
|
|
|
count = dec2num(tmp);
|
|
|
|
logging(DEBUG, "sixel_repeat()\nbuf:%s length:%u\ncount:%d repeat:0x%.2X\n",
|
|
tmp, (unsigned) length, count, *cp);
|
|
|
|
if ('?' <= *cp && *cp <= '~') {
|
|
bitmap = bit_mask[BITS_PER_SIXEL] & (*cp - '?');
|
|
for (i = 0; i < count; i++)
|
|
sixel_bitmap(term, sc, bitmap);
|
|
}
|
|
|
|
return length + 1;
|
|
}
|
|
|
|
static inline int sixel_attr(struct sixel_canvas_t *sc, char *buf)
|
|
{
|
|
char *cp, tmp[BUFSIZE];
|
|
size_t length;
|
|
struct parm_t parm;
|
|
|
|
cp = buf + 1;
|
|
while (isdigit(*cp) || *cp == ';') /* skip valid params */
|
|
cp++;
|
|
|
|
length = (cp - buf);
|
|
strncpy(tmp, buf + 1, length - 1);
|
|
*(tmp + length - 1) = '\0';
|
|
|
|
reset_parm(&parm);
|
|
parse_arg(tmp, &parm, ';', isdigit);
|
|
|
|
if (parm.argc >= 4) {
|
|
sc->width = dec2num(parm.argv[2]);
|
|
sc->height = dec2num(parm.argv[3]);
|
|
}
|
|
|
|
logging(DEBUG, "sixel_attr()\nbuf:%s\nwidth:%d height:%d\n",
|
|
tmp, sc->width, sc->height);
|
|
|
|
return length;
|
|
}
|
|
|
|
static inline uint32_t hue2rgb(int n1, int n2, int hue)
|
|
{
|
|
if (hue < 0)
|
|
hue += HUEMAX;
|
|
|
|
if (hue > HUEMAX)
|
|
hue -= HUEMAX;
|
|
|
|
if (hue < (HUEMAX / 6))
|
|
return (n1 + (((n2 - n1) * hue + (HUEMAX / 12)) / (HUEMAX / 6)));
|
|
if (hue < (HUEMAX / 2))
|
|
return n2;
|
|
if (hue < ((HUEMAX * 2) / 3))
|
|
return (n1 + (((n2 - n1) * (((HUEMAX * 2) / 3) - hue) + (HUEMAX / 12)) / (HUEMAX / 6)));
|
|
else
|
|
return n1;
|
|
}
|
|
|
|
static inline uint32_t hls2rgb(int hue, int lum, int sat)
|
|
{
|
|
uint32_t r, g, b;
|
|
int magic1, magic2;
|
|
|
|
if (sat == 0) {
|
|
r = g = b = (lum * RGBMAX) / LSMAX;
|
|
} else {
|
|
if (lum <= (LSMAX / 2) )
|
|
magic2 = (lum * (LSMAX + sat) + (LSMAX / 2)) / LSMAX;
|
|
else
|
|
magic2 = lum + sat - ((lum * sat) + (LSMAX / 2)) / LSMAX;
|
|
magic1 = 2 * lum - magic2;
|
|
|
|
r = (hue2rgb(magic1, magic2, hue + (HUEMAX / 3)) * RGBMAX + (LSMAX / 2)) / LSMAX;
|
|
g = (hue2rgb(magic1, magic2, hue) * RGBMAX + (LSMAX / 2)) / LSMAX;
|
|
b = (hue2rgb(magic1, magic2, hue - (HUEMAX / 3)) * RGBMAX + (LSMAX/2)) / LSMAX;
|
|
}
|
|
return (r << 16) + (g << 8) + b;
|
|
}
|
|
|
|
static inline int sixel_color(struct sixel_canvas_t *sc, char *buf)
|
|
{
|
|
char *cp, tmp[BUFSIZE];
|
|
int index, type;
|
|
size_t length;
|
|
uint16_t v1, v2, v3, r, g, b;
|
|
uint32_t color;
|
|
struct parm_t parm;
|
|
|
|
cp = buf + 1;
|
|
while (isdigit(*cp) || *cp == ';') /* skip valid params */
|
|
cp++;
|
|
|
|
length = (cp - buf);
|
|
strncpy(tmp, buf + 1, length - 1); /* skip '#' */
|
|
*(tmp + length - 1) = '\0';
|
|
|
|
reset_parm(&parm);
|
|
parse_arg(tmp, &parm, ';', isdigit);
|
|
|
|
if (parm.argc < 1)
|
|
return length;
|
|
|
|
index = dec2num(parm.argv[0]);
|
|
if (index < 0)
|
|
index = 0;
|
|
else if (index >= COLORS)
|
|
index = COLORS - 1;
|
|
|
|
logging(DEBUG, "sixel_color()\nbuf:%s length:%u\nindex:%d\n",
|
|
tmp, (unsigned) length, index);
|
|
|
|
if (parm.argc == 1) { /* select color */
|
|
sc->color_index = index;
|
|
return length;
|
|
}
|
|
|
|
if (parm.argc != 5)
|
|
return length;
|
|
|
|
type = dec2num(parm.argv[1]);
|
|
v1 = dec2num(parm.argv[2]);
|
|
v2 = dec2num(parm.argv[3]);
|
|
v3 = dec2num(parm.argv[4]);
|
|
|
|
if (type == 1) { /* HLS */
|
|
color = hls2rgb(v1, v2, v3);
|
|
} else {
|
|
r = bit_mask[8] & (0xFF * v1 / 100);
|
|
g = bit_mask[8] & (0xFF * v2 / 100);
|
|
b = bit_mask[8] & (0xFF * v3 / 100);
|
|
color = (r << 16) | (g << 8) | b;
|
|
}
|
|
|
|
logging(DEBUG, "type:%d v1:%u v2:%u v3:%u color:0x%.8X\n",
|
|
type, v1, v2, v3, color);
|
|
|
|
sc->color_table[index] = color;
|
|
|
|
return length;
|
|
}
|
|
|
|
static inline int sixel_cr(struct sixel_canvas_t *sc)
|
|
{
|
|
logging(DEBUG, "sixel_cr()\n");
|
|
|
|
sc->point.x = 0;
|
|
|
|
return 1;
|
|
}
|
|
|
|
static inline int sixel_nl(struct sixel_canvas_t *sc)
|
|
{
|
|
logging(DEBUG, "sixel_nl()\n");
|
|
|
|
/* DECGNL moves active position to left margin
|
|
and down one line of sixels:
|
|
http://odl.sysworks.biz/disk$vaxdocdec963/decw$book/d3qsaaa1.p67.decw$book */
|
|
sc->point.y += BITS_PER_SIXEL;
|
|
sc->point.x = 0;
|
|
|
|
if (sc->point.y > sc->height)
|
|
sc->height = sc->point.y;
|
|
|
|
return 1;
|
|
}
|
|
|
|
void sixel_parse_data(struct terminal_t *term, struct sixel_canvas_t *sc, char *start_buf)
|
|
{
|
|
/*
|
|
DECDLD sixel data
|
|
'$': carriage return
|
|
'-': new line
|
|
'#': color
|
|
# Pc: select color
|
|
# Pc; Pu; Px; Py; Pz
|
|
Pc : color index (0 to 255)
|
|
Pu : color coordinate system
|
|
1: HLS (0 to 360 for Hue, 0 to 100 for others)
|
|
2: RGB (0 to 100 percent) (default)
|
|
Px : Hue / Red
|
|
Py : Lightness / Green
|
|
Pz : Saturation / Blue
|
|
'"': attr
|
|
" Pan; Pad; Ph; Pv
|
|
Pan, Pad: defines aspect ratio (Pan / Pad) (ignored)
|
|
Ph, Pv : defines vertical/horizontal size of the image
|
|
'!': repeat
|
|
! Pn ch
|
|
Pn : repeat count ([0-9]+)
|
|
ch : character to repeat ('?' to '~')
|
|
sixel bitmap:
|
|
range of ? (hex 3F) to ~ (hex 7E)
|
|
? (hex 3F) represents the binary value 00 0000.
|
|
t (hex 74) represents the binary value 11 0101.
|
|
~ (hex 7E) represents the binary value 11 1111.
|
|
*/
|
|
int size = 0;
|
|
char *cp, *end_buf;
|
|
uint8_t bitmap;
|
|
|
|
cp = start_buf;
|
|
end_buf = cp + strlen(start_buf);
|
|
|
|
while (cp < end_buf) {
|
|
if (*cp == '!') {
|
|
size = sixel_repeat(term, sc, cp);
|
|
} else if (*cp == '"') {
|
|
size = sixel_attr(sc, cp);
|
|
} else if (*cp == '#') {
|
|
size = sixel_color(sc, cp);
|
|
} else if (*cp == '$') {
|
|
size = sixel_cr(sc);
|
|
} else if (*cp == '-') {
|
|
size = sixel_nl(sc);
|
|
} else if ('?' <= *cp && *cp <= '~') {
|
|
bitmap = bit_mask[BITS_PER_SIXEL] & (*cp - '?');
|
|
size = sixel_bitmap(term, sc, bitmap);
|
|
} else if (*cp == '\0') { /* end of sixel data */
|
|
break;
|
|
} else {
|
|
size = 1;
|
|
}
|
|
cp += size;
|
|
}
|
|
|
|
logging(DEBUG, "sixel_parse_data()\nwidth:%d height:%d\n", sc->width, sc->height);
|
|
}
|
|
|
|
void reset_sixel(struct sixel_canvas_t *sc, struct color_pair_t color_pair, int width, int height)
|
|
{
|
|
extern const uint32_t color_list[]; /* global */
|
|
int i;
|
|
|
|
memset(sc->pixmap, 0, BYTES_PER_PIXEL * width * height);
|
|
|
|
sc->width = 1;
|
|
sc->height = 6;
|
|
sc->point.x = 0;
|
|
sc->point.y = 0;
|
|
sc->line_length = BYTES_PER_PIXEL * width;
|
|
sc->color_index = 0;
|
|
|
|
/* 0 - 15: use vt340 or ansi color map */
|
|
/* VT340 VT340 Default Color Map
|
|
ref: http://www.vt100.net/docs/vt3xx-gp/chapter2.html#T2-3
|
|
*/
|
|
sc->color_table[0] = 0x000000; sc->color_table[8] = 0x424242;
|
|
sc->color_table[1] = 0x3333CC; sc->color_table[9] = 0x545499;
|
|
sc->color_table[2] = 0xCC2121; sc->color_table[10] = 0x994242;
|
|
sc->color_table[3] = 0x33CC33; sc->color_table[11] = 0x549954;
|
|
sc->color_table[4] = 0xCC33CC; sc->color_table[12] = 0x995499;
|
|
sc->color_table[5] = 0x33CCCC; sc->color_table[13] = 0x549999;
|
|
sc->color_table[6] = 0xCCCC33; sc->color_table[14] = 0x999954;
|
|
sc->color_table[7] = 0x878787; sc->color_table[15] = 0xCCCCCC;
|
|
|
|
/* ANSI 16color table (but unusual order corresponding vt340 color map)
|
|
sc->color_table[0] = color_list[0]; sc->color_table[8] = color_list[8];
|
|
sc->color_table[1] = color_list[4]; sc->color_table[9] = color_list[12];
|
|
sc->color_table[2] = color_list[1]; sc->color_table[10] = color_list[9];
|
|
sc->color_table[3] = color_list[2]; sc->color_table[11] = color_list[10];
|
|
sc->color_table[4] = color_list[5]; sc->color_table[12] = color_list[13];
|
|
sc->color_table[5] = color_list[6]; sc->color_table[13] = color_list[14];
|
|
sc->color_table[6] = color_list[3]; sc->color_table[14] = color_list[11];
|
|
sc->color_table[7] = color_list[7]; sc->color_table[15] = color_list[15];
|
|
*/
|
|
/* change palette 0, because its often the same color as terminal background */
|
|
sc->color_table[0] = color_list[color_pair.fg];
|
|
|
|
/* 16 - 255: use xterm 256 color palette */
|
|
/* copy 256 color map */
|
|
for (i = 16; i < COLORS; i++)
|
|
sc->color_table[i] = color_list[i];
|
|
}
|
|
|
|
void sixel_copy2cell(struct terminal_t *term, struct sixel_canvas_t *sc)
|
|
{
|
|
int y, x, h, cols, lines;
|
|
int src_offset, dst_offset;
|
|
struct cell_t *cellp;
|
|
|
|
if (sc->height > term->height)
|
|
sc->height = term->height;
|
|
|
|
cols = my_ceil(sc->width, CELL_WIDTH);
|
|
lines = my_ceil(sc->height, CELL_HEIGHT);
|
|
|
|
if (cols + term->cursor.x > term->cols)
|
|
cols -= (cols + term->cursor.x - term->cols);
|
|
|
|
for (y = 0; y < lines; y++) {
|
|
for (x = 0; x < cols; x++) {
|
|
erase_cell(term, term->cursor.y, term->cursor.x + x);
|
|
cellp = &term->cells[term->cursor.y][term->cursor.x + x];
|
|
cellp->has_pixmap = true;
|
|
for (h = 0; h < CELL_HEIGHT; h++) {
|
|
src_offset = (y * CELL_HEIGHT + h) * sc->line_length + (CELL_WIDTH * x) * BYTES_PER_PIXEL;
|
|
dst_offset = h * CELL_WIDTH * BYTES_PER_PIXEL;
|
|
if (src_offset >= BYTES_PER_PIXEL * term->width * term->height)
|
|
break;
|
|
memcpy(cellp->pixmap + dst_offset, sc->pixmap + src_offset, CELL_WIDTH * BYTES_PER_PIXEL);
|
|
}
|
|
}
|
|
move_cursor(term, 1, 0);
|
|
//set_cursor(term, term->cursor.y + 1, term->cursor.x);
|
|
}
|
|
cr(term);
|
|
}
|
|
|
|
void sixel_parse_header(struct terminal_t *term, char *start_buf)
|
|
{
|
|
/*
|
|
sixel format
|
|
DSC P1; P2; P3; q; s...s; ST
|
|
parameters
|
|
DCS: ESC(0x1B) P (0x50) (8bit C1 character not recognized)
|
|
P1 : pixel aspect ratio (force 0, 2:1) (ignored)
|
|
P2 : background mode (ignored)
|
|
0 or 2: 0 stdands for current background color (default)
|
|
1 : 0 stands for remaining current color
|
|
P3 : horizontal grid parameter (ignored)
|
|
q : final character of sixel sequence
|
|
s : see parse_sixel_data()
|
|
ST : ESC (0x1B) '\' (0x5C) or BEL (0x07)
|
|
*/
|
|
char *cp;
|
|
struct parm_t parm;
|
|
|
|
/* replace final char of sixel header by NUL '\0' */
|
|
cp = strchr(start_buf, 'q');
|
|
*cp = '\0';
|
|
|
|
logging(DEBUG, "sixel_parse_header()\nbuf:%s\n", start_buf);
|
|
|
|
/* split header by semicolon ';' */
|
|
reset_parm(&parm);
|
|
parse_arg(start_buf, &parm, ';', isdigit);
|
|
|
|
/* set canvas parameters */
|
|
reset_sixel(&term->sixel, term->color_pair, term->width, term->height);
|
|
sixel_parse_data(term, &term->sixel, cp + 1); /* skip 'q' */
|
|
sixel_copy2cell(term, &term->sixel);
|
|
}
|
|
|
|
static inline void decdld_bitmap(struct glyph_t *glyph, uint8_t bitmap, uint8_t row, uint8_t column)
|
|
{
|
|
/*
|
|
MSB LSB (glyph_t bitmap order, padding at LSB side)
|
|
-> column
|
|
sixel bit0 ->........
|
|
sixel bit1 ->........
|
|
sixel bit2 ->....@@..
|
|
sixel bit3 ->...@..@.
|
|
sixel bit4 ->...@....
|
|
sixel bit5 ->...@....
|
|
.@@@@@..
|
|
...@....
|
|
|...@....
|
|
row |...@....
|
|
v...@....
|
|
...@....
|
|
...@....
|
|
...@....
|
|
........
|
|
........
|
|
*/
|
|
int i, height_shift, width_shift;
|
|
|
|
logging(DEBUG, "bit pattern:0x%.2X\n", bitmap);
|
|
|
|
width_shift = CELL_WIDTH - 1 - column;
|
|
if (width_shift < 0)
|
|
return;
|
|
|
|
for (i = 0; i < BITS_PER_SIXEL; i++) {
|
|
if((bitmap >> i) & 0x01) {
|
|
height_shift = row * BITS_PER_SIXEL + i;
|
|
|
|
if (height_shift < CELL_HEIGHT) {
|
|
logging(DEBUG, "height_shift:%d width_shift:%d\n", height_shift, width_shift);
|
|
glyph->bitmap[height_shift] |= bit_mask[CELL_WIDTH] & (0x01 << width_shift);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static inline void init_glyph(struct glyph_t *glyph)
|
|
{
|
|
int i;
|
|
|
|
glyph->width = 1; /* drcs glyph must be HALF */
|
|
glyph->code = 0; /* this value not used: drcs call by DRCSMMv1 */
|
|
|
|
for (i = 0; i < CELL_HEIGHT; i++)
|
|
glyph->bitmap[i] = 0;
|
|
}
|
|
|
|
void decdld_parse_data(char *start_buf, int start_char, struct glyph_t *chars)
|
|
{
|
|
/*
|
|
DECDLD sixel data
|
|
';': glyph separator
|
|
'/': line feed
|
|
sixel bitmap:
|
|
range of ? (hex 3F) to ~ (hex 7E)
|
|
? (hex 3F) represents the binary value 00 0000.
|
|
t (hex 74) represents the binary value 11 0101.
|
|
~ (hex 7E) represents the binary value 11 1111.
|
|
*/
|
|
char *cp, *end_buf;
|
|
uint8_t char_num = start_char; /* start_char == 0 means SPACE(0x20) */
|
|
uint8_t bitmap, row = 0, column = 0;
|
|
|
|
init_glyph(&chars[char_num]);
|
|
cp = start_buf;
|
|
end_buf = cp + strlen(cp);
|
|
|
|
while (cp < end_buf) {
|
|
if ('?' <= *cp && *cp <= '~') { /* sixel bitmap */
|
|
logging(DEBUG, "char_num(ten):0x%.2X\n", char_num);
|
|
/* remove offset '?' and use only 6bit */
|
|
bitmap = bit_mask[BITS_PER_SIXEL] & (*cp - '?');
|
|
decdld_bitmap(&chars[char_num], bitmap, row, column);
|
|
column++;
|
|
} else if (*cp == ';') { /* next char */
|
|
row = column = 0;
|
|
char_num++;
|
|
init_glyph(&chars[char_num]);
|
|
} else if (*cp == '/') { /* sixel nl+cr */
|
|
row++;
|
|
column = 0;
|
|
} else if (*cp == '\0') { /* end of DECDLD sequence */
|
|
break;
|
|
}
|
|
cp++;
|
|
}
|
|
}
|
|
|
|
void decdld_parse_header(struct terminal_t *term, char *start_buf)
|
|
{
|
|
/*
|
|
DECDLD format
|
|
DCS Pfn; Pcn; Pe; Pcmw; Pss; Pt; Pcmh; Pcss; f Dscs Sxbp1 ; Sxbp2 ; .. .; Sxbpn ST
|
|
parameters
|
|
DCS : ESC (0x1B) 'P' (0x50) (DCS(8bit C1 code) is not supported)
|
|
Pfn : fontset (ignored)
|
|
Pcn : start char (0 means SPACE 0x20)
|
|
Pe : erase mode
|
|
0: clear selectet charset
|
|
1: clear only redefined glyph
|
|
2: clear all drcs charset
|
|
Pcmw: max cellwidth (force CELL_WEDTH defined in glyph.h)
|
|
Pss : screen size (ignored)
|
|
Pt : defines the glyph as text or full cell or sixel (force full cell mode)
|
|
(TODO: implement sixel/text mode)
|
|
Pcmh: max cellheight (force CELL_HEIGHT defined in glyph.h)
|
|
Pcss: character set size (force: 96)
|
|
0: 94 gylphs charset
|
|
1: 96 gylphs charset
|
|
f : '{' (0x7B)
|
|
Dscs: define character set
|
|
Intermediate char: SPACE (0x20) to '/' (0x2F)
|
|
final char : '0' (0x30) to '~' (0x7E)
|
|
but allow chars between '@' (0x40) and '~' (0x7E) for DRCSMMv1
|
|
(ref: https://github.com/saitoha/drcsterm/blob/master/README.rst)
|
|
Sxbp: see parse_decdld_sixel()
|
|
ST : ESC (0x1B) '\' (0x5C) or BEL (0x07)
|
|
*/
|
|
char *cp;
|
|
int start_char, erase_mode, charset;
|
|
struct parm_t parm;
|
|
|
|
/* replace final char of DECDLD header by NUL '\0' */
|
|
cp = strchr(start_buf, '{');
|
|
*cp = '\0';
|
|
|
|
logging(DEBUG, "decdld_parse_header()\nbuf:%s\n", start_buf);
|
|
|
|
/* split header by semicolon ';' */
|
|
reset_parm(&parm);
|
|
parse_arg(start_buf, &parm, ';', isdigit);
|
|
|
|
if (parm.argc != 8) /* DECDLD header must have 8 params */
|
|
return;
|
|
|
|
/* set params */
|
|
start_char = dec2num(parm.argv[1]);
|
|
erase_mode = dec2num(parm.argv[2]);
|
|
|
|
/* parse Dscs */
|
|
cp++; /* skip final char (NUL) of DECDLD header */
|
|
while (SPACE <= *cp && *cp <= '/') /* skip intermediate char */
|
|
cp++;
|
|
|
|
if (0x40 <= *cp && *cp <= 0x7E) /* final char of Dscs must be between 0x40 to 0x7E (DRCSMMv1) */
|
|
charset = *cp - 0x40;
|
|
else
|
|
charset = 0;
|
|
|
|
logging(DEBUG, "charset(ku):0x%.2X start_char:%d erase_mode:%d\n",
|
|
charset, start_char, erase_mode);
|
|
|
|
/* reset previous glyph data */
|
|
if (erase_mode < 0 || erase_mode > 2)
|
|
erase_mode = 0;
|
|
|
|
if (erase_mode == 2) /* reset all drcs charset */
|
|
memset(term->drcs, 0, sizeof(struct glyph_t) * DRCS_CHARS);
|
|
else if (erase_mode == 0) /* reset selected drcs charset */
|
|
memset(term->drcs + GLYPHS_PER_CHARSET * charset, 0, sizeof(struct glyph_t) * DRCS_CHARS);
|
|
|
|
//if (term->drcs[charset] == NULL) /* always allcate 96 chars buffer */
|
|
//term->drcs[charset] = ecalloc(GLYPH_PER_CHARSET, sizeof(struct glyph_t));
|
|
|
|
decdld_parse_data(cp + 1, start_char, term->drcs + GLYPHS_PER_CHARSET * charset); /* skip final char */
|
|
}
|