summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez@gmail.com>2018-09-11 17:32:57 +0200
committerantirez <antirez@gmail.com>2018-09-11 17:32:57 +0200
commit7777379814a3e3b64bbc30d07ffb366ce9240759 (patch)
treea44ba433a67a26b797c7a98d7eb331ec4ce2933b
parent096c74c8867fd1ae3f9f91320750fd8ae5d58218 (diff)
downloadredis-7777379814a3e3b64bbc30d07ffb366ce9240759.tar.gz
LOLWUT: Rendering of the virtual canvas to a string.
-rw-r--r--src/lolwut.c85
1 files changed, 78 insertions, 7 deletions
diff --git a/src/lolwut.c b/src/lolwut.c
index 6047da294..a6fa86832 100644
--- a/src/lolwut.c
+++ b/src/lolwut.c
@@ -33,16 +33,18 @@
* each new version of Redis.
*/
+#include "server.h"
+
/* This function represents our canvas. Drawing functions will take a pointer
* to a canvas to write to it. Later the canvas can be rendered to a string
* suitable to be printed on the screen, using unicode Braille characters. */
-struct lwCanvas {
+typedef struct lwCanvas {
int width;
int height;
char *pixels;
-};
+} lwCanvas;
-/* Translate a group of 8 pixels (2x8 vertical rectangle) to the corresponding
+/* Translate a group of 8 pixels (2x4 vertical rectangle) to the corresponding
* braille character. The byte should correspond to the pixels arranged as
* follows, where 0 is the least significant bit, and 7 the most significant
* bit:
@@ -56,14 +58,83 @@ struct lwCanvas {
* pointed by 'output'.
*/
#include <stdio.h>
-void lwEmitPixelsGroup(int byte, char *output) {
+void lwTranslatePixelsGroup(int byte, char *output) {
int code = 0x2800 + byte;
/* Convert to unicode. This is in the U0800-UFFFF range, so we need to
* emit it like this in three bytes:
* 1110xxxx 10xxxxxx 10xxxxxx. */
- output[1] = 0xE0 | (code >> 12); /* 1110-xxxx */
- output[2] = 0x80 | ((code >> 6) & 0x3F); /* 10-xxxxxx */
- output[3] = 0x80 | (code & 0x3F); /* 10-xxxxxx */
+ output[0] = 0xE0 | (code >> 12); /* 1110-xxxx */
+ output[1] = 0x80 | ((code >> 6) & 0x3F); /* 10-xxxxxx */
+ output[2] = 0x80 | (code & 0x3F); /* 10-xxxxxx */
+}
+
+/* Allocate and return a new canvas of the specified size. */
+lwCanvas *lwCreateCanvas(int width, int height) {
+ lwCanvas *canvas = zmalloc(sizeof(*canvas));
+ canvas->width = width;
+ canvas->height = height;
+ canvas->pixels = zmalloc(width*height);
+ memset(canvas->pixels,0,width*height);
+ return canvas;
}
+/* Free the canvas created by lwCreateCanvas(). */
+void lwFreeCanvas(lwCanvas *canvas) {
+ zfree(canvas->pixels);
+ zfree(canvas);
+}
+
+/* Set a pixel to the specified color. Color is 0 or 1, where zero means no
+ * dot will be displyed, and 1 means dot will be displayed.
+ * Coordinates are arranged so that left-top corner is 0,0. You can write
+ * out of the size of the canvas without issues. */
+void lwPutPixel(lwCanvas *canvas, int x, int y, int color) {
+ if (x < 0 || x >= canvas->width ||
+ y < 0 || y >= canvas->height) return;
+ canvas->pixels[x+y*canvas->width] = color;
+}
+/* Return the value of the specified pixel on the canvas. */
+int lwGetPixel(lwCanvas *canvas, int x, int y) {
+ if (x < 0 || x >= canvas->width ||
+ y < 0 || y >= canvas->height) return 0;
+ return canvas->pixels[x+y*canvas->width];
+}
+
+/* Converts the canvas to an SDS string representing the UTF8 characters to
+ * print to the terminal in order to obtain a graphical representaiton of the
+ * logical canvas. The actual returned string will require a terminal that is
+ * width/2 large and height/4 tall in order to hold the whole image without
+ * overflowing or scrolling, since each Barille character is 2x4. */
+sds lwRenderCanvas(lwCanvas *canvas) {
+ sds text = sdsempty();
+ for (int y = 0; y < canvas->height; y += 4) {
+ for (int x = 0; x < canvas->width; x += 2) {
+ /* We need to emit groups of 8 bits according to a specific
+ * arrangement. See lwTranslatePixelsGroup() for more info. */
+ int byte = 0;
+ if (lwGetPixel(canvas,x,y)) byte |= (1<<0);
+ if (lwGetPixel(canvas,x,y+1)) byte |= (1<<1);
+ if (lwGetPixel(canvas,x,y+2)) byte |= (1<<2);
+ if (lwGetPixel(canvas,x+1,y)) byte |= (1<<3);
+ if (lwGetPixel(canvas,x+1,y+1)) byte |= (1<<4);
+ if (lwGetPixel(canvas,x+1,y+2)) byte |= (1<<5);
+ if (lwGetPixel(canvas,x,y+3)) byte |= (1<<6);
+ if (lwGetPixel(canvas,x+1,y+3)) byte |= (1<<7);
+ char unicode[3];
+ lwTranslatePixelsGroup(byte,unicode);
+ text = sdscatlen(text,unicode,3);
+ }
+ if (y != canvas->height-1) text = sdscatlen(text,"\n",1);
+ }
+ return text;
+}
+
+int main(void) {
+ lwCanvas *c = lwCreateCanvas(80,80);
+ for (int i = 0; i < 40; i++) {
+ lwPutPixel(c,i,i,1);
+ }
+ sds rendered = lwRenderCanvas(c);
+ printf("%s\n", rendered);
+}