Merge pull request #351 from matthijskooijman/bitmap
Improvements to the new bitmap code
This commit is contained in:
commit
f5ae8d8f0d
|
@ -310,6 +310,7 @@ uint8_t u8g2_UserInterfaceInputValue(u8g2_t *u8g2, const char *title, const char
|
|||
*/
|
||||
|
||||
|
||||
#ifdef U8X8_USE_PINS
|
||||
|
||||
/* Arduino constructor list start */
|
||||
/* generated code (codebuild), u8g2 project */
|
||||
|
@ -6310,5 +6311,19 @@ class U8G2_MAX7219_32X8_F_2ND_4W_HW_SPI : public U8G2 {
|
|||
|
||||
/* Arduino constructor list end */
|
||||
|
||||
#endif // U8X8_USE_PINS
|
||||
|
||||
class U8G2_BITMAP : public U8G2 {
|
||||
public: U8G2_BITMAP(uint16_t pixel_width, uint16_t pixel_height, const u8g2_cb_t *rotation) {
|
||||
u8g2_SetupBitmap(getU8g2(), rotation, pixel_width, pixel_height);
|
||||
}
|
||||
|
||||
// This completely resets various settings, such as the
|
||||
// font, so be sure to re-initialize things
|
||||
void changeSize(uint16_t pixel_width, uint16_t pixel_height) {
|
||||
u8g2_SetupBitmap(getU8g2(), getU8g2()->cb, pixel_width, pixel_height);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _U8G2LIB_HH */
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@ size_t U8X8::write(uint8_t v)
|
|||
/*=============================================*/
|
||||
/* callbacks */
|
||||
|
||||
#ifdef U8X8_USE_PINS
|
||||
extern "C" uint8_t u8x8_gpio_and_delay_arduino(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, U8X8_UNUSED void *arg_ptr)
|
||||
{
|
||||
uint8_t i;
|
||||
|
@ -156,6 +157,7 @@ extern "C" uint8_t u8x8_gpio_and_delay_arduino(u8x8_t *u8x8, uint8_t msg, uint8_
|
|||
}
|
||||
return 1;
|
||||
}
|
||||
#endif // U8X8_USE_PINS
|
||||
|
||||
|
||||
/*=============================================*/
|
||||
|
@ -337,6 +339,7 @@ extern "C" uint8_t u8x8_byte_arduino_4wire_sw_spi(u8x8_t *u8x8, uint8_t msg, uin
|
|||
|
||||
/*=============================================*/
|
||||
|
||||
#ifdef U8X8_USE_PINS
|
||||
|
||||
extern "C" uint8_t u8x8_byte_arduino_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
|
||||
{
|
||||
|
@ -610,6 +613,8 @@ extern "C" uint8_t u8x8_byte_arduino_2nd_hw_i2c(U8X8_UNUSED u8x8_t *u8x8, U8X8_U
|
|||
return 1;
|
||||
}
|
||||
|
||||
#endif // U8X8_USE_PINS
|
||||
|
||||
/*=============================================*/
|
||||
|
||||
/*
|
||||
|
@ -876,6 +881,7 @@ extern "C" uint8_t u8x8_byte_arduino_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t a
|
|||
|
||||
|
||||
|
||||
#ifdef U8X8_USE_PINS
|
||||
|
||||
/*
|
||||
use U8X8_PIN_NONE as value for "reset", if there is no reset line
|
||||
|
@ -1089,4 +1095,5 @@ void u8x8_SetPin_SED1520(u8x8_t *u8x8, uint8_t d0, uint8_t d1, uint8_t d2, uint8
|
|||
u8x8_SetPin(u8x8, U8X8_PIN_CS, e2);
|
||||
u8x8_SetPin(u8x8, U8X8_PIN_DC, dc);
|
||||
u8x8_SetPin(u8x8, U8X8_PIN_RESET, reset);
|
||||
}
|
||||
}
|
||||
#endif // U8X8_USE_PINS
|
||||
|
|
|
@ -101,6 +101,7 @@ extern "C" uint8_t u8x8_byte_arduino_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t a
|
|||
extern "C" uint8_t u8x8_byte_arduino_2nd_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
extern "C" uint8_t u8x8_byte_arduino_ks0108(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
|
||||
|
||||
#ifdef U8X8_USE_PINS
|
||||
void u8x8_SetPin_4Wire_SW_SPI(u8x8_t *u8x8, uint8_t clock, uint8_t data, uint8_t cs, uint8_t dc, uint8_t reset);
|
||||
void u8x8_SetPin_3Wire_SW_SPI(u8x8_t *u8x8, uint8_t clock, uint8_t data, uint8_t cs, uint8_t reset);
|
||||
void u8x8_SetPin_4Wire_HW_SPI(u8x8_t *u8x8, uint8_t cs, uint8_t dc, uint8_t reset);
|
||||
|
@ -111,6 +112,7 @@ void u8x8_SetPin_8Bit_6800(u8x8_t *u8x8, uint8_t d0, uint8_t d1, uint8_t d2, uin
|
|||
void u8x8_SetPin_8Bit_8080(u8x8_t *u8x8, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t wr, uint8_t cs, uint8_t dc, uint8_t reset);
|
||||
void u8x8_SetPin_KS0108(u8x8_t *u8x8, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t enable, uint8_t dc, uint8_t cs0, uint8_t cs1, uint8_t cs2, uint8_t reset);
|
||||
void u8x8_SetPin_SED1520(u8x8_t *u8x8, uint8_t d0, uint8_t d1, uint8_t d2, uint8_t d3, uint8_t d4, uint8_t d5, uint8_t d6, uint8_t d7, uint8_t dc, uint8_t e1, uint8_t e2, uint8_t reset);
|
||||
#endif
|
||||
|
||||
//void u8x8_Setup_4Wire_SW_SPI(u8x8_t *u8x8, u8x8_msg_cb display_cb, uint8_t clock, uint8_t data, uint8_t cs, uint8_t dc, uint8_t reset);
|
||||
//void u8x8_Setup_3Wire_SW_SPI(u8x8_t *u8x8, u8x8_msg_cb display_cb, uint8_t clock, uint8_t data, uint8_t cs, uint8_t reset);
|
||||
|
@ -268,6 +270,7 @@ class U8X8 : public Print
|
|||
};
|
||||
|
||||
|
||||
#ifdef U8X8_USE_PINS
|
||||
// constructor list start
|
||||
/* generated code (codebuild), u8g2 project */
|
||||
class U8X8_SSD1305_128X32_NONAME_4W_SW_SPI : public U8X8 {
|
||||
|
@ -2269,6 +2272,8 @@ class U8X8_MAX7219_32X8_2ND_4W_HW_SPI : public U8X8 {
|
|||
}
|
||||
};
|
||||
|
||||
#endif // U8X8_USE_PINS
|
||||
|
||||
// constructor list end
|
||||
|
||||
|
||||
|
|
|
@ -999,7 +999,7 @@ void u8g2_SetupBuffer_TGA_LCD(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb);
|
|||
|
||||
/*==========================================*/
|
||||
/* u8x8_d_bitmap.c */
|
||||
void u8g2_SetupBitmap(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb, uint16_t tile_width, uint16_t tile_height);
|
||||
void u8g2_SetupBitmap(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb, uint16_t pixel_width, uint16_t pixel_height);
|
||||
|
||||
|
||||
/*==========================================*/
|
||||
|
|
|
@ -734,7 +734,7 @@ void tga_save(const char *name);
|
|||
/* u8x8_d_bitmap.c */
|
||||
uint8_t u8x8_GetBitmapPixel(u8x8_t *u8x8, uint16_t x, uint16_t y);
|
||||
void u8x8_SaveBitmapTGA(u8x8_t *u8x8, const char *filename);
|
||||
void u8x8_SetupBitmap(u8x8_t *u8x8, uint16_t tile_width, uint16_t tile_height);
|
||||
void u8x8_SetupBitmap(u8x8_t *u8x8, uint16_t pixel_width, uint16_t pixel_height);
|
||||
uint8_t u8x8_ConnectBitmapToU8x8(u8x8_t *u8x8);
|
||||
|
||||
/*==========================================*/
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
CFLAGS = -g -Wall -I../../../csrc/ -ICImg
|
||||
CXXFLAGS = $(CFLAGS)
|
||||
LDFLAGS = -lpthread
|
||||
CSRC = $(wildcard ls ../../../csrc/*.c) ../common/u8x8_d_bitmap.c
|
||||
CPPSRC = main.cpp
|
||||
OBJ = $(CSRC:.c=.o) $(CPPSRC:.cpp=.o)
|
||||
|
||||
cimg_annotate_screenshot: $(OBJ) CImg
|
||||
$(CXX) $(CFLAGS) $(LDFLAGS) $(OBJ) -o cimg_annotate_screenshot
|
||||
|
||||
CImg:
|
||||
git clone --depth=1 https://github.com/dtschump/CImg.git
|
||||
|
||||
clean:
|
||||
-rm $(OBJ) cimg_annotate_screenshot
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/stat.h>
|
||||
#include <assert.h>
|
||||
#include <u8g2.h>
|
||||
#define cimg_display 0 // Prevent CImg from including Xlib and other unneeded stuff
|
||||
#include <CImg.h>
|
||||
|
||||
using namespace cimg_library;
|
||||
|
||||
const char * OUT_DIR = "output";
|
||||
|
||||
u8g2_t u8g2;
|
||||
|
||||
// Convert the buffer of an u8g2 bitmap device to a CImg bitmap
|
||||
template<typename T>
|
||||
CImg<T> u8x8_bitmap_to_cimg(u8g2_t *u8g2, unsigned int size_c, T *fg_color, T *bg_color) {
|
||||
uint16_t width = u8g2_GetDisplayWidth(u8g2);
|
||||
uint16_t height = u8g2_GetDisplayHeight(u8g2);
|
||||
u8x8_t *u8x8 = u8g2_GetU8x8(u8g2);
|
||||
|
||||
CImg<T> img(width, height, /* size_z */ 1, size_c);
|
||||
for (uint16_t y = 0; y < height; ++y) {
|
||||
for (uint16_t x = 0; x < width; ++x) {
|
||||
T *color = u8x8_GetBitmapPixel(u8x8, x, y) ? fg_color : bg_color;
|
||||
img.draw_point(x, y, color);
|
||||
}
|
||||
}
|
||||
return img;
|
||||
}
|
||||
|
||||
static uint8_t black[] = {0, 0, 0};
|
||||
static uint8_t white[] = {255, 255, 255};
|
||||
static uint8_t grey[] = {128, 128, 128};
|
||||
static uint8_t red[] = {255, 0, 0};
|
||||
|
||||
using Font = CImgList<uint8_t>;
|
||||
const float OPAQUE = 1;
|
||||
const unsigned SOLID_LINE = ~0U;
|
||||
const uint8_t SCREENSHOT_BORDER = 2;
|
||||
const uint8_t SCREENSHOT_SCALE = 3;
|
||||
const float ARROW_ANGLE = 30;
|
||||
const float ARROW_LENGTH = 2 * SCREENSHOT_SCALE + 1; // +1 makes for a more (but not necessarily perfect) symmetrical triangle
|
||||
auto ANNOTATE_FONT = Font::font(8 * SCREENSHOT_SCALE);
|
||||
|
||||
// Draw a non-filled rectangle, using the specified line width (in pixels)
|
||||
template<typename T>
|
||||
void draw_outline(CImg<T>& img, int x, int y, int w, int h, const T* color, int line_width = 1) {
|
||||
for (int i = 0; i < line_width; ++i)
|
||||
img.draw_rectangle(x + i, y + i, x + w - 1 - i, y + h - 1 - i, color, OPAQUE, SOLID_LINE);
|
||||
}
|
||||
|
||||
enum { ALIGN_LEFT = 0, ALIGN_CENTER = 1, ALIGN_RIGHT = 2};
|
||||
enum { ALIGN_TOP = 0, ALIGN_MIDDLE = 4, ALIGN_BOTTOM = 8};
|
||||
|
||||
// Draw aligned text
|
||||
template<typename T>
|
||||
void draw_text(CImg<T>& img, int x, int y, const T* color, Font& font, unsigned align, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
char buf[100];
|
||||
int ret = vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
assert(ret >= 0 && (size_t)ret < sizeof(buf));
|
||||
|
||||
if (align) {
|
||||
auto text = CImg<uint8_t>().draw_text(0, 0, "%s", color, 0, OPAQUE, font, buf);
|
||||
if (align & ALIGN_RIGHT)
|
||||
x -= text.width();
|
||||
else if (align & ALIGN_CENTER)
|
||||
x -= text.width() / 2;
|
||||
if (align & ALIGN_BOTTOM)
|
||||
y -= text.height();
|
||||
else if (align & ALIGN_MIDDLE)
|
||||
y -= text.height() / 2;
|
||||
}
|
||||
img.draw_text(x, y, "%s", color, 0, OPAQUE, font, buf);
|
||||
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
enum {TOP, RIGHT, BOTTOM, LEFT};
|
||||
struct Annotation {
|
||||
// Will be called to add annotations to the screenshot
|
||||
virtual void annotate(CImg<uint8_t>& /*img*/) const { }
|
||||
|
||||
// Margins are in screenshot pixels, will be scaled later
|
||||
// Top, right, bottom, left (like CSS)
|
||||
size_t margin[4] = {0, 0, 0, 0};
|
||||
};
|
||||
|
||||
int translate_x(float x, const Annotation& ann) {
|
||||
return (x + ann.margin[LEFT]) * SCREENSHOT_SCALE + SCREENSHOT_BORDER;
|
||||
}
|
||||
int translate_y(float y, const Annotation& ann) {
|
||||
return (y + ann.margin[TOP]) * SCREENSHOT_SCALE + SCREENSHOT_BORDER;
|
||||
}
|
||||
int translate_wh(float wh) {
|
||||
return wh * SCREENSHOT_SCALE;
|
||||
}
|
||||
|
||||
void save_screenshot(const char *dir, const char* name, const Annotation& ann = Annotation()) {
|
||||
char filename[PATH_MAX];
|
||||
int ret = snprintf(filename, sizeof(filename), "%s/%s.png", dir, name);
|
||||
assert(ret >= 0 && (size_t)ret < sizeof(filename));
|
||||
|
||||
auto screenshot = u8x8_bitmap_to_cimg<uint8_t>(&u8g2, 3, black, white);
|
||||
screenshot.resize(screenshot.width() * SCREENSHOT_SCALE, screenshot.height() * SCREENSHOT_SCALE);
|
||||
|
||||
// Create a bigger output image
|
||||
size_t width = screenshot.width() + 2*SCREENSHOT_BORDER + (ann.margin[LEFT] + ann.margin[RIGHT]) * SCREENSHOT_SCALE;
|
||||
size_t height = screenshot.height() + 2*SCREENSHOT_BORDER + (ann.margin[TOP] + ann.margin[BOTTOM]) * SCREENSHOT_SCALE;
|
||||
auto output = CImg<uint8_t>(width, height, 1, 3, /* value for all channels */ 255);
|
||||
|
||||
// Draw the screenshot in the center
|
||||
output.draw_image(translate_x(0, ann), translate_y(0, ann), 0, 0, screenshot);
|
||||
|
||||
// Draw a 1px border around the screenshot, just inside the
|
||||
// SCREENSHOT_BORDER area (leaving a bit of white space between
|
||||
// the border and the screenshot).
|
||||
draw_outline(output, ann.margin[LEFT] * SCREENSHOT_SCALE, ann.margin[TOP] * SCREENSHOT_SCALE, screenshot.width() + 2 * SCREENSHOT_BORDER, screenshot.height() + 2 * SCREENSHOT_BORDER, grey);
|
||||
|
||||
ann.annotate(output);
|
||||
|
||||
output.save_png(filename);
|
||||
|
||||
printf("Generated %s\n", filename);
|
||||
}
|
||||
|
||||
struct DescribeFigures : public Annotation {
|
||||
DescribeFigures() {
|
||||
this->margin[RIGHT] = 30;
|
||||
this->margin[LEFT] = 30;
|
||||
this->margin[TOP] = 10;
|
||||
this->margin[BOTTOM] = 10;
|
||||
}
|
||||
|
||||
virtual void annotate(CImg<uint8_t>& img) const {
|
||||
// Add annotations. Coordinates are converted by translate_x/y from
|
||||
// original screenshot pixels to the output screenshot pixels
|
||||
draw_text(img, translate_x(132, *this), translate_y(15, *this), red, ANNOTATE_FONT, ALIGN_LEFT|ALIGN_MIDDLE, "Box");
|
||||
img.draw_arrow(translate_x(130, *this), translate_y(15, *this), translate_x(116, *this), translate_y(15, *this), red, OPAQUE, ARROW_ANGLE, ARROW_LENGTH);
|
||||
|
||||
draw_text(img, translate_x(-4, *this), translate_y(10, *this), red, ANNOTATE_FONT, ALIGN_RIGHT|ALIGN_MIDDLE, "Circle");
|
||||
img.draw_arrow(translate_x(-3, *this), translate_y(10, *this), translate_x(8, *this), translate_y(10, *this), red, OPAQUE, ARROW_ANGLE, ARROW_LENGTH);
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
mkdir(OUT_DIR, 0755);
|
||||
|
||||
u8g2_SetupBitmap(&u8g2, &u8g2_cb_r0, 128, 64);
|
||||
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
|
||||
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
|
||||
u8g2_SetFont(&u8g2, u8g2_font_helvB08_tr);
|
||||
|
||||
u8g2_ClearBuffer(&u8g2);
|
||||
u8g2_DrawCircle(&u8g2, 15, 10, 5, U8G2_DRAW_ALL);
|
||||
u8g2_DrawBox(&u8g2, 100, 10, 10, 10);
|
||||
u8g2_SendBuffer(&u8g2);
|
||||
save_screenshot(OUT_DIR, "plain_screenshot");
|
||||
save_screenshot(OUT_DIR, "annotated_screenshot", DescribeFigures());
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -22,7 +22,8 @@ struct _u8x8_bitmap_struct
|
|||
uint16_t tile_height;
|
||||
uint16_t pixel_width;
|
||||
uint16_t pixel_height;
|
||||
uint8_t *buf;
|
||||
uint8_t *u8x8_buf;
|
||||
uint8_t *u8g2_buf;
|
||||
};
|
||||
|
||||
typedef struct _u8x8_bitmap_struct u8x8_bitmap_t;
|
||||
|
@ -30,27 +31,31 @@ typedef struct _u8x8_bitmap_struct u8x8_bitmap_t;
|
|||
/*========================================================*/
|
||||
/* bitmap functions */
|
||||
|
||||
uint8_t u8x8_bitmap_SetSize(u8x8_bitmap_t *b, uint16_t tile_width, uint16_t tile_height)
|
||||
uint8_t u8x8_bitmap_SetSize(u8x8_bitmap_t *b, uint16_t pixel_width, uint16_t pixel_height)
|
||||
{
|
||||
if ( b->buf != NULL )
|
||||
free(b->buf);
|
||||
|
||||
b->tile_width = tile_width;
|
||||
b->tile_height = tile_height;
|
||||
b->pixel_width = tile_width*8;
|
||||
b->pixel_height = tile_height*8;
|
||||
|
||||
if ( b->u8x8_buf != NULL )
|
||||
free(b->u8x8_buf);
|
||||
|
||||
b->tile_width = (pixel_width+7)/8;
|
||||
b->tile_height = (pixel_height+7)/8;
|
||||
b->pixel_width = pixel_width;
|
||||
b->pixel_height = pixel_height;
|
||||
|
||||
/* allocate the bitmap twice, one for u8x8 and another bitmap for u8g2 */
|
||||
/* however, the final bitmap will always be in the first half of the buffer */
|
||||
b->buf = (uint8_t *)malloc((size_t)tile_width*(size_t)tile_height*(size_t)8*(size_t)2);
|
||||
if ( b->buf == NULL )
|
||||
b->u8x8_buf = (uint8_t *)malloc((size_t)b->tile_width*(size_t)b->tile_height*(size_t)8*(size_t)2);
|
||||
b->u8g2_buf = b->u8x8_buf+(size_t)b->tile_width*(size_t)b->tile_height*(size_t)8;
|
||||
|
||||
if ( b->u8x8_buf == NULL ) {
|
||||
b->u8g2_buf = NULL;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void u8x8_bitmap_DrawTiles(u8x8_bitmap_t *b, uint16_t tx, uint16_t ty, uint8_t tile_cnt, uint8_t *tile_ptr)
|
||||
{
|
||||
uint8_t *dest_ptr = b->buf;
|
||||
uint8_t *dest_ptr = b->u8x8_buf;
|
||||
if ( dest_ptr == NULL )
|
||||
return;
|
||||
dest_ptr += ty*b->pixel_width;
|
||||
|
@ -60,7 +65,7 @@ void u8x8_bitmap_DrawTiles(u8x8_bitmap_t *b, uint16_t tx, uint16_t ty, uint8_t t
|
|||
|
||||
uint8_t u8x8_bitmap_GetPixel(u8x8_bitmap_t *b, uint16_t x, uint16_t y)
|
||||
{
|
||||
uint8_t *dest_ptr = b->buf;
|
||||
uint8_t *dest_ptr = b->u8x8_buf;
|
||||
if ( dest_ptr == NULL )
|
||||
return 0;
|
||||
dest_ptr += (y/8)*b->pixel_width;
|
||||
|
@ -166,17 +171,17 @@ static u8x8_display_info_t u8x8_bitmap_info =
|
|||
|
||||
/* allocate bitmap */
|
||||
/* will be called by u8x8_SetupBitmap or u8g2_SetupBitmap */
|
||||
static uint8_t u8x8_SetBitmapDeviceSize(u8x8_t *u8x8, uint16_t tile_width, uint16_t tile_height)
|
||||
static uint8_t u8x8_SetBitmapDeviceSize(u8x8_t *u8x8, uint16_t pixel_width, uint16_t pixel_height)
|
||||
{
|
||||
/* update the global bitmap object, allocate the bitmap */
|
||||
if ( u8x8_bitmap_SetSize(&u8x8_bitmap, tile_width, tile_height) == 0 )
|
||||
if ( u8x8_bitmap_SetSize(&u8x8_bitmap, pixel_width, pixel_height) == 0 )
|
||||
return 0;
|
||||
|
||||
/* update the u8x8 object */
|
||||
u8x8_bitmap_info.tile_width = tile_width;
|
||||
u8x8_bitmap_info.tile_height = tile_height;
|
||||
u8x8_bitmap_info.pixel_width = tile_width*8;
|
||||
u8x8_bitmap_info.pixel_height = tile_height*8;
|
||||
u8x8_bitmap_info.tile_width = (pixel_width+7)/8;
|
||||
u8x8_bitmap_info.tile_height = (pixel_height+7)/8;
|
||||
u8x8_bitmap_info.pixel_width = pixel_width;
|
||||
u8x8_bitmap_info.pixel_height = pixel_height;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -237,9 +242,9 @@ static uint8_t u8x8_d_bitmap(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *a
|
|||
/*========================================================*/
|
||||
/* u8x8 and u8g2 setup functions */
|
||||
|
||||
void u8x8_SetupBitmap(u8x8_t *u8x8, uint16_t tile_width, uint16_t tile_height)
|
||||
void u8x8_SetupBitmap(u8x8_t *u8x8, uint16_t pixel_width, uint16_t pixel_height)
|
||||
{
|
||||
u8x8_SetBitmapDeviceSize(u8x8, tile_width, tile_height);
|
||||
u8x8_SetBitmapDeviceSize(u8x8, pixel_width, pixel_height);
|
||||
|
||||
/* setup defaults */
|
||||
u8x8_SetupDefaults(u8x8);
|
||||
|
@ -251,13 +256,13 @@ void u8x8_SetupBitmap(u8x8_t *u8x8, uint16_t tile_width, uint16_t tile_height)
|
|||
u8x8_SetupMemory(u8x8);
|
||||
}
|
||||
|
||||
void u8g2_SetupBitmap(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb, uint16_t tile_width, uint16_t tile_height)
|
||||
void u8g2_SetupBitmap(u8g2_t *u8g2, const u8g2_cb_t *u8g2_cb, uint16_t pixel_width, uint16_t pixel_height)
|
||||
{
|
||||
/* allocate bitmap, assign the device callback to u8x8 */
|
||||
u8x8_SetupBitmap(u8g2_GetU8x8(u8g2), tile_width, tile_height);
|
||||
u8x8_SetupBitmap(u8g2_GetU8x8(u8g2), pixel_width, pixel_height);
|
||||
|
||||
/* configure u8g2 in full buffer mode */
|
||||
u8g2_SetupBuffer(u8g2, u8x8_bitmap.buf+(size_t)tile_width*(size_t)tile_height*(size_t)8, tile_height, u8g2_ll_hvline_vertical_top_lsb, u8g2_cb);
|
||||
u8g2_SetupBuffer(u8g2, u8x8_bitmap.u8g2_buf, (pixel_height+7)/8, u8g2_ll_hvline_vertical_top_lsb, u8g2_cb);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
CFLAGS = -g -Wall -I../../../csrc/.
|
||||
|
||||
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/u8x8_d_bitmap.c ) main.c
|
||||
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
||||
hello_world: $(OBJ)
|
||||
$(CC) $(CFLAGS) $(LDFLAGS) $(OBJ) -o $@
|
||||
|
||||
clean:
|
||||
-rm -f $(OBJ) hello_world *.tga
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#include "u8g2.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* This example uses the Bitmap device to draw to an in-memory buffer
|
||||
* and writes the result to a TGA file. This can for example be used to
|
||||
* make screenshots of an application normally running on an Arduino.
|
||||
*/
|
||||
|
||||
u8g2_t u8g2;
|
||||
|
||||
int main(void)
|
||||
{
|
||||
u8g2_SetupBitmap(&u8g2, &u8g2_cb_r0, 128, 64);
|
||||
u8x8_InitDisplay(u8g2_GetU8x8(&u8g2));
|
||||
u8x8_SetPowerSave(u8g2_GetU8x8(&u8g2), 0);
|
||||
u8g2_SetFont(&u8g2, u8g2_font_helvB08_tr);
|
||||
|
||||
u8g2_ClearBuffer(&u8g2);
|
||||
// Here, you can call other code to actually draw things, such as
|
||||
// existing application code to generate a screenshot
|
||||
u8g2_DrawStr(&u8g2, 10, 30, "Hello, world!");
|
||||
u8g2_SendBuffer(&u8g2);
|
||||
u8x8_SaveBitmapTGA(u8g2_GetU8x8(&u8g2), "small.tga");
|
||||
|
||||
// This changes size, but also resets other stuff like font
|
||||
u8g2_SetupBitmap(&u8g2, &u8g2_cb_r0, 128, 128);
|
||||
u8g2_SetFont(&u8g2, u8g2_font_helvB08_tr);
|
||||
|
||||
u8g2_ClearBuffer(&u8g2);
|
||||
// Here, you can call other code to actually draw things, such as
|
||||
// existing application code to generate a screenshot
|
||||
u8g2_DrawStr(&u8g2, 10, 30, "Hello, world!");
|
||||
u8g2_DrawStr(&u8g2, 10, 100, "Hello, larger world!");
|
||||
u8g2_SendBuffer(&u8g2);
|
||||
u8x8_SaveBitmapTGA(u8g2_GetU8x8(&u8g2), "large.tga");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
CFLAGS = -g -Wall -I../../../csrc/. `sdl-config --cflags`
|
||||
|
||||
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
|
||||
SRC = $(shell ls ../../../csrc/*.c) ../../bitmap/common/u8x8_d_bitmap.c $(shell ls ../common/*.c ) main.c
|
||||
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
CFLAGS = -g -Wall -I../../../csrc/. `sdl-config --cflags`
|
||||
|
||||
SRC = $(shell ls ../../../csrc/*.c) $(shell ls ../common/*.c ) main.c
|
||||
SRC = $(shell ls ../../../csrc/*.c) ../../bitmap/common/u8x8_d_bitmap.c $(shell ls ../common/*.c ) main.c
|
||||
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
To generate (TGA) image files using u8g2 on a regular (non-Arduino)
|
||||
system, have a look at the sys/bitmap directory, which is the
|
||||
recommended way to approach this. This sys/tga directory is mostly kept
|
||||
around for compatibility and to generate u8g2 manual images.
|
Loading…
Reference in New Issue