#include #include #include #include #include #include #include #include #include #include #define HEAD_s 4 /* rows, columns, x, y of the screen */ #define height 16 #define row_size 160 #define rows 25 char y [512][32], *m, /* our yield :) and the matrix of mapped font*/ s [HEAD_s + 4002], /* 25x80 + attributes */ os [HEAD_s + 4000],/* 25x80 + attributes */ partial = 1, greed = 0; unsigned char pl [rows];/* previous length, when it can't be reached the left should be erased */ short r = 0; /* remaining length of an incomplete page */ char compose (FILE* d) { unsigned char x, x2, *p = s+HEAD_s, *e = s+sizeof(s), n; /* the next seat to sit */ char allused = 0, intensified = 0, row = 0, * f = y [0], #define QUANTITY 8*1024 seats [QUANTITY] = { [0 ... QUANTITY-1] = 0 }; #define INTENSIFIED 0x8000 short attrs [QUANTITY] = { [0 ... QUANTITY-1] = 0 }; if (greed) n = 34; else n = 128; if (partial) { #define MENDING 0x8000 #define MENDED 0x8000 if (r && !(r & MENDING)) { while (p < e - r) { *p++ = 0; } row = rows - r/row_size; r |= MENDING; } else if (r && (r & MENDED)) { r &= ~MENDING; for (row = rows - r/row_size; row < rows; pl [row++] = 0); row = 0; e -= r; while (r) { *e++ = 0; r--; } } } repeat: if (p >= e) goto eox; x = getc (d); while (x < 0x20 && x != '\n' && x != '\t') x = getc (d); if (x == '\n') goto eox; if (x == '\t') { x = ((void*)p - (void*)s - HEAD_s) % row_size / 2; x++; *p++ = ' '; *p++ = 7; while (x++ % 8) { *p++ = ' '; *p++ = 7; } goto repeat; } if ((x < 0xA1) || (x > 0xF7 && x != (unsigned char)EOF)){ nomad: if (greed) *p++ = x == ' '? x : '!'; else *p++ = x < 0x80? x : '?'; *p++ = 7; goto repeat; } if (x == (unsigned char)EOF) goto eox; x2 = getc (d); if (x2 >= 0xA1 && x2 <= 0xFE) { int o = (x - 0xA1) * 94 + (x2 - 0xA1); short sat = attrs [o]; if (!allused && !sat) { seats [o] = n; attrs [o] ++; memcpy (f + n*32, m+ o*32, height); memcpy (f + (n+1)*32, m+ o*32 +height, height); *p++ = n++; *p++ = intensified? 017 : 7; *p++ = n++; *p++ = intensified? 017 : 7; if (intensified) attrs [o] |= INTENSIFIED; if (n == 32) { f = y [256]; intensified ^= 1; if (!intensified) { allused = 1; if (partial) goto eox; } } } else if (sat) { attrs [o] ++; *p++ = seats [o]; *p++ = attrs [o] & INTENSIFIED? 017 : 7; *p++ = seats [o] + 1; *p++ = attrs [o] & INTENSIFIED? 017 : 7; } else { *p++ = greed? '!' : '['; *p++ = 7; *p++ = greed? '!' : ']'; *p++ = 7; } goto repeat; } else { ungetc (x2, d); goto nomad; } eox: { unsigned char * h = s + HEAD_s, * sol = p - (p - h) % row_size, curr_row = (p - h) / row_size, * q = sol + pl [curr_row]; if (row != curr_row) while (row < curr_row) pl [row++] = row_size; if (curr_row >= rows) return 0; pl [curr_row] = p - sol; if (partial && allused) { r = e - p; while (p < q) *p++ = 0; p = sol + row_size; for (row = 0;row < curr_row-1;row++) pl[row] =0; for (row = curr_row+1; row < rows; row++) { sol += row_size; q = sol + pl [row]; while (p < q) *p++ = 0; p = sol; } return 0; } while (p < q) *p++ = 0; if (x == (unsigned char)EOF) { while (p < e) *p++ = 0; return EOF; } p = sol + row_size; row++; goto repeat; } return 0; } struct termios saved_attributes; void restore (void) { tcsetattr (0, TCSANOW, &saved_attributes); { char *argv [] = { "setfont", NULL }; execv ("/bin/setfont", argv); } } int main (int argc, char *argv []) { FILE* d; /* document */ int f, a; /* fileno of the font and vcsa handler*/ char end = 0; struct consolefontdesc cfd = { .charcount = 512, .charheight = height, .chardata = y[0], }; if (argc > 1) { int i, j; for (i = 1;i < argc;) { if (*argv [i] == '-') { switch (*(argv [i] + 1)) { case 'h' : puts ("[-h] [-[gG]] [-pP] #help| greedlly or gracefully|" " partially or show patches"); return 0; case 'g' : greed = 1; break; case 'G' : greed = 0; break; case 'p' : partial = 1; break; case 'P' : partial = 0; break; } for (j = i; j+1 < argc; j++) strcpy (argv [j], argv [j+1]); argc--; } else i++; } } if (!isatty (0) || argc == 1 || !(strcmp (argv[1], "-"))) { d = fdopen (dup (0), "r"); close (0); open ("/dev/tty", O_RDONLY); if (!isatty (0) ) return 1; } else d = fopen (argv[1], "rb"); if (d == NULL) return 1; f = open ("ge/faci/gb", O_RDONLY); if (f < 0) return 2; a = open ("/tmp/vcsa2", O_RDWR); if (a < 0) return 3; m = mmap (0, 256*1024, PROT_READ, MAP_SHARED, f, 0); if (m == MAP_FAILED) return 4; tcgetattr (0, &saved_attributes); atexit (restore); { struct termios tattr; tcgetattr (0, &tattr); tattr.c_lflag &= ~(ICANON|ECHO); tcsetattr (0, TCSANOW, &tattr); } ioctl (0, GIO_FONTX, &cfd); cfd.charcount = 512; read (a, os, sizeof(os)); lseek (a, 0, 0); do { if (compose (d) == EOF) end = 1; write (a, s, sizeof(s)); lseek (a, 0, 0); ioctl (0, PIO_FONTX, &cfd); if (getchar () == 'q') end = 1; } while (!end); write (a, os, sizeof(os)); return 0; }