The fundamentals of the new ctypes interface are working
This commit is contained in:
parent
900a9c38e3
commit
9934f27cc1
7 changed files with 90 additions and 17 deletions
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
all: main.c font.c font.h color.c color.h gif.h gif.c
|
||||
gcc -shared -std=gnu11 -Wall -lm -o libbdf.so -g -O0 main.c font.c color.c
|
||||
all: main.c font.c font.h color.c color.h
|
||||
gcc -shared -fPIC -std=gnu11 -Wall -lm -o libbdf.so -g -O0 main.c font.c color.c
|
||||
|
||||
clean:
|
||||
rm libbdf.so
|
||||
|
|
|
|||
26
host/font.c
26
host/font.c
|
|
@ -4,6 +4,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
void render_glyph(glyph_t *g, color_t *buf, unsigned int bufwidth, unsigned int offx, unsigned int offy, color_t fg, color_t bg){
|
||||
unsigned int bitmap_row_width = g->width/8;
|
||||
|
|
@ -30,7 +31,7 @@ glyphtable_t *read_bdf_file(char *filename){
|
|||
goto error;
|
||||
}
|
||||
|
||||
glyphtable_t *glyph_table = read_bdf(fontfile, glyph_table, BLP_SIZE)
|
||||
glyphtable_t *glyph_table = read_bdf(fontfile);
|
||||
if(!glyph_table){
|
||||
fprintf(stderr, "Error reading font file.\n");
|
||||
goto error;
|
||||
|
|
@ -50,15 +51,16 @@ glyphtable_t *extend_glyphtable(glyphtable_t *glyph_table){
|
|||
size_t newlen = oldlen + (oldlen<MAX_GLYPHTABLE_INCREMENT ? oldlen : MAX_GLYPHTABLE_INCREMENT);
|
||||
if(oldlen == 0)
|
||||
newlen = START_GLYPHTABLE_SIZE;
|
||||
glyph_t *newdata = realloc(glyph_table->data, newlen*sizeof(glyph_t));
|
||||
glyph_t **newdata = realloc(glyph_table->data, newlen*sizeof(glyph_t*));
|
||||
if(!newdata){
|
||||
fprintf(stderr, "Cannot allocate bdf glyph buffer\n");
|
||||
goto error;
|
||||
}
|
||||
glyph_table->data = newdata;
|
||||
// Clear newly allocated memory area
|
||||
memset(glyph_table->data+oldlen, 0, (newlen-oldlen)*sizeof(glyph_t));
|
||||
memset(glyph_table->data+oldlen, 0, (newlen-oldlen)*sizeof(glyph_t*));
|
||||
glyph_table->size = newlen;
|
||||
return glyph_table;
|
||||
error:
|
||||
free_glyphtable(glyph_table);
|
||||
return NULL;
|
||||
|
|
@ -66,7 +68,7 @@ error:
|
|||
|
||||
void free_glyphtable(glyphtable_t *glyph_table){
|
||||
if(glyph_table){
|
||||
for(unsigned int i=0; i<glyph_table->length; i++){
|
||||
for(unsigned int i=0; i<glyph_table->size; i++){
|
||||
free(glyph_table->data[i]);
|
||||
}
|
||||
free(glyph_table->data);
|
||||
|
|
@ -119,13 +121,6 @@ glyphtable_t *read_bdf(FILE *f){
|
|||
fprintf(stderr, "Invalid ENCODING line: %s %s\n", line, args);
|
||||
goto error;
|
||||
}
|
||||
if(encoding > glyph_table->size){
|
||||
glyph_table = extend_glyphtable(glyph_table);
|
||||
if(!glyph_table){
|
||||
fprintf(stderr, "Cannot allocate glyph table.\n");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
}else if(strcmp("BBX", line) == 0){
|
||||
if(!args){
|
||||
|
|
@ -228,6 +223,15 @@ glyphtable_t *read_bdf(FILE *f){
|
|||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
if(encoding >= glyph_table->size){
|
||||
glyph_table = extend_glyphtable(glyph_table);
|
||||
if(!glyph_table){
|
||||
fprintf(stderr, "Cannot extend glyph table.\n");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(glyph_data, ¤t_glyph, sizeof(glyph_t));
|
||||
glyph_table->data[encoding] = glyph_data;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ typedef struct {
|
|||
} glyph_t;
|
||||
|
||||
typedef struct {
|
||||
glyph_t *t;
|
||||
glyph_t **data;
|
||||
size_t size;
|
||||
} glyphtable_t;
|
||||
|
||||
|
|
@ -25,7 +25,9 @@ typedef struct {
|
|||
#define MAX_CSI_ELEMENTS 8
|
||||
|
||||
// We could also use some fancy hashtable here, but unifont includes about 57k glyphs so we would hardly save any memory.
|
||||
int read_bdf(FILE *f, glyph_t **glyph_table, unsigned int glyph_table_size);
|
||||
glyphtable_t *read_bdf(FILE *f);
|
||||
|
||||
void free_glyphtable(glyphtable_t *glyph_table);
|
||||
|
||||
// Requires buf to point to a buffer at least of size glyph->width*glyph->height.
|
||||
void render_glyph(glyph_t *glyph, color_t *buf, unsigned int bufwidth, unsigned int offx, unsigned int offy, color_t fg, color_t bg);
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ framebuffer_t *framebuffer_render_text(char *s, glyphtable_t *glyph_table){
|
|||
p += inc;
|
||||
|
||||
if(c > glyph_table->size){
|
||||
fprintf(stderr, "Error rendering string: Codepoint 0x%lx out of valid range (0-%d).\n", (long int)c, glyph_table->size);
|
||||
fprintf(stderr, "Error rendering string: Codepoint 0x%lx out of valid range (0-%ld).\n", (long int)c, glyph_table->size);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
#include "color.h"
|
||||
#include "font.h"
|
||||
|
||||
framebuffer_t *framebuffer_render_text(char *s, glyph_t **glyph_table, unsigned int glyph_table_size);
|
||||
framebuffer_t *framebuffer_render_text(char *s, glyphtable_t *glyph_table);
|
||||
void console_render_buffer(framebuffer_t *fb);
|
||||
|
||||
#endif//__MAIN_H__
|
||||
|
|
|
|||
35
host/matelight.py
Normal file
35
host/matelight.py
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
import usb
|
||||
import colorsys
|
||||
import numpy as np
|
||||
import itertools
|
||||
|
||||
CRATE_WIDTH = 5
|
||||
CRATE_HEIGHT = 4
|
||||
CRATES_X = 8
|
||||
CRATES_Y = 4
|
||||
|
||||
DISPLAY_WIDTH = CRATES_X*CRATE_WIDTH
|
||||
DISPLAY_HEIGHT = CRATES_Y*CRATE_HEIGHT
|
||||
FRAME_SIZE = CRATE_WIDTH*CRATE_HEIGHT*3
|
||||
|
||||
dev = usb.core.find(idVendor=0x1cbe, idProduct=0x0003)
|
||||
|
||||
def sendframe(framedata):
|
||||
""" Send a frame to the display
|
||||
|
||||
The argument contains a h * w array of 3-tuples of (r, g, b)-data or 4-tuples of (r, g, b, a)-data where the a
|
||||
channel is ignored.
|
||||
"""
|
||||
def chunks(l, n):
|
||||
for i in xrange(0, len(l), n):
|
||||
yield l[i:i+n]
|
||||
|
||||
for cx, cy in itertools.product(range(DISPLAY_WIDTH), range(DISPLAY_HEIGHT)):
|
||||
data = [ v for x in range(CRATE_WIDTH) for y in range(CRATE_HEIGHT) for v in framedata[cy*CRATE_HEIGHT + y][cx*CRATE_WIDTH + x][:3] ]
|
||||
if len(data) != FRAME_SIZE:
|
||||
raise ValueError('Invalid frame data. Expected {} bytes, got {}.'.format(FRAME_SIZE, len(data)))
|
||||
# Send framebuffer data
|
||||
dev.write(0x01, bytes([0, x, y])+bytes(data))
|
||||
# Send latch command
|
||||
dev.write(0x01, b'\x01')
|
||||
|
||||
32
host/server.py
Executable file
32
host/server.py
Executable file
|
|
@ -0,0 +1,32 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from ctypes import CDLL, POINTER, c_void_p, Structure, c_uint8, c_size_t, cast
|
||||
import numpy as np
|
||||
from matelight import sendframe
|
||||
|
||||
class COLOR(Structure):
|
||||
_fields_ = ('r', c_uint8), ('g', c_uint8), ('b', c_uint8), ('a', c_uint8)
|
||||
|
||||
class FRAMEBUFFER(Structure):
|
||||
_fields_ = ('data', POINTER(COLOR)), ('w', c_size_t), ('h', c_size_t)
|
||||
|
||||
bdf = CDLL('./libbdf.so')
|
||||
bdf.read_bdf_file.restype = c_void_p
|
||||
bdf.framebuffer_render_text.restype = POINTER(FRAMEBUFFER)
|
||||
|
||||
unifont = bdf.read_bdf_file('unifont.bdf')
|
||||
|
||||
def render_text(text):
|
||||
assert unifont
|
||||
fb = bdf.framebuffer_render_text(str(text), unifont)
|
||||
fbd = fb.contents
|
||||
buf = np.ctypeslib.as_array(cast(fbd.data, POINTER(c_uint8)), shape=(fbd.h, fbd.w, 4))
|
||||
# Set data pointer to NULL before freeing framebuffer struct to prevent free_framebuffer from also freeing the data
|
||||
# buffer that is now used by numpy
|
||||
fb.data = cast(c_void_p(), POINTER(COLOR))
|
||||
bdf.free_framebuffer(fb)
|
||||
return buf
|
||||
|
||||
if __name__ == '__main__':
|
||||
sendframe(render_text('test'));
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue