xuxuxu lol
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

240 lines
8.1KB

  1. /*
  2. * Copyright (c) 2023 : Ognjen 'xolatile' Milan Robovic
  3. *
  4. * Xuxuxu is free software! You will redistribute it or modify it under the terms of the GNU General Public License by Free Software Foundation.
  5. * 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.
  6. * 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.
  7. */
  8. #include <xolatile/xyntax.h>
  9. #include <xolatile/xyntax.c>
  10. #include <png.h>
  11. #define FOREGROUND (0XFFFFFFFF)
  12. #define BACKGROUND (0XFF000000)
  13. #define TAB_WIDTH ( 8)
  14. #define FONT_WIDTH ( 8)
  15. #define FONT_HEIGHT ( 8)
  16. #define FONT_COUNT (96)
  17. static unsigned int * render = NULL;
  18. static unsigned int colour = FOREGROUND;
  19. static int width = 0;
  20. static int height = 0;
  21. static int x = 0;
  22. static int y = 0;
  23. static void export_render_as_png (char * file_path) {
  24. png_image image = { 0 };
  25. image.version = PNG_IMAGE_VERSION;
  26. image.format = PNG_FORMAT_RGBA;
  27. image.width = (unsigned int) width;
  28. image.height = (unsigned int) height;
  29. fatal_failure (png_image_write_to_file (& image, file_path, 0, render, 0, NULL) == 0, "Failed to export render as PNG image!\n");
  30. png_image_free (& image);
  31. }
  32. static int fetch_width (char * data) {
  33. int image_width = 0;
  34. int count = 0;
  35. do {
  36. if (* data == '\t') {
  37. count += TAB_WIDTH;
  38. } else if (* data == '\n') {
  39. ++count;
  40. image_width = (count > image_width)
  41. ? count
  42. : image_width;
  43. count = 0;
  44. } else {
  45. ++count;
  46. }
  47. } while (* (++data) != '\0');
  48. return (image_width - 1);
  49. }
  50. static int fetch_height (char * data) {
  51. int image_height = 0;
  52. do {
  53. if (* data == '\n') {
  54. ++image_height;
  55. }
  56. } while (* (++data) != '\0');
  57. return (image_height + 1);
  58. }
  59. static void fetch_font_glyph (unsigned int * glyph, const char character) {
  60. const unsigned long int font_code_list [FONT_COUNT] = {
  61. 0X0000000000000000, 0X00180018183C3C18, 0X0000000000363636,
  62. 0X006C6CFE6CFE6C6C, 0X00187ED07C16FC30, 0X0060660C18306606,
  63. 0X00DC66B61C36361C, 0X0000000000181818, 0X0030180C0C0C1830,
  64. 0X000C18303030180C, 0X0000187E3C7E1800, 0X000018187E181800,
  65. 0X0C18180000000000, 0X000000007E000000, 0X0018180000000000,
  66. 0X0000060C18306000, 0X003C666E7E76663C, 0X007E181818181C18,
  67. 0X007E0C183060663C, 0X003C66603860663C, 0X0030307E363C3830,
  68. 0X003C6660603E067E, 0X003C66663E060C38, 0X000C0C0C1830607E,
  69. 0X003C66663C66663C, 0X001C30607C66663C, 0X0018180018180000,
  70. 0X0C18180018180000, 0X0030180C060C1830, 0X0000007E007E0000,
  71. 0X000C18306030180C, 0X001800181830663C, 0X003C06765676663C,
  72. 0X006666667E66663C, 0X003E66663E66663E, 0X003C66060606663C,
  73. 0X001E36666666361E, 0X007E06063E06067E, 0X000606063E06067E,
  74. 0X003C66667606663C, 0X006666667E666666, 0X007E18181818187E,
  75. 0X001C36303030307C, 0X0066361E0E1E3666, 0X007E060606060606,
  76. 0X00C6C6D6D6FEEEC6, 0X006666767E6E6666, 0X003C66666666663C,
  77. 0X000606063E66663E, 0X006C36566666663C, 0X006666363E66663E,
  78. 0X003C66603C06663C, 0X001818181818187E, 0X003C666666666666,
  79. 0X00183C6666666666, 0X00C6EEFED6D6C6C6, 0X0066663C183C6666,
  80. 0X001818183C666666, 0X007E060C1830607E, 0X003E06060606063E,
  81. 0X00006030180C0600, 0X007C60606060607C, 0X000000000000663C,
  82. 0XFFFF000000000000, 0X000000000030180C, 0X007C667C603C0000,
  83. 0X003E6666663E0606, 0X003C6606663C0000, 0X007C6666667C6060,
  84. 0X003C067E663C0000, 0X000C0C0C3E0C0C38, 0X3C607C66667C0000,
  85. 0X00666666663E0606, 0X003C1818181C0018, 0X0E181818181C0018,
  86. 0X0066361E36660606, 0X003C18181818181C, 0X00C6D6D6FE6C0000,
  87. 0X00666666663E0000, 0X003C6666663C0000, 0X06063E66663E0000,
  88. 0XE0607C66667C0000, 0X000606066E360000, 0X003E603C067C0000,
  89. 0X00380C0C0C3E0C0C, 0X007C666666660000, 0X00183C6666660000,
  90. 0X006CFED6D6C60000, 0X00663C183C660000, 0X3C607C6666660000,
  91. 0X007E0C18307E0000, 0X003018180E181830, 0X0018181818181818,
  92. 0X000C18187018180C, 0X000000000062D68C, 0X0000000000000000
  93. };
  94. int offset = 0;
  95. unsigned long int font_code = 0;
  96. font_code = font_code_list [(int) character];
  97. do {
  98. glyph [offset] = ((font_code >> offset) & 1)
  99. ? colour
  100. : BACKGROUND;
  101. } while (++offset != FONT_WIDTH * FONT_HEIGHT);
  102. }
  103. static void render_character (char character) {
  104. unsigned int glyph [FONT_WIDTH * FONT_HEIGHT] = { 0 };
  105. int offset = 0;
  106. fetch_font_glyph (glyph, character);
  107. do {
  108. int u = offset / FONT_WIDTH + y;
  109. int v = offset % FONT_WIDTH + x;
  110. render [u * width + v] = glyph [offset];
  111. } while (++offset != FONT_WIDTH * FONT_HEIGHT);
  112. x += FONT_WIDTH + 1;
  113. }
  114. static void render_string (char * string, int length) {
  115. int offset = 0;
  116. do {
  117. if (string [offset] == '\t') {
  118. x += FONT_WIDTH * TAB_WIDTH;
  119. } else if (string [offset] == '\n') {
  120. y += FONT_HEIGHT + 1;
  121. x = 1;
  122. } else {
  123. render_character (string [offset] - ' ');
  124. }
  125. } while (++offset != length);
  126. }
  127. int main (void) {
  128. int offset = 0;
  129. int word = 0;
  130. int index = 0;
  131. int length = 0;
  132. char * buffer = NULL;
  133. int preprocessor = 0;
  134. int line_comment = 0;
  135. int multiline_comment = 0;
  136. int character = 0;
  137. int string = 0;
  138. int bracket = 0;
  139. int operator = 0;
  140. int keyword = 0;
  141. int digit = 0;
  142. int uppercase = 0;
  143. int lowercase = 0;
  144. int underscore = 0;
  145. char separator [29] = ".,:;<=>+-*/%!&~^()[]{}'\" \t\r\n";
  146. char * c_keywords [32] = {
  147. "register", "volatile", "auto", "const", "static", "extern", "if", "else",
  148. "do", "while", "for", "continue", "switch", "case", "default", "break",
  149. "enum", "union", "struct", "typedef", "goto", "void", "return", "sizeof",
  150. "char", "short", "int", "long", "signed", "unsigned", "float", "double"
  151. };
  152. syntax_define (& preprocessor, 0, 0, "#", "\n", '\\', COLOUR_RED, EFFECT_BOLD);
  153. syntax_define (& line_comment, 0, 0, "//", "\n", '\0', COLOUR_GREY, EFFECT_BOLD);
  154. syntax_define (& multiline_comment, 0, 0, "/*", "*/", '\0', COLOUR_GREY, EFFECT_BOLD);
  155. syntax_define (& character, 0, 0, "'", "'", '\\', COLOUR_PINK, EFFECT_BOLD);
  156. syntax_define (& string, 0, 0, "\"", "\"", '\\', COLOUR_RED, EFFECT_BOLD);
  157. syntax_define (& bracket, 1, 0, "()[]{}", "", '\0', COLOUR_GREEN, EFFECT_BOLD);
  158. syntax_define (& operator, 1, 0, ".,:;<=>+-*/%!&~^?", "", '\0', COLOUR_BLUE, EFFECT_BOLD);
  159. for (word = 0; word != 32; ++word) {
  160. syntax_define (& keyword, 0, 1, c_keywords [word], separator, '\0', COLOUR_YELLOW, EFFECT_BOLD);
  161. }
  162. syntax_define (& digit, 1, 1, "0123456789", separator, '\0', COLOUR_CYAN, EFFECT_BOLD);
  163. syntax_define (& uppercase, 1, 1, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", separator, '\0', COLOUR_PINK, EFFECT_ITALIC);
  164. syntax_define (& lowercase, 1, 1, "abcdefghijklmnopqrstuvwxyz", separator, '\0', COLOUR_WHITE, EFFECT_ITALIC);
  165. syntax_define (& underscore, 0, 1, "_", separator, '\0', COLOUR_YELLOW, EFFECT_ITALIC);
  166. buffer = record ();
  167. width = fetch_width (buffer) * (FONT_WIDTH + 1) + 1;
  168. height = fetch_height (buffer) * (FONT_HEIGHT + 1) + 1;
  169. render = allocate (4 * width * height);
  170. for (offset = 0; offset != width * height; ++offset) {
  171. render [offset] = BACKGROUND;
  172. }
  173. for (offset = 0; buffer [offset] != '\0'; offset += length) {
  174. syntax_select (& buffer [offset], & index, & length);
  175. switch (syntax_colour [index]) {
  176. case COLOUR_GREY: colour = 0XFF333333; break;
  177. case COLOUR_RED: colour = 0XFF3333FF; break;
  178. case COLOUR_GREEN: colour = 0XFF33FF33; break;
  179. case COLOUR_YELLOW: colour = 0XFF33FFFF; break;
  180. case COLOUR_BLUE: colour = 0XFFFF3333; break;
  181. case COLOUR_PINK: colour = 0XFFFF33FF; break;
  182. case COLOUR_CYAN: colour = 0XFFFFFF33; break;
  183. case COLOUR_WHITE: colour = 0XFFFFFFFF; break;
  184. default: colour = 0XFFFFFFFF; break;
  185. }
  186. render_string (& buffer [offset], length);
  187. }
  188. export_render_as_png ("xuxuxu.png");
  189. buffer = deallocate (buffer);
  190. render = deallocate (render);
  191. syntax_delete ();
  192. return (EXIT_SUCCESS);
  193. }