aboutsummaryrefslogtreecommitdiff
path: root/host/matelight/main.c
diff options
context:
space:
mode:
authorjaseg <jaseg@jaseg.net>2014-01-03 16:40:44 +0100
committerjaseg <jaseg@jaseg.net>2014-01-03 16:40:44 +0100
commitd27f9ecf7ea92b702df128f856c1063aa91c51f2 (patch)
tree1dc2b1ff871e28966aceb7a6bf7da8f190a6cd24 /host/matelight/main.c
parent9ef5c135e894b2da95940e2556f4df9ce2205552 (diff)
downloadmatelight-d27f9ecf7ea92b702df128f856c1063aa91c51f2.tar.gz
matelight-d27f9ecf7ea92b702df128f856c1063aa91c51f2.tar.bz2
matelight-d27f9ecf7ea92b702df128f856c1063aa91c51f2.zip
Maybe gif-lib wasn't too bright an idea...
Diffstat (limited to 'host/matelight/main.c')
-rw-r--r--host/matelight/main.c357
1 files changed, 0 insertions, 357 deletions
diff --git a/host/matelight/main.c b/host/matelight/main.c
deleted file mode 100644
index 48532f7..0000000
--- a/host/matelight/main.c
+++ /dev/null
@@ -1,357 +0,0 @@
-
-#include "font.h"
-#include "color.h"
-#include <stdint.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <errno.h>
-#include <string.h>
-#include <wchar.h>
-#include <locale.h>
-#include <sys/timeb.h>
-#include <unistd.h>
-
-// CAUTION: REQUIRES INPUT TO BE \0-TERMINATED
-// ...also, it does a hardcodes setlocale of LC_CTYPE to en_US.utf8 for... reasons.
-int console_render(char *s, glyph_t **glyph_table, unsigned int glyph_table_size){
- unsigned int len = strlen(s);
-
- uint8_t *gbuf = NULL;
- unsigned int gbufwidth = 0;
- unsigned int gbufheight = 0;
- char *p = s;
-
- // Calculate screen width of string prior to allocating memory for the frame buffer
- wchar_t c;
- mbstate_t ps = {0};
- memset(&ps, 0, sizeof(mbstate_t));
- if(!setlocale(LC_CTYPE, "en_US.utf8")){
- fprintf(stderr, "Cannot set locale\n");
- goto error;
- }
- for(;;){
- while(*p == '\033'){
- p++;
- // Jump over escape sequences
- for(;;p++){
- if(!(*p == ';' || *p == '[' || ('0' <= *p && *p <= '9'))){
- p++;
- break;
- }
- }
- memset(&ps, 0, sizeof(mbstate_t));
- }
-
- size_t inc = mbrtowc(&c, p, MB_CUR_MAX, &ps); // MB_CUR_MAX is safe since p is \0-terminated
- if(inc == -1 || inc == -2){
- fprintf(stderr, "Error rendering string: No valid UTF-8 input.\n");
- goto error;
- }
- if(inc == 0) // Reached end of string
- break;
- p += inc;
-
- if(c > glyph_table_size){
- fprintf(stderr, "Error rendering string: Codepoint 0x%lx out of valid range (0-%d).\n", (long int)c, glyph_table_size);
- goto error;
- }
-
- glyph_t *g = glyph_table[c];
- if(!g){
- fprintf(stderr, "Error rendering string: Codepoint 0x%lx not in font.\n", (long int)c);
- goto error;
- }
-
- if(g->height > gbufheight)
- gbufheight = g->height;
-
- gbufwidth += g->width;
- }
- // For easier rendering on the terminal, round up to multiples of two
- gbufheight += gbufheight&1;
-
- // gbuf uses 3 bytes per color for r, g and b
- unsigned int gbufsize = gbufwidth*3*gbufheight;
- gbuf = malloc(gbufsize);
- if(gbuf == 0){
- fprintf(stderr, "Cannot malloc() %d bytes.\n", gbufsize);
- goto error;
- }
- memset(gbuf, 0, gbufsize);
-
- unsigned int x = 0;
- p = s;
- memset(&ps, 0, sizeof(mbstate_t));
- struct {
- color_t fg;
- color_t bg;
- unsigned int blink:4;
- unsigned int bold:1; // TODO
- unsigned int underline:1;
- unsigned int strikethrough:1;
- unsigned int fraktur:1; // TODO See: Flat10 Fraktur font
- unsigned int invert:1;
- } style = {
- colortable[DEFAULT_FG_COLOR], colortable[DEFAULT_BG_COLOR], 0, 0, 0, 0, 0, 0
- };
- // Render glyphs (now with escape sequence rendering!)
- for(;;){
- // NOTE: This nested escape sequence parsing does not contain any unicode-awareness whatsoever
- if(*p == '\033'){ // Escape sequence YAY
- char *sequence_start = ++p;
- if(*p == '['){ // This was a CSI!
- // Disassemble the list of numbers, only accept SGR sequences (those ending with 'm')
- long elems[MAX_CSI_ELEMENTS];
- int nelems;
- for(nelems = 0; nelems<MAX_CSI_ELEMENTS; nelems++){
- p++;
- char *endptr;
- elems[nelems] = strtol(p, &endptr, 10);
- if(p == endptr){
- fprintf(stderr, "Invalid escape sequence: \"\\e%s\"\n", sequence_start);
- goto error;
- }
- p = endptr;
- if(*endptr == 'm')
- break;
- if(*endptr != ';'){
- fprintf(stderr, "Invalid escape sequence: \"\\e%s\"\n", sequence_start);
- goto error;
- }
- }
- p++; // gobble up trailing 'm' of "\033[23;42m"
- nelems++;
- // By now we know it's a SGR since we error'ed out on anything else
- if(nelems < 1){
- fprintf(stderr, "Unsupported escape sequence: \"\\e%s\"\n", sequence_start);
- goto error;
- }
- // Parse the sequence numbers
- for(int i=0; i<nelems; i++){
- switch(elems[i]){
- case 0: // reset style
- style.fg = colortable[DEFAULT_FG_COLOR];
- style.bg = colortable[DEFAULT_BG_COLOR];
- style.bold = 0;
- style.underline = 0;
- style.blink = 0;
- style.strikethrough = 0;
- style.fraktur = 0;
- style.invert = 0;
- break;
- case 1: // bold
- style.bold = 1;
- break;
- case 4: // underline
- style.underline = 1;
- break;
- case 5: // slow blink
- style.blink = 1;
- break;
- case 6: // rapid blink
- style.blink = 8;
- break;
- case 7: // color invert on
- style.invert = 1;
- break;
- case 9: // strike-through
- style.strikethrough = 1;
- break;
- case 20:// Fraktur
- style.fraktur = 1;
- break;
- case 22:// Bold off
- style.bold = 0;
- break;
- case 24:// Underline off
- style.underline = 0;
- break;
- case 25:// Blink off
- style.blink = 0;
- break;
- case 27:// color invert off
- style.invert = 0;
- break;
- case 29:// strike-through off
- style.strikethrough = 0;
- break;
- case 30: // Set foreground color, "dim" colors
- case 31:
- case 32:
- case 33:
- case 34:
- case 35:
- case 36:
- case 37:
- style.fg = colortable[elems[i]-30];
- break;
- case 38: // Set xterm-256 foreground color
- i++;
- if(nelems-i < 2 || elems[i] != 5){
- fprintf(stderr, "Invalid ANSI escape code: \"\\e%s\"\n", sequence_start);
- goto error;
- }
- style.fg = colortable[elems[++i]];
- break;
- case 39: // Reset foreground color to default
- style.bg = colortable[DEFAULT_FG_COLOR];
- break;
- case 40: // Set background color, "dim" colors
- case 41:
- case 42:
- case 43:
- case 44:
- case 45:
- case 46:
- case 47:
- style.bg = colortable[elems[i]-40];
- break;
- case 48: // Set xterm-256 background color
- i++;
- if(nelems-i < 2 || elems[i] != 5){
- fprintf(stderr, "Invalid ANSI escape code: \"\\e%s\"\n", sequence_start);
- goto error;
- }
- style.bg = colortable[elems[++i]];
- break;
- case 49: // Reset background color to default
- style.bg = colortable[DEFAULT_BG_COLOR];
- break;
- case 90: // Set foreground color, "bright" colors
- case 91:
- case 92:
- case 93:
- case 94:
- case 95:
- case 96:
- case 97:
- style.fg = colortable[elems[i]-90+8];
- break;
- case 100: // Set background color, "bright" colors
- case 101:
- case 102:
- case 103:
- case 104:
- case 105:
- case 106:
- case 107:
- style.bg = colortable[elems[i]-100+8];
- break;
- default:
- fprintf(stderr, "Unsupported escape sequence: \"\\e%s\"\n", sequence_start);
- goto error;
- }
- }
-
- }else{
- fprintf(stderr, "Unsupported escape sequence: \"\\e%s\"\n", sequence_start);
- goto error;
- }
-
- continue;
- }
-
- size_t inc = mbrtowc(&c, p, (s+len+1)-p, NULL);
- // If p contained
- if(inc == 0) // Reached end of string
- break;
- p += inc;
-
- // Render glyph into frame buffer
- struct timeb time = {0};
- ftime(&time);
- unsigned long int t = time.time*1000 + time.millitm;
- int blink = style.blink && (t % (1000/style.blink) < (333/style.blink));
- int inv = !(style.invert ^ blink);
- color_t fg = inv ? style.fg : style.bg;
- color_t bg = inv ? style.bg : style.fg;
-
- glyph_t *g = glyph_table[c];
- render_glyph(g, gbuf, gbufwidth, x, 0, fg, bg);
- if(style.strikethrough || style.underline){
- int sty = gbufheight/2;
- // g->y usually is a negative index of the glyph's baseline measured from the glyph's bottom
- int uly = gbufheight + g->y;
- for(int i=0; i<g->width; i++){
- if(style.strikethrough)
- *((color_t *)(gbuf + (sty*gbufwidth + x + i)*3)) = fg;
- if(style.underline)
- *((color_t *)(gbuf + (uly*gbufwidth + x + i)*3)) = fg;
- }
- }
- x += g->width;
- }
-
- // Render framebuffer to terminal, two pixels per character using Unicode box drawing stuff
- color_t lastfg = {0, 0, 0}, lastbg = {0, 0, 0};
- printf("\e[38;5;0;48;5;0m");
- for(unsigned int y=0; y < gbufheight; y+=2){
- for(unsigned int x=0; x < gbufwidth; x++){
- // Da magicks: ▀█▄
- color_t ct = *((color_t *)(gbuf + (y*gbufwidth + x)*3)); // Top pixel
- color_t cb = *((color_t *)(gbuf + ((y+1)*gbufwidth + x)*3)); // Bottom pixel
- // The following, rather convoluted logic tries to "save" escape sequences when rendering.
- if(!memcmp(&ct, &lastfg, sizeof(color_t))){
- if(!memcmp(&cb, &lastbg, sizeof(color_t))){
- printf("▀");
- }else if(!memcmp(&cb, &lastfg, sizeof(color_t))){
- printf("█");
- }else{
- printf("\033[48;5;%dm▀", xterm_color_index(cb));
- lastbg = cb;
- }
- }else if(!memcmp(&ct, &lastbg, sizeof(color_t))){
- if(!memcmp(&cb, &lastfg, sizeof(color_t))){
- printf("▄");
- }else if(!memcmp(&cb, &lastbg, sizeof(color_t))){
- printf(" ");
- }else{
- printf("\033[38;5;%dm▄", xterm_color_index(cb));
- lastfg = cb;
- }
- }else{ // No matches for the upper pixel
- if(!memcmp(&cb, &lastfg, sizeof(color_t))){
- printf("\033[48;5;%dm▄", xterm_color_index(ct));
- lastbg = ct;
- }else if(!memcmp(&cb, &lastbg, sizeof(color_t))){
- printf("\033[38;5;%dm▀", xterm_color_index(ct));
- lastfg = ct;
- }else{
- printf("\033[38;5;%d;48;5;%dm▀", xterm_color_index(ct), xterm_color_index(cb));
- lastfg = ct;
- lastbg = cb;
- }
- }
- }
- printf("\n");
- }
- return 0;
-error:
- free(gbuf);
- return 1;
-}
-
-int main(int argc, char **argv){
- FILE *f = fopen("unifont.bdf", "r");
- if(!f){
- fprintf(stderr, "Error opening font file: %s\n", strerror(errno));
- return 1;
- }
- glyph_t* glyph_table[BLP_SIZE];
- if(read_bdf(f, glyph_table, BLP_SIZE)){
- fprintf(stderr, "Error reading font file.\n");
- return 1;
- }
- for(;;){
- printf("\033[2J");
- for(unsigned int i=1; i<argc; i++){
- if(console_render(argv[i], glyph_table, BLP_SIZE)){
- fprintf(stderr, "Error rendering text.\n");
- return 1;
- }
- printf("\n");
- }
- usleep(20000);
- }
- return 0;
-}