The fundamentals of the new ctypes interface are working

This commit is contained in:
jaseg 2014-02-16 11:57:21 +01:00
parent 900a9c38e3
commit 9934f27cc1
7 changed files with 90 additions and 17 deletions

View file

@ -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

View file

@ -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, &current_glyph, sizeof(glyph_t));
glyph_table->data[encoding] = glyph_data;

View file

@ -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);

View file

@ -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;
}

View file

@ -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
View 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
View 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'));