Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
77773798
Commit
77773798
authored
Sep 11, 2018
by
antirez
Browse files
LOLWUT: Rendering of the virtual canvas to a string.
parent
096c74c8
Changes
1
Hide whitespace changes
Inline
Side-by-side
src/lolwut.c
View file @
77773798
...
@@ -33,16 +33,18 @@
...
@@ -33,16 +33,18 @@
* each new version of Redis.
* each new version of Redis.
*/
*/
#include "server.h"
/* This function represents our canvas. Drawing functions will take a pointer
/* 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
* 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. */
* suitable to be printed on the screen, using unicode Braille characters. */
struct
lwCanvas
{
typedef
struct
lwCanvas
{
int
width
;
int
width
;
int
height
;
int
height
;
char
*
pixels
;
char
*
pixels
;
};
}
lwCanvas
;
/* Translate a group of 8 pixels (2x
8
vertical rectangle) to the corresponding
/* Translate a group of 8 pixels (2x
4
vertical rectangle) to the corresponding
* braille character. The byte should correspond to the pixels arranged as
* braille character. The byte should correspond to the pixels arranged as
* follows, where 0 is the least significant bit, and 7 the most significant
* follows, where 0 is the least significant bit, and 7 the most significant
* bit:
* bit:
...
@@ -56,14 +58,83 @@ struct lwCanvas {
...
@@ -56,14 +58,83 @@ struct lwCanvas {
* pointed by 'output'.
* pointed by 'output'.
*/
*/
#include <stdio.h>
#include <stdio.h>
void
lw
Emit
PixelsGroup
(
int
byte
,
char
*
output
)
{
void
lw
Translate
PixelsGroup
(
int
byte
,
char
*
output
)
{
int
code
=
0x2800
+
byte
;
int
code
=
0x2800
+
byte
;
/* Convert to unicode. This is in the U0800-UFFFF range, so we need to
/* Convert to unicode. This is in the U0800-UFFFF range, so we need to
* emit it like this in three bytes:
* emit it like this in three bytes:
* 1110xxxx 10xxxxxx 10xxxxxx. */
* 1110xxxx 10xxxxxx 10xxxxxx. */
output
[
1
]
=
0xE0
|
(
code
>>
12
);
/* 1110-xxxx */
output
[
0
]
=
0xE0
|
(
code
>>
12
);
/* 1110-xxxx */
output
[
2
]
=
0x80
|
((
code
>>
6
)
&
0x3F
);
/* 10-xxxxxx */
output
[
1
]
=
0x80
|
((
code
>>
6
)
&
0x3F
);
/* 10-xxxxxx */
output
[
3
]
=
0x80
|
(
code
&
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
);
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment