#include // GUI (screen/keyboard) API #include "images.h" //----------------------------------------------------------------------------- ---------------------------------------- static Canvas* _canvas; static uint8_t _tlx; static uint8_t _tly; static uint8_t _x; static uint8_t _y; static const image_t* _img; static bool _blk; static Color _set; static Color _clr; //+============================================================================ static void _showByteSet(const uint8_t b) { for(uint8_t m = 0x80; m; m >>= 1) { if(b & m) // plot only SET bits canvas_draw_dot(_canvas, (_tlx + _x), (_tly + _y)); if(((++_x) == _img->w) && !(_x = 0) && ((++_y) == _img->h)) break; } } //+============================================================================ static void _showByteClr(const uint8_t b) { for(uint8_t m = 0x80; m; m >>= 1) { if(!(b & m)) // plot only CLR bits canvas_draw_dot(_canvas, (_tlx + _x), (_tly + _y)); if(((++_x) == _img->w) && !(_x = 0) && ((++_y) == _img->h)) break; } } //+============================================================================ static void _showByteAll(const uint8_t b) { for(uint8_t m = 0x80; m; m >>= 1) { if((!!(b & m)) ^ _blk) { // Change colour only when required canvas_set_color(_canvas, ((b & m) ? _set : _clr)); _blk = !_blk; } canvas_draw_dot(_canvas, (_tlx + _x), (_tly + _y)); if(((++_x) == _img->w) && !(_x = 0) && ((++_y) == _img->h)) break; } } //+============================================================================ // available modes are SHOW_SET_BLK - plot image pixels that are SET in BLACK // SHOW_XOR - same as SET_BLACK // SHOW_SET_WHT - plot image pixels that are SET in WHITE // SHOW_CLR_BLK - plot image pixels that are CLEAR in BLACK // SHOW_CLR_WHT - plot image pixels that are CLEAR in WHITE // SHOW_ALL - plot all images pixels as they are // SHOW_ALL_INV - plot all images pixels inverted // void show( Canvas* const canvas, const uint8_t tlx, const uint8_t tly, const image_t* img, const showMode_t mode) { void (*fnShow)(const uint8_t) = NULL; const uint8_t* bp = img->data; // code size optimisation switch(mode & SHOW_INV_) { case SHOW_NRM_: _set = ColorBlack; _clr = ColorWhite; break; case SHOW_INV_: _set = ColorWhite; _clr = ColorBlack; break; case SHOW_BLK_: canvas_set_color(canvas, ColorBlack); break; case SHOW_WHT_: canvas_set_color(canvas, ColorWhite); break; } switch(mode & SHOW_INV_) { case SHOW_NRM_: case SHOW_INV_: fnShow = _showByteAll; canvas_set_color(canvas, ColorWhite); _blk = 0; break; case SHOW_BLK_: case SHOW_WHT_: switch(mode & SHOW_ALL_) { case SHOW_SET_: fnShow = _showByteSet; break; case SHOW_CLR_: fnShow = _showByteClr; break; } break; } furi_check(fnShow); // I want nested functions! _canvas = canvas; _img = img; _tlx = tlx; _tly = tly; _x = 0; _y = 0; // Compressed if(img->c) { for(unsigned int i = 0; i < img->len; i++, bp++) { // Compressed data? {tag, length, value} if(*bp == img->tag) { for(uint16_t c = 0; c < bp[1]; c++) fnShow(bp[2]); bp += 3 - 1; i += 3 - 1; // Uncompressed byte } else { fnShow(*bp); } } // Not compressed } else { for(unsigned int i = 0; i < img->len; i++, bp++) fnShow(*bp); } }