mirror of
https://github.com/UberGuidoZ/Flipper.git
synced 2025-01-08 06:40:20 +00:00
142 lines
3.6 KiB
C
142 lines
3.6 KiB
C
#include <gui/gui.h> // 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) ;
|
|
}
|
|
}
|