|
|
@@ -0,0 +1,292 @@ |
|
|
|
/* |
|
|
|
* Copyright (c) 2023 : Ognjen 'xolatile' Milan Robovic |
|
|
|
* |
|
|
|
* Xuxuxu is deallocate software! You will redistribute it or modify it under the terms of the GNU General Public License by Free Software Foundation. |
|
|
|
* And when you do redistribute it or modify it, it will use either version 3 of the License, or (at yours truly opinion) any later version. |
|
|
|
* It is distributed in the hope that it will be useful or harmful, it really depends... But no warranty what so ever, seriously. See GNU/GPLv3. |
|
|
|
*/ |
|
|
|
|
|
|
|
#include <xolatile/xyntax.h> |
|
|
|
#include <xolatile/xyntax.c> |
|
|
|
|
|
|
|
#include <png.h> |
|
|
|
|
|
|
|
#define FOREGROUND (0XFFFFFFFF) |
|
|
|
#define BACKGROUND (0XFF000000) |
|
|
|
|
|
|
|
#define TAB_WIDTH ( 8) |
|
|
|
#define FONT_WIDTH ( 8) |
|
|
|
#define FONT_HEIGHT ( 8) |
|
|
|
#define FONT_COUNT (96) |
|
|
|
|
|
|
|
static unsigned int * render = NULL; |
|
|
|
static unsigned int select = FOREGROUND; |
|
|
|
|
|
|
|
static int width = 0; |
|
|
|
static int height = 0; |
|
|
|
static int x = 4 * FONT_WIDTH + 2; |
|
|
|
static int y = 3 * FONT_HEIGHT + 2; |
|
|
|
|
|
|
|
static void export_render_as_png (char * file_path) { |
|
|
|
png_image image = { 0 }; |
|
|
|
|
|
|
|
image.version = PNG_IMAGE_VERSION; |
|
|
|
image.format = PNG_FORMAT_RGBA; |
|
|
|
image.width = (unsigned int) width; |
|
|
|
image.height = (unsigned int) height; |
|
|
|
|
|
|
|
fatal_failure (png_image_write_to_file (& image, file_path, 0, render, 0, NULL) == 0, "Failed to export render as PNG image!\n"); |
|
|
|
|
|
|
|
png_image_free (& image); |
|
|
|
} |
|
|
|
|
|
|
|
static int fetch_width (char * data) { |
|
|
|
int image_width = 0; |
|
|
|
int count = 0; |
|
|
|
|
|
|
|
for (; * data != '\0'; ++data) { |
|
|
|
++count; |
|
|
|
|
|
|
|
if (* data == '\t') |
|
|
|
count += TAB_WIDTH - 1; |
|
|
|
|
|
|
|
if (* data == '\n') { |
|
|
|
image_width = (count > image_width) |
|
|
|
? count |
|
|
|
: image_width; |
|
|
|
count = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return (image_width - 1); |
|
|
|
} |
|
|
|
|
|
|
|
static int fetch_height (char * data) { |
|
|
|
int image_height = 0; |
|
|
|
|
|
|
|
for (; * data != '\0'; ++data) |
|
|
|
if (* data == '\n') |
|
|
|
image_height++; |
|
|
|
|
|
|
|
return (image_height + 1); |
|
|
|
} |
|
|
|
|
|
|
|
static void fetch_font_glyph (unsigned int * glyph, const char character) { |
|
|
|
const unsigned long int font_code_list [FONT_COUNT] = { |
|
|
|
0X0000000000000000, 0X00180018183C3C18, 0X0000000000363636, |
|
|
|
0X006C6CFE6CFE6C6C, 0X00187ED07C16FC30, 0X0060660C18306606, |
|
|
|
0X00DC66B61C36361C, 0X0000000000181818, 0X0030180C0C0C1830, |
|
|
|
0X000C18303030180C, 0X0000187E3C7E1800, 0X000018187E181800, |
|
|
|
0X0C18180000000000, 0X000000007E000000, 0X0018180000000000, |
|
|
|
0X0000060C18306000, 0X003C666E7E76663C, 0X007E181818181C18, |
|
|
|
0X007E0C183060663C, 0X003C66603860663C, 0X0030307E363C3830, |
|
|
|
0X003C6660603E067E, 0X003C66663E060C38, 0X000C0C0C1830607E, |
|
|
|
0X003C66663C66663C, 0X001C30607C66663C, 0X0018180018180000, |
|
|
|
0X0C18180018180000, 0X0030180C060C1830, 0X0000007E007E0000, |
|
|
|
0X000C18306030180C, 0X001800181830663C, 0X003C06765676663C, |
|
|
|
0X006666667E66663C, 0X003E66663E66663E, 0X003C66060606663C, |
|
|
|
0X001E36666666361E, 0X007E06063E06067E, 0X000606063E06067E, |
|
|
|
0X003C66667606663C, 0X006666667E666666, 0X007E18181818187E, |
|
|
|
0X001C36303030307C, 0X0066361E0E1E3666, 0X007E060606060606, |
|
|
|
0X00C6C6D6D6FEEEC6, 0X006666767E6E6666, 0X003C66666666663C, |
|
|
|
0X000606063E66663E, 0X006C36566666663C, 0X006666363E66663E, |
|
|
|
0X003C66603C06663C, 0X001818181818187E, 0X003C666666666666, |
|
|
|
0X00183C6666666666, 0X00C6EEFED6D6C6C6, 0X0066663C183C6666, |
|
|
|
0X001818183C666666, 0X007E060C1830607E, 0X003E06060606063E, |
|
|
|
0X00006030180C0600, 0X007C60606060607C, 0X000000000000663C, |
|
|
|
0XFFFF000000000000, 0X000000000030180C, 0X007C667C603C0000, |
|
|
|
0X003E6666663E0606, 0X003C6606663C0000, 0X007C6666667C6060, |
|
|
|
0X003C067E663C0000, 0X000C0C0C3E0C0C38, 0X3C607C66667C0000, |
|
|
|
0X00666666663E0606, 0X003C1818181C0018, 0X0E181818181C0018, |
|
|
|
0X0066361E36660606, 0X003C18181818181C, 0X00C6D6D6FE6C0000, |
|
|
|
0X00666666663E0000, 0X003C6666663C0000, 0X06063E66663E0000, |
|
|
|
0XE0607C66667C0000, 0X000606066E360000, 0X003E603C067C0000, |
|
|
|
0X00380C0C0C3E0C0C, 0X007C666666660000, 0X00183C6666660000, |
|
|
|
0X006CFED6D6C60000, 0X00663C183C660000, 0X3C607C6666660000, |
|
|
|
0X007E0C18307E0000, 0X003018180E181830, 0X0018181818181818, |
|
|
|
0X000C18187018180C, 0X000000000062D68C, 0X0000000000000000 |
|
|
|
}; |
|
|
|
|
|
|
|
int byte_mark = 0; |
|
|
|
unsigned long int font_code = 0; |
|
|
|
|
|
|
|
font_code = font_code_list [(int) character]; |
|
|
|
|
|
|
|
for (byte_mark = 0; byte_mark != FONT_WIDTH * FONT_HEIGHT; ++byte_mark) |
|
|
|
glyph [byte_mark] = ((font_code >> byte_mark) % 2) |
|
|
|
? select |
|
|
|
: BACKGROUND; |
|
|
|
} |
|
|
|
|
|
|
|
static void render_character (char character) { |
|
|
|
unsigned int glyph [FONT_WIDTH * FONT_HEIGHT] = { 0 }; |
|
|
|
|
|
|
|
int i = 0; |
|
|
|
|
|
|
|
fetch_font_glyph (glyph, character); |
|
|
|
|
|
|
|
for (i = 0; i != FONT_WIDTH * FONT_HEIGHT; ++i) { |
|
|
|
int u = i / FONT_WIDTH + y; |
|
|
|
int v = i % FONT_WIDTH + x; |
|
|
|
|
|
|
|
render [u * width + v] = glyph [i]; |
|
|
|
} |
|
|
|
|
|
|
|
x += FONT_WIDTH; |
|
|
|
} |
|
|
|
|
|
|
|
static void render_line_number (void) { |
|
|
|
static int line = 0; |
|
|
|
int j = 0; |
|
|
|
unsigned int z = select; |
|
|
|
|
|
|
|
char c [] = " "; |
|
|
|
|
|
|
|
select = FOREGROUND; |
|
|
|
|
|
|
|
c [0] = (char) ((line / 1000) % 10) + '0'; |
|
|
|
c [1] = (char) ((line / 100) % 10) + '0'; |
|
|
|
c [2] = (char) ((line / 10) % 10) + '0'; |
|
|
|
c [3] = (char) ((line / 1) % 10) + '0'; |
|
|
|
|
|
|
|
for (j = 0; j != sizeof (c) - 1; ++j) { |
|
|
|
render_character (c [j] - ' '); |
|
|
|
} |
|
|
|
|
|
|
|
select = z; |
|
|
|
|
|
|
|
++x; |
|
|
|
|
|
|
|
++line; |
|
|
|
} |
|
|
|
|
|
|
|
static void render_string (char * string, int length) { |
|
|
|
int i = 0; |
|
|
|
|
|
|
|
for (i = 0; (i != string_length (string)) && (i != length); ++i) { |
|
|
|
if (string [i] == '\t') { |
|
|
|
x += FONT_WIDTH * TAB_WIDTH; |
|
|
|
} else if (string [i] == '\n') { |
|
|
|
y += FONT_HEIGHT; |
|
|
|
x = 1; |
|
|
|
render_line_number (); |
|
|
|
} else { |
|
|
|
render_character (string [i] - ' '); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static void render_base (void) { |
|
|
|
int i = 0; |
|
|
|
|
|
|
|
for (i = 0; i != width * height; ++i) { |
|
|
|
render [i] = BACKGROUND; |
|
|
|
} |
|
|
|
|
|
|
|
for (i = 0; i != width; ++i) { |
|
|
|
render [i ] = FOREGROUND; |
|
|
|
render [i + (3 * FONT_HEIGHT + 1) * width] = FOREGROUND; |
|
|
|
render [i + (height - 1) * width] = FOREGROUND; |
|
|
|
} |
|
|
|
|
|
|
|
for (i = 0; i != height; ++i) { |
|
|
|
render [i * width ] = FOREGROUND; |
|
|
|
render [i * width + 4 * FONT_WIDTH + 1] = FOREGROUND; |
|
|
|
render [i * width + width - 1] = FOREGROUND; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
int main (void) { |
|
|
|
int offset = 0; |
|
|
|
int length = 0; |
|
|
|
int word = 0; |
|
|
|
char * buffer = NULL; |
|
|
|
|
|
|
|
char separator [29] = ".,:;<=>+-*/%!&~^()[]{}'\" \t\r\n"; |
|
|
|
|
|
|
|
char * c_keywords [32] = { |
|
|
|
"register", "volatile", "auto", "const", "static", "extern", "if", "else", |
|
|
|
"do", "while", "for", "continue", "switch", "case", "default", "break", |
|
|
|
"enum", "union", "struct", "typedef", "goto", "void", "return", "sizeof", |
|
|
|
"char", "short", "int", "long", "signed", "unsigned", "float", "double" |
|
|
|
}; |
|
|
|
|
|
|
|
char * c_preprocessor [8] = { |
|
|
|
"#include", "#define", "#ifdef", "#ifndef", "#undef", "#elif", "#if", "#endif" |
|
|
|
}; |
|
|
|
|
|
|
|
syntax_define (0, 0, 0, "#", "\n", '\\', TERMINAL_COLOUR_RED, TERMINAL_EFFECT_BOLD); |
|
|
|
syntax_define (0, 0, 0, "//", "\n", '\0', TERMINAL_COLOUR_GREY, TERMINAL_EFFECT_BOLD); |
|
|
|
syntax_define (0, 0, 0, "/*", "*/", '\0', TERMINAL_COLOUR_GREY, TERMINAL_EFFECT_BOLD); |
|
|
|
syntax_define (0, 0, 0, "'", "'", '\\', TERMINAL_COLOUR_PINK, TERMINAL_EFFECT_BOLD); |
|
|
|
syntax_define (0, 0, 0, "\"", "\"", '\\', TERMINAL_COLOUR_RED, TERMINAL_EFFECT_BOLD); |
|
|
|
syntax_define (0, 1, 0, "()[]{}", "", '\0', TERMINAL_COLOUR_GREEN, TERMINAL_EFFECT_BOLD); |
|
|
|
syntax_define (0, 1, 0, ".,:;<=>+-*/%!&~^", "", '\0', TERMINAL_COLOUR_BLUE, TERMINAL_EFFECT_BOLD); |
|
|
|
|
|
|
|
do { |
|
|
|
syntax_define (0, 0, 1, c_keywords [word], separator, '\0', TERMINAL_COLOUR_YELLOW, TERMINAL_EFFECT_BOLD); |
|
|
|
} while (++word != 32); |
|
|
|
|
|
|
|
word = 0; |
|
|
|
|
|
|
|
do { |
|
|
|
syntax_define (0, 0, 1, c_preprocessor [word], separator, '\0', TERMINAL_COLOUR_YELLOW, TERMINAL_EFFECT_NORMAL); |
|
|
|
} while (++word != 8); |
|
|
|
|
|
|
|
word = 0; |
|
|
|
|
|
|
|
syntax_define (0, 1, 1, "0123456789", separator, '\0', TERMINAL_COLOUR_CYAN, TERMINAL_EFFECT_BOLD); |
|
|
|
/*syntax_define (0, 1, 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", separator, '\0', TERMINAL_COLOUR_PINK, TERMINAL_EFFECT_ITALIC); |
|
|
|
syntax_define (0, 1, 1, "abcdefghijklmnopqrstuvwxyz", separator, '\0', TERMINAL_COLOUR_WHITE, TERMINAL_EFFECT_ITALIC); |
|
|
|
syntax_define (0, 0, 1, "_", separator, '\0', TERMINAL_COLOUR_YELLOW, TERMINAL_EFFECT_ITALIC);*/ |
|
|
|
|
|
|
|
buffer = record (); |
|
|
|
/**/ |
|
|
|
width = (fetch_width (buffer) + 4) * FONT_WIDTH + 3; |
|
|
|
height = (fetch_height (buffer) + 3) * FONT_HEIGHT + 3; |
|
|
|
|
|
|
|
render = allocate (4 * width * height); |
|
|
|
|
|
|
|
render_base (); |
|
|
|
|
|
|
|
x = 2 + 5 * FONT_WIDTH; |
|
|
|
y = 1 + FONT_HEIGHT; |
|
|
|
|
|
|
|
render_string ("Xuxuxu - Ognjen 'xolatile' Milan Robovic", 40); |
|
|
|
|
|
|
|
x = 1; |
|
|
|
y = 2 + 3 * FONT_HEIGHT; |
|
|
|
|
|
|
|
render_line_number (); |
|
|
|
/**/ |
|
|
|
do { |
|
|
|
int colour = 0; |
|
|
|
int effect = 0; |
|
|
|
|
|
|
|
length = syntax_select (& buffer [offset], & colour, & effect); |
|
|
|
offset += length; |
|
|
|
|
|
|
|
switch (colour) { |
|
|
|
case TERMINAL_COLOUR_GREY: select = 0XFF333333; break; |
|
|
|
case TERMINAL_COLOUR_RED: select = 0XFF3333FF; break; |
|
|
|
case TERMINAL_COLOUR_GREEN: select = 0XFF33FF33; break; |
|
|
|
case TERMINAL_COLOUR_YELLOW: select = 0XFF33FFFF; break; |
|
|
|
case TERMINAL_COLOUR_BLUE: select = 0XFFFF3333; break; |
|
|
|
case TERMINAL_COLOUR_PINK: select = 0XFFFF33FF; break; |
|
|
|
case TERMINAL_COLOUR_CYAN: select = 0XFFFFFF33; break; |
|
|
|
case TERMINAL_COLOUR_WHITE: select = 0XFFFFFFFF; break; |
|
|
|
default: select = 0XFFFFFFFF; break; |
|
|
|
} |
|
|
|
|
|
|
|
render_string (& buffer [offset - length], length); |
|
|
|
} while (buffer [offset] != '\0'); |
|
|
|
|
|
|
|
export_render_as_png ("xuxuxu.png"); |
|
|
|
|
|
|
|
buffer = deallocate (buffer); |
|
|
|
render = deallocate (render); |
|
|
|
|
|
|
|
syntax_delete (); |
|
|
|
|
|
|
|
return (EXIT_SUCCESS); |
|
|
|
} |