add text out capabilities using FreeType and the Inconsolata font

This commit is contained in:
Amy G. Bowersox 2019-12-07 23:30:05 -07:00
parent 2cfb92d97b
commit 30106490c0
8 changed files with 146 additions and 3 deletions

View File

@ -19,3 +19,4 @@ upiwin_tmp.filled_rectangle(110, 60, 150, 100, FBPRIMCLR_YELLOW, False)
upiwin_tmp.rectangle(10, 110, 150, 150, FBPRIMCLR_WHITE, False)
upiwin_tmp.line(10, 110, 150, 150, FBPRIMCLR_WHITE, False)
upiwin_tmp.line(10, 150, 150, 110, FBPRIMCLR_WHITE, False)
upiwin_tmp.textout(10, 180, 'Amy was here!!!')

View File

@ -1,7 +1,8 @@
OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_upiwin_tmp.o ep_util.o fbinit.o fbprimitive.o \
OBJS=main.o sysinput.o ep_init.o ep_upiwin.o ep_backlight.o ep_upiwin_tmp.o ep_util.o fbinit.o fontengine.o 6fbprimitive.o \
log.o gpio.o msg_queue.o time_func.o config.o splash.o
LIBS=-lpython3.7m -lcrypt -lbcm2835 -lpthread -ldl -lutil -lm
CFLAGS=-I/usr/include/python3.7m -Wall -fstack-protector -fwrapv -fno-PIE -g -O3 -DDEBUG_ASSERT
LIBS=-lpython3.7m -lcrypt -lfreetype -lbcm2835 -lpthread -ldl -lutil -lm
CFLAGS=-I/usr/include/python3.7m -I/usr/include/freetype2 -I/usr/include/libpng16 \
-Wall -fstack-protector -fwrapv -fno-PIE -g -O3 -DDEBUG_ASSERT
LDFLAGS=-L/usr/lib/python3.7/config-3.7m-arm-linux-gnueabihf -Xlinker -export-dynamic -Wl,-O1 \
-Wl,-Bsymbolic-functions

View File

@ -52,11 +52,23 @@ static PyObject *do_filled_rectangle(PyObject *self, PyObject *args)
Py_RETURN_NONE;
}
static PyObject *do_textout(PyObject *self, PyObject *args)
{
INT32 x, y;
PSTR text;
if (!PyArg_ParseTuple(args, "iis", &x, &y, &text))
return NULL;
Fb_textout(x, y, text);
Py_RETURN_NONE;
}
static PyMethodDef UPIWIN_tmpMethods[] = {
{"setpixel", do_setpixel, METH_VARARGS, "Set a single pixel on the display."},
{"line", do_line, METH_VARARGS, "Draw a line on the display."},
{"rectangle", do_rectangle, METH_VARARGS, "Draw a rectangle on the display."},
{"filled_rectangle", do_filled_rectangle, METH_VARARGS, "Draw a filled rectangle on the display."},
{"textout", do_textout, METH_VARARGS, "Draw text on the display."},
{NULL, NULL, 0, NULL}
};

View File

@ -1,3 +1,4 @@
#include <alloca.h>
#include "wintype.h"
#include "fbinit.h"
@ -112,3 +113,33 @@ void Fb_filled_rectangle(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, B
ps += Fb_Info->width;
}
}
static void internal_textout(INT32 x, INT32 y, INT32 width, INT32 height, PBYTE gsbits)
{
INT32 i, j;
BYTE b;
PUINT16 dptr, lbuf;
if (((x + width) >= Fb_Info->width) || ((y + height) >= Fb_Info->height))
return;
dptr = loc_from_coords(x, y);
lbuf = (PUINT16)alloca(width * sizeof(UINT16));
for (i=0; i<height; i++)
{
for (j=0; j<width; j++)
{
b = *gsbits++;
lbuf[i] = ((UINT16)(b >> 3) & 0x1F) << 11;
lbuf[i] |= ((UINT16)(b >> 2) & 0x3F) << 5;
lbuf[i] |= ((UINT16)(b >> 3) & 0x1F);
}
memcpy(dptr, lbuf, width * sizeof(UINT16));
dptr += Fb_Info->width;
}
}
void Fb_textout(INT32 x, INT32 y, PCSTR pstr)
{
FontEng_do_text_out(x, y, pstr, internal_textout);
}

View File

@ -17,5 +17,6 @@ extern UINT16 Fb_setpixel(INT32 x, INT32 y, UINT16 color, BOOL xor);
extern void Fb_line(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor);
extern void Fb_rectangle(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor);
extern void Fb_filled_rectangle(INT32 x1, INT32 y1, INT32 x2, INT32 y2, UINT16 color, BOOL xor);
extern void Fb_textout(INT32 x, INT32 y, PCSTR pstr);
#endif /* __FBPRIMITIVE_H_INCLUDED */

84
src/fontengine.c Normal file
View File

@ -0,0 +1,84 @@
#include <ft2build.h>
#include FT_FREETYPE_H
#include "scode.h"
#include "config.h"
#include "log.h"
#include "fontengine.h"
static FT_LIbrary library;
static FT_Face stdfont;
static void fonteng_cleanup(void)
{
FT_Done_Face(stdfont);
FT_Done_FreeType(library);
}
HRESULT FontEng_setup(void)
{
HRESULT hr = S_OK;
FT_Error err;
err = FT_Init_FreeType(&library);
if (err != 0)
{
Log(LFATAL, "Unable to initialize Freetype (%d)", err);
return E_FAIL;
}
err = FT_New_Face(library, "/usr/local/share/fonts/opentype/Inconsolata.otf", 0, &stdfont);
if (err != 0)
{
Log(LFATAL, "Unable to load font (%d)", err);
hr = E_FAIL;
goto error_0;
}
err = FT_Set_Pixel_Sizes(stdfont, 0, 16);
if (err != 0)
{
Log(LFATAL, "Unable to set font size (%d)", err);
hr = E_FAIL;
goto error_1;
}
hr = Config_exitfunc(fonteng_cleanup);
if (FAILED(hr))
fonteng_cleanup();
return hr;
error_1:
FT_Done_Face(stdfont);
error_0:
FT_Done_FreeType(library);
return hr;
}
HRESULT FontEng_do_text_out(INT32 x, INT32 y, PCSTR pstr, TEXTOUTFUNC renderfunc)
{
HRESULT hr = S_OK;
FT_GlyphSlot slot = stdfont->glyph;
FT_UInt glyph_index;
FT_Error err;
while (*pstr)
{
glyph_index = FT_Get_Char_Index(stdfont, *pstr++);
err = FT_Load_Glyph(stdfont, glyph_index, FT_LOAD_DEFAULT);
if (err != 0)
{
hr = E_FAIL;
break;
}
err = FT_Render_Glyph(stdfont->glyph, FT_RENDER_MODE_NORMAL);
if (err != 0)
{
hr = E_FAIL;
break;
}
(*renderfunc)(x, y, slot->bitmap.width, slot->bitmap.rows, slot->bitmap.buffer);
x += slot->advance.x >> 6;
y += slot->advance.y >> 6;
}
return hr;
}

11
src/fontengine.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef __FONTENGINE_H_INCLUDED
#define __FONTENGINE_H_INCLUDED
#include "wintype.h"
typedef void (*TEXTOUTFUNC)(INT32 x, INT32 y, INT32 width, INT32 height, PBYTE gsbits);
extern HRESULT FontEng_setup(void);
extern HRESULT FontEng_do_text_out(INT32 x, INT32 y, PCSTR pstr, TEXTOUTFUNC renderfunc);
#endif /* __FONTENGINE_H_INCLUDED */

View File

@ -31,6 +31,8 @@ int main(int argc, char *argv[])
return EXIT_SUCCESS;
if (FAILED(Fb_setup()))
return EXIT_FAILURE;
if (FAILED(FontEng_setup()))
return EXIT_FAILURE;
if (FAILED(Gpio_setup()))
return EXIT_FAILURE;
if (FAILED(Epython_setup()))