oswald/ui/oswald_graphics.c

247 lines
6.6 KiB
C
Raw Normal View History

2021-02-14 18:03:13 +01:00
#include "oswald.h"
#include "oswald_strings.h"
#include "oswald_fonts.h"
#include "oswald_hal.h"
#include "oswald_graphics.h"
#if 0
void oswald_draw_pixel(const unsigned int xstart, const unsigned int ystart, uint8_t color)
{
hal_lcd_set_pixel(xstart, ystart, TRUE);
}
#endif
void oswald_draw_bitmap_opts(const unsigned int xstart, const unsigned int ystart,
const unsigned int xoff, const unsigned int yoff,
const unsigned int width, const unsigned int height,
const boolean invert,
const unsigned int bmp_width, const unsigned int bmp_height,
const void *bmp)
{
unsigned int x, y;
uint8_t *cb;
if (bmp == NULL)
return;
//g_printerr("dbmp %d,%d off %d,%d\n", xstart, ystart, width, height);
cb = (uint8_t *)bmp;
//g_printerr("dat %02x %02x %02x\n", (uint8_t)cb[0], (uint8_t)cb[1], (uint8_t)cb[2]);
// we only draw set pixel, unset pixel remain as they are
for (y=yoff; y<bmp_height && y<height; y++) {
for (x=xoff; x<bmp_width && x<width; x++) {
cb = (uint8_t *)(bmp + (y * ((bmp_width / 8) + ((bmp_width % 8) ? 1 : 0))) + (x / 8));
// g_printerr("dat %02x %02x %02x\n", (uint8_t)cb[0], (uint8_t)cb[1], (uint8_t)cb[2]);
if (*cb & (1 << (x % 8))) {
if (!invert)
hal_lcd_set_pixel((xstart + x) - xoff, (ystart + y) - yoff, TRUE);
// g_printerr("X");
} else {
if (invert)
hal_lcd_set_pixel((xstart + x) - xoff, (ystart + y) - yoff, TRUE);
// g_printerr(".");
}
}
//g_printerr("\n");
}
}
void oswald_draw_line(const uint8_t xstart, const uint8_t ystart, const uint8_t xend, const uint8_t yend)
{
int x, y, t, dx, dy, incx, incy, pdx, pdy, ddx, ddy, es, el, err;
dx = xend - xstart;
dy = yend - ystart;
incx = (dx >= 0) ? 1 : -1;
incy = (dy >= 0) ? 1 : -1;
if (dx<0)
dx = -dx;
if (dy<0)
dy = -dy;
if (dx>dy) {
pdx = incx; pdy = 0;
ddx=incx; ddy=incy;
es =dy; el =dx;
} else {
pdx=0; pdy=incy;
ddx=incx; ddy=incy;
es =dx; el =dy;
}
x = xstart;
y = ystart;
err = el/2;
hal_lcd_set_pixel(x, y, TRUE);
for (t = 0; t < el; ++t) {
err -= es;
if (err < 0) {
err += el;
x += ddx;
y += ddy;
} else {
x += pdx;
y += pdy;
}
hal_lcd_set_pixel(x, y, TRUE);
}
}
void oswald_draw_line_ww(const uint8_t xstart, const uint8_t ystart, const uint8_t xend, const uint8_t yend, const uint8_t thickness)
{
int16_t i, x, y, t, dx, dy, incx, incy, pdx, pdy, ddx, ddy, es, el, err;
dx = xend - xstart;
dy = yend - ystart;
incx = (dx >= 0) ? 1 : -1;
incy = (dy >= 0) ? 1 : -1;
if (dx<0)
dx = -dx;
if (dy<0)
dy = -dy;
if (dx>dy) {
pdx = incx;
pdy = 0;
ddx = incx;
ddy = incy;
es = dy;
el = dx;
} else {
pdx = 0;
pdy = incy;
ddx = incx;
ddy = incy;
es = dx;
el = dy;
}
x = xstart;
y = ystart;
err = el/2;
hal_lcd_set_pixel(x, y, TRUE);
for (i=1; i<thickness; i++) {
hal_lcd_set_pixel(x-i, y, TRUE);
hal_lcd_set_pixel(x+i, y, TRUE);
hal_lcd_set_pixel(x, y-i, TRUE);
hal_lcd_set_pixel(x, y+i, TRUE);
}
for (t = 0; t < el; ++t) {
err -= es;
if (err < 0) {
err += el;
x += ddx;
y += ddy;
} else {
x += pdx;
y += pdy;
}
hal_lcd_set_pixel(x, y, TRUE);
for (i=1; i<thickness; i++) {
hal_lcd_set_pixel(x-i, y, TRUE);
hal_lcd_set_pixel(x+i, y, TRUE);
hal_lcd_set_pixel(x, y-i, TRUE);
hal_lcd_set_pixel(x, y+i, TRUE);
}
}
}
uint8_t oswald_write_character(const uint8_t x, const uint8_t y, const oswald_font_face face, const boolean invert, const uint8_t Character)
{
uint8_t *cdata = oswald_fonts[face].data;
uint8_t cwidth;
int csize;
// if (Character == 32) { // space, blank no need to draw one ;)
// return oswald_fonts[face].width / 2;
// }
csize = ((oswald_fonts[face].width / 8) + ((oswald_fonts[face].width % 8) ? 1 : 0)) * oswald_fonts[face].height;
if (oswald_fonts[face].font_type == FONT_TYPE_PROPORTIONAL)
csize += 1; // at least 1px spacing
//csize += (oswald_fonts[face].height / 8) + ((oswald_fonts[face].height % 8) ? 1 : 0);
// g_printerr("fp = 0x%08lx cdata = 0x%08lx\n", font_7x12, cdata);
cdata = (cdata + ((int)csize * (int)Character));
//g_printerr("%02x\n", oswald_fonts[face].data[0][0]);
//g_printerr("char %02x face %d %dx%d csize %d\n", Character, face, oswald_fonts[face].width, oswald_fonts[face].height, csize);
//g_printerr("char %02x %02x %02x\n", (uint8_t)cdata[0], (uint8_t)cdata[1], (uint8_t)cdata[2]);
// oswald_draw_bitmap(x, y, oswald_fonts[face].height, oswald_fonts[face].height, cdata);
if (oswald_fonts[face].font_type == FONT_TYPE_MONOSPACE) {
cwidth = oswald_fonts[face].width;
//oswald_draw_bitmap(x, y, ((oswald_fonts[face].width / 8) + ((oswald_fonts[face].width % 8) ? 1 : 0)) * 8, oswald_fonts[face].height, (uint8_t *)cdata);
oswald_draw_bitmap_opts(x,y,0,0,((oswald_fonts[face].width / 8) + ((oswald_fonts[face].width % 8) ? 1 : 0)) * 8,oswald_fonts[face].height,invert,((oswald_fonts[face].width / 8) + ((oswald_fonts[face].width % 8) ? 1 : 0)) * 8,oswald_fonts[face].height,(uint8_t *)cdata);
} else if (oswald_fonts[face].font_type == FONT_TYPE_PROPORTIONAL) {
cwidth = cdata[0];
cdata++;
// oswald_draw_bitmap_size(x, y, (cwidth+1), oswald_fonts[face].height, ((oswald_fonts[face].width / 8) + ((oswald_fonts[face].width % 8) ? 1 : 0))*8, oswald_fonts[face].height, (uint8_t *)cdata);
oswald_draw_bitmap_opts(x,y,0,0,(cwidth+1),oswald_fonts[face].height,invert,((oswald_fonts[face].width / 8) + ((oswald_fonts[face].width % 8) ? 1 : 0))*8,oswald_fonts[face].height,(uint8_t *)cdata);
} else {
cwidth = 0;
}
// oswald_draw_bitmap_offset(x, y, (oswald_fonts[face].width % 8) > 0 ? (8-(oswald_fonts[face].width % 8)) : 0, 0, ((oswald_fonts[face].width / 8) + ((oswald_fonts[face].width % 8) ? 1 : 0))*8, oswald_fonts[face].height, cdata);
return cwidth;
}
void oswald_write_string(const uint8_t x, const uint8_t y, const oswald_font_face face, const boolean invert, char *str)
{
uint8_t lx, i, strl;
strl = oswald_strlen(str);
if (strl == 0)
return;
lx = x;
for (i=0; i<strl; i++) {
lx += oswald_write_character(lx, y, face, invert, str[i]);
}
}
uint8_t oswald_write_string_length(const uint8_t x, const uint8_t y, const uint8_t len, const oswald_font_face face, const boolean invert, char *str)
{
uint8_t lx, i, strl;
strl = oswald_strlen(str);
if (strl == 0)
return;
lx = x;
for (i=0; i<strl; i++) {
lx += oswald_write_character(lx, y, face, invert, str[i]);
if (lx > len)
break;
}
return (i+1);
}
void oswald_write_number(const uint8_t x, const uint8_t y, const oswald_font_face face, const boolean invert, const int16_t number)
{
uint8_t lx, i, strl;
char str[8];
itoa(number, str, 10);
strl = oswald_strlen(str);
if (strl == 0)
return;
lx = x;
for (i=0; i<strl; i++) {
lx += oswald_write_character(lx, y, face, invert, str[i]);
}
}