274 lines
11 KiB
C
Executable File
274 lines
11 KiB
C
Executable File
/// _
|
|
/// __ ____ _ _ __| |__ ___ _ __
|
|
/// \ \/ / _` | '__| '_ \ / _ \| '_ |
|
|
/// > < (_| | | | |_) | (_) | | | |
|
|
/// /_/\_\__,_|_| |_.__/ \___/|_| |_|
|
|
///
|
|
/// Copyright (c) 1997 - Ognjen 'xolatile' Milan Robovic
|
|
///
|
|
/// xolatile@chud.cyou - xarbon - Source code renderer to PNG image, very slow but self-contained, hardcoded font.
|
|
///
|
|
/// This program is free software, free as in freedom and as in free beer, you can redistribute it and/or modify it under the terms of the GNU
|
|
/// General Public License as published by the Free Software Foundation, either version 3 of the License, or any later version if you wish...
|
|
///
|
|
/// This program is distributed in the hope that it will be useful, but it is probably not, and without any warranty, without even the implied
|
|
/// warranty of merchantability or fitness for a particular purpose, because it is pointless. Please see the GNU (Geenoo) General Public License
|
|
/// for more details, if you dare, it is a lot of text that nobody wants to read...
|
|
|
|
#define use_png_library
|
|
|
|
#include "xtandard.h"
|
|
#include "xyntax.h"
|
|
#include "xanguage.h"
|
|
#include "xormat.h"
|
|
|
|
static natural background = 0xff181818;
|
|
static natural foreground = 0xffcccccc;
|
|
static natural font_width = 8;
|
|
static natural font_height = 16;
|
|
static natural tab_width = 8;
|
|
static natural render_border = 10;
|
|
|
|
static natural * render_image = null;
|
|
static natural render_width = 0;
|
|
static natural render_height = 0;
|
|
static natural line_number = 0;
|
|
static natural line_digits = 0;
|
|
|
|
static procedure conditionally_exit (language_structure * language, syntax_structure * syntax, boolean terminate) {
|
|
syntax = syntax_deinitialize (syntax);
|
|
language = language_deinitialize (language);
|
|
|
|
if (terminate == true) {
|
|
exit (log_success);
|
|
}
|
|
}
|
|
|
|
static procedure print_common (none) {
|
|
print ("/B/4xarbon/-: /4Source code PNG renderer/-\n\n");
|
|
print ("\tAuthor: /4Ognjen 'xolatile' Milan Robovic/-\n");
|
|
print ("\tLicense: /4GNU//GPLv3/-\n\n");
|
|
}
|
|
|
|
static procedure print_help (none) {
|
|
print_common ();
|
|
|
|
print ("Example usage:\n\n");
|
|
print ("\t/6$ cat file.ext | xarbon [flags]/- /0---/- You need to pass language flag in this case.\n");
|
|
print ("\t/6$ xarbon [flags] < file.ext/- /0---/- You need to pass language flag in this case.\n");
|
|
print ("\t/6$ xarbon file.ext/- /0---/- Language is automatically detected in this case.\n\n");
|
|
print ("Supported languages:\n\n");
|
|
|
|
for (language_enumeration index = 0; index < language_count; ++index) {
|
|
character align [32] = "";
|
|
|
|
print ("\t/B/4%s/- /4%s/- /0---/- %s syntax highlighting\n",
|
|
language_short_option [index],
|
|
string_align_left (string_copy (align, language_long_option [index]), 9, ' '),
|
|
language_identifier [index]);
|
|
}
|
|
}
|
|
|
|
static procedure print_version (none) {
|
|
print_common ();
|
|
|
|
print ("\tVersion: /40 (Zero)/-\n");
|
|
}
|
|
|
|
static natural fetch_width (character * data) {
|
|
natural image_width = 0;
|
|
natural count = 0;
|
|
|
|
do {
|
|
if (* data == '\t') {
|
|
count += tab_width;
|
|
} else if (* data == '\n') {
|
|
image_width = (++count > image_width) ? count : image_width;
|
|
count = 0;
|
|
} else {
|
|
++count;
|
|
}
|
|
} while (* (++data) != '\0');
|
|
|
|
return (image_width - 1);
|
|
}
|
|
|
|
static natural fetch_height (character * data) {
|
|
natural image_height = 0;
|
|
natural count = 0;
|
|
|
|
do {
|
|
if (* data == '\n') {
|
|
++image_height;
|
|
}
|
|
} while (* (++data) != '\0');
|
|
|
|
count = image_height + 1;
|
|
|
|
do {
|
|
++line_digits;
|
|
|
|
count /= 10;
|
|
} while (count > 0);
|
|
|
|
return (image_height + 1);
|
|
}
|
|
|
|
static procedure render_character (character data, natural * x, natural * y, natural colour) {
|
|
natural_64 glyphmap [192] = {
|
|
0x0000000000000000, 0x0000000000000000, 0x0000101010101010, 0x1000101000000000, 0x0024242400000000, 0x0000000000000000,
|
|
0x00002424247e2424, 0x7e24242400000000, 0x0010107c9290907c, 0x1212927c10100000, 0x0000649468081010, 0x202c524c00000000,
|
|
0x000018242418304a, 0x4444443a00000000, 0x0010101000000000, 0x0000000000000000, 0x0000081020202020, 0x2020100800000000,
|
|
0x0000201008080808, 0x0808102000000000, 0x000000000024187e, 0x1824000000000000, 0x000000000010107c, 0x1010000000000000,
|
|
0x0000000000000000, 0x0000101020000000, 0x000000000000007e, 0x0000000000000000, 0x0000000000000000, 0x0000101000000000,
|
|
0x0000040408081010, 0x2020404000000000, 0x00003c4242464a52, 0x6242423c00000000, 0x0000081828080808, 0x0808083e00000000,
|
|
0x00003c4242020408, 0x1020407e00000000, 0x00003c4242021c02, 0x0242423c00000000, 0x000002060a122242, 0x7e02020200000000,
|
|
0x00007e4040407c02, 0x0202423c00000000, 0x00001c2040407c42, 0x4242423c00000000, 0x00007e0202040408, 0x0810101000000000,
|
|
0x00003c4242423c42, 0x4242423c00000000, 0x00003c424242423e, 0x0202043800000000, 0x0000000000101000, 0x0000101000000000,
|
|
0x0000000000101000, 0x0000101020000000, 0x0000000408102040, 0x2010080400000000, 0x00000000007e0000, 0x7e00000000000000,
|
|
0x0000004020100804, 0x0810204000000000, 0x00003c4242420408, 0x0800080800000000, 0x00007c829ea2a2a2, 0xa69a807e00000000,
|
|
0x00003c424242427e, 0x4242424200000000, 0x00007c4242427c42, 0x4242427c00000000, 0x00003c4242404040, 0x4042423c00000000,
|
|
0x0000784442424242, 0x4242447800000000, 0x00007e4040407840, 0x4040407e00000000, 0x00007e4040407840, 0x4040404000000000,
|
|
0x00003c424240404e, 0x4242423c00000000, 0x0000424242427e42, 0x4242424200000000, 0x0000381010101010, 0x1010103800000000,
|
|
0x00000e0404040404, 0x0444443800000000, 0x0000424448506060, 0x5048444200000000, 0x0000404040404040, 0x4040407e00000000,
|
|
0x000082c6aa929282, 0x8282828200000000, 0x000042424262524a, 0x4642424200000000, 0x00003c4242424242, 0x4242423c00000000,
|
|
0x00007c424242427c, 0x4040404000000000, 0x00003c4242424242, 0x42424a3c02000000, 0x00007c424242427c, 0x5048444200000000,
|
|
0x00003c4240403c02, 0x0242423c00000000, 0x0000fe1010101010, 0x1010101000000000, 0x0000424242424242, 0x4242423c00000000,
|
|
0x0000424242424224, 0x2424181800000000, 0x0000828282828292, 0x92aac68200000000, 0x0000424224241818, 0x2424424200000000,
|
|
0x0000828244442810, 0x1010101000000000, 0x00007e0202040810, 0x2040407e00000000, 0x0000382020202020, 0x2020203800000000,
|
|
0x0000404020201010, 0x0808040400000000, 0x0000380808080808, 0x0808083800000000, 0x0000102844000000, 0x0000000000000000,
|
|
0x0000000000000000, 0x0000007e00000000, 0x1008000000000000, 0x0000000000000000, 0x00000000003c023e, 0x4242423e00000000,
|
|
0x00004040407c4242, 0x4242427c00000000, 0x00000000003c4240, 0x4040423c00000000, 0x00000202023e4242, 0x4242423e00000000,
|
|
0x00000000003c4242, 0x7e40403c00000000, 0x00000e10107c1010, 0x1010101000000000, 0x00000000003e4242, 0x4242423e02023c00,
|
|
0x00004040407c4242, 0x4242424200000000, 0x0000101000301010, 0x1010103800000000, 0x00000404000c0404, 0x0404040444443800,
|
|
0x0000404040424448, 0x7048444200000000, 0x0000301010101010, 0x1010103800000000, 0x0000000000fc9292, 0x9292929200000000,
|
|
0x00000000007c4242, 0x4242424200000000, 0x00000000003c4242, 0x4242423c00000000, 0x00000000007c4242, 0x4242427c40404000,
|
|
0x00000000003e4242, 0x4242423e02020200, 0x00000000005e6040, 0x4040404000000000, 0x00000000003e4040, 0x3c02027c00000000,
|
|
0x00001010107c1010, 0x1010100e00000000, 0x0000000000424242, 0x4242423e00000000, 0x0000000000424242, 0x2424181800000000,
|
|
0x0000000000828292, 0x9292927c00000000, 0x0000000000424224, 0x1824424200000000, 0x0000000000424242, 0x4242423e02023c00,
|
|
0x00000000007e0408, 0x1020407e00000000, 0x00000c1010102010, 0x1010100c00000000, 0x0000101010101010, 0x1010101000000000,
|
|
0x0000300808080408, 0x0808083000000000, 0x000000000062928c, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000
|
|
};
|
|
|
|
for (natural_64 index = 0; index < 2; ++index) {
|
|
for (natural_64 bit = 64; bit > 0; --bit) {
|
|
natural_64 destination = (* y + (index << 3) - ((bit - 1) >> 3) + 7) * render_width + (* x - ((bit - 1) & 7) + 7);
|
|
natural_64 source = (glyphmap [2 * (natural_64) (data - ' ') + index] >> (bit - 1)) & 1;
|
|
|
|
render_image [destination] = (source) ? colour : background;
|
|
}
|
|
}
|
|
|
|
* x += font_width;
|
|
}
|
|
|
|
static procedure render_string (character * string, natural length, natural * x, natural * y, natural colour) {
|
|
for (natural offset = 0; offset < length; ++offset) {
|
|
if (string [offset] == '\t') {
|
|
* x += font_width * tab_width;
|
|
} else if (string [offset] == '\n') {
|
|
* y += font_height;
|
|
* x = render_border;
|
|
|
|
render_string (format_to_string ((int) ++line_number, false, 10, (int) line_digits, ' '),
|
|
line_digits, x, y, foreground);
|
|
|
|
* x += font_width;
|
|
} else {
|
|
render_character (string [offset], x, y, colour);
|
|
}
|
|
}
|
|
}
|
|
|
|
integer main (integer argc, character * * argv) {
|
|
natural select = language_count;
|
|
natural offset = 0;
|
|
natural length = 0;
|
|
natural x = render_border;
|
|
natural y = render_border;
|
|
character * buffer = null;
|
|
character * dump = null;
|
|
|
|
syntax_structure * syntax = syntax_initialize (666);
|
|
language_structure * language = language_initialize (true);
|
|
|
|
for (integer argument = 1; argument < argc; ++argument) {
|
|
if (argument_compare (argv [argument], "-h", "--help") == true) {
|
|
print_help ();
|
|
conditionally_exit (language, syntax, true);
|
|
} else if (argument_compare (argv [argument], "-v", "--version") == true) {
|
|
print_version ();
|
|
conditionally_exit (language, syntax, true);
|
|
} else if (argument_compare (argv [argument], "-o", "--output") == true) {
|
|
if (argument + 1 >= argc) {
|
|
print ("/f Expected output file name: /1%s/-\n", argv [argument]);
|
|
conditionally_exit (language, syntax, true);
|
|
}
|
|
++argument;
|
|
dump = string_duplicate (argv [argument]);
|
|
continue;
|
|
}
|
|
|
|
for (natural index = 0; index < language_count; ++index) {
|
|
if (argument_compare (argv [argument], language_short_option [index], language_long_option [index]) == true) {
|
|
(* (language_highlighter [index])) (language, syntax);
|
|
select = index;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (file_exists (argv [argument]) == true) {
|
|
if (select == language_count) {
|
|
select = (natural) file_type (argv [argument]);
|
|
}
|
|
if (buffer == null) {
|
|
buffer = file_import (argv [argument]);
|
|
} continue;
|
|
} else {
|
|
print ("/f Unrecognized command line argument: /1%s/-\n", argv [argument]);
|
|
conditionally_exit (language, syntax, true);
|
|
}
|
|
}
|
|
|
|
if (dump == null) {
|
|
dump = string_duplicate ("xarbon.png");
|
|
}
|
|
|
|
if (buffer == null) {
|
|
buffer = record ();
|
|
}
|
|
|
|
language_conditionally_select (language, syntax, select);
|
|
|
|
render_width = fetch_width (buffer) * font_width + 2 * render_border;
|
|
render_height = fetch_height (buffer) * font_height + 2 * render_border;
|
|
|
|
render_width += (line_digits + 1) * font_width;
|
|
|
|
render_image = allocate (render_width * render_height * sizeof (* render_image));
|
|
|
|
for (offset = 0; offset < render_width * render_height; ++offset) {
|
|
render_image [offset] = background;
|
|
}
|
|
|
|
render_string (format_to_string ((int) ++line_number, false, 10, (int) line_digits, ' '), line_digits, & x, & y, foreground);
|
|
|
|
x += font_width;
|
|
|
|
for (offset = 0; buffer [offset] != '\0'; offset += length) {
|
|
select = syntax_select (syntax, & buffer [offset], & length);
|
|
|
|
render_string (& buffer [offset], length, & x, & y, (select >= syntax->count) ? background : (natural) syntax->colour [select]);
|
|
}
|
|
|
|
png_image_export (dump, render_image, render_width, render_height);
|
|
|
|
conditionally_exit (language, syntax, false);
|
|
|
|
render_image = deallocate (render_image);
|
|
buffer = deallocate (buffer);
|
|
dump = deallocate (dump);
|
|
|
|
return (log_success);
|
|
}
|