23#include "os_helpers.h"
28#ifdef SCREEN_SIZE_WALLET
35 BAGL_FILL_CIRCLE_0_PI2,
36 BAGL_FILL_CIRCLE_PI2_PI,
37 BAGL_FILL_CIRCLE_PI_3PI2,
38 BAGL_FILL_CIRCLE_3PI2_2PI
42#define QR_PIXEL_WIDTH_HEIGHT 4
49 uint8_t
qrcode[qrcodegen_BUFFER_LEN_MAX];
54#define qrcode ((QrCodeBuffer_t *) ramBuffer)->qrcode
55#define tempBuffer ((QrCodeBuffer_t *) ramBuffer)->tempBuffer
56#define QrDrawBuffer ((QrCodeBuffer_t *) ramBuffer)->QrDrawBuffer
60#ifdef SCREEN_SIZE_WALLET
67 const uint8_t *topLeftDisc;
68 const uint8_t *bottomLeftDisc;
69 const uint8_t *topLeftCircle;
70 const uint8_t *bottomLeftCircle;
81#ifndef SCREEN_SIZE_WALLET
82static const uint8_t quarter_disc_3px_1bpp[] = {0xEC, 0xFF};
83static const uint8_t quarter_disc_3px_90_1bpp[] = {0x2F, 0xFF};
84static const uint8_t quarter_disc_3px_180_1bpp[] = {0x9B, 0xFF};
85static const uint8_t quarter_disc_3px_270_1bpp[] = {0xFA, 0x00};
87static const uint8_t quarter_circle_3px_1bpp[] = {0x4C, 0x00};
88static const uint8_t quarter_circle_3px_90_1bpp[] = {0x0D, 0x00};
89static const uint8_t quarter_circle_3px_180_1bpp[] = {0x19, 0x00};
90static const uint8_t quarter_circle_3px_270_1bpp[] = {0x58, 0x00};
94static const uint8_t radiusValues[
RADIUS_MAX + 1] = {
95#ifdef SCREEN_SIZE_WALLET
107#ifdef SCREEN_SIZE_WALLET
109#if COMMON_RADIUS == 28
111 = {&C_half_disc_left_56px_1bpp, &C_half_circle_left_56px_1bpp};
112#elif COMMON_RADIUS == 40
114 = {&C_half_disc_left_80px_1bpp, &C_half_circle_left_80px_1bpp};
115#elif COMMON_RADIUS == 44
117 = {&C_half_disc_left_88px_1bpp, &C_half_circle_left_88px_1bpp};
119#if SMALL_BUTTON_RADIUS == 20
120static const radiusIcons_t radiusIcons20px = {&C_half_disc_left_40px_1bpp, NULL};
121#elif SMALL_BUTTON_RADIUS == 32
123 = {&C_half_disc_left_64px_1bpp, &C_half_circle_left_64px_1bpp};
128#if SMALL_BUTTON_RADIUS == 20
133#if COMMON_RADIUS == 28
138#if SMALL_BUTTON_RADIUS == 32
143#if COMMON_RADIUS == 40
148#if COMMON_RADIUS == 44
169#ifdef SCREEN_SIZE_WALLET
170static void draw_circle_helper(
int x0,
185 if (borderColor == innerColor) {
186 half_icon = PIC(radiusIcons[radiusIndex]->leftDisc);
189#if NB_COLOR_BITS == 1
192 half_icon = PIC(radiusIcons[radiusIndex]->leftCircle);
194 area.width = half_icon->width;
195 area.height = half_icon->height;
203 area.x0 = x0 - half_icon->width;
210static void draw_circle_helper(
int x_center,
218 const uint8_t *quarter_buffer = NULL;
225 area.width = area.height = radiusValues[radiusIndex];
227 case BAGL_FILL_CIRCLE_3PI2_2PI:
230 quarter_buffer = (borderColor == innerColor) ? quarter_disc_3px_180_1bpp
231 : quarter_circle_3px_180_1bpp;
233 case BAGL_FILL_CIRCLE_PI_3PI2:
234 area.x0 = x_center - area.width;
236 quarter_buffer = (borderColor == innerColor) ? quarter_disc_3px_270_1bpp
237 : quarter_circle_3px_270_1bpp;
239 case BAGL_FILL_CIRCLE_0_PI2:
241 area.y0 = y_center - area.width;
242 quarter_buffer = (borderColor == innerColor) ? quarter_disc_3px_90_1bpp
243 : quarter_circle_3px_90_1bpp;
245 case BAGL_FILL_CIRCLE_PI2_PI:
246 area.x0 = x_center - area.width;
247 area.y0 = y_center - area.width;
249 = (borderColor == innerColor) ? quarter_disc_3px_1bpp : quarter_circle_3px_1bpp;
275 "nbgl_drawRoundedRect x0 = %d, y0 = %d, width =%d, height =%d\n",
282 radius = radiusValues[radiusIndex];
294 rectArea.x0 = area->x0;
295 rectArea.y0 = area->y0;
296 rectArea.width = area->width;
297 rectArea.height = area->height;
298 rectArea.backgroundColor = innerColor;
305#ifdef SCREEN_SIZE_WALLET
308 draw_circle_helper(area->x0,
314 area->backgroundColor);
315 draw_circle_helper(area->x0 + area->width,
321 area->backgroundColor);
323 if (radiusIndex == RADIUS_1_PIXEL) {
327 draw_circle_helper(area->x0 + radius,
330 BAGL_FILL_CIRCLE_PI2_PI,
333 area->backgroundColor);
334 draw_circle_helper(area->x0 + area->width - radius,
337 BAGL_FILL_CIRCLE_0_PI2,
340 area->backgroundColor);
341 draw_circle_helper(area->x0 + radius,
342 area->y0 + area->height - radius,
344 BAGL_FILL_CIRCLE_PI_3PI2,
347 area->backgroundColor);
348 draw_circle_helper(area->x0 + area->width - radius,
349 area->y0 + area->height - radius,
351 BAGL_FILL_CIRCLE_3PI2_2PI,
354 area->backgroundColor);
379 "nbgl_drawRoundedBorderedRect: innerColor = %d, borderColor = %d, backgroundColor=%d\n",
382 area->backgroundColor);
385 radius = radiusValues[radiusIndex];
393 DRAW_LOGGER,
"nbgl_drawRoundedBorderedRect forbidden radius index =%d\n", radiusIndex);
396 rectArea.backgroundColor = innerColor;
399 rectArea.x0 = area->x0;
400 rectArea.y0 = area->y0;
401 rectArea.width = area->width;
402 rectArea.height = area->height;
405 if ((innerColor == borderColor) && (borderColor == area->backgroundColor)) {
410#ifdef SCREEN_SIZE_WALLET
411 uint16_t circle_width = 0;
414 circle_width = half_icon->width;
416 if ((2 * circle_width) < area->width) {
417 if ((area->height - stroke) > VERTICAL_ALIGNMENT) {
418 rectArea.height = stroke;
420 rectArea.y0 = area->y0 + area->height - stroke;
426 for (i = 0; i < stroke; i++) {
427 pattern |= 1 << (7 - i);
429 for (i = area->height - stroke; i < area->height; i++) {
430 pattern |= 1 << (7 - i);
438 if ((2 * radius) < area->height) {
439 rectArea.x0 = area->x0;
440 rectArea.y0 = area->y0;
441 rectArea.width = stroke;
442 rectArea.height = area->height;
443 rectArea.backgroundColor = area->backgroundColor;
445 rectArea.x0 = area->x0 + area->width - stroke;
450 draw_circle_helper(area->x0,
456 area->backgroundColor);
457 draw_circle_helper(area->x0 + area->width,
463 area->backgroundColor);
466 rectArea.x0 = area->x0 + radius;
467 rectArea.y0 = area->y0;
468 rectArea.width = area->width - 2 * radius;
469 rectArea.height = stroke;
470 rectArea.backgroundColor = borderColor;
472 rectArea.y0 = area->y0 + area->height - stroke;
474 if ((2 * radius) < area->height) {
475 rectArea.x0 = area->x0;
476 rectArea.y0 = area->y0 + radius;
477 rectArea.width = stroke;
478 rectArea.height = area->height - 2 * radius;
479 rectArea.backgroundColor = area->backgroundColor;
481 rectArea.x0 = area->x0 + area->width - stroke;
487 draw_circle_helper(area->x0 + radius,
490 BAGL_FILL_CIRCLE_PI2_PI,
493 area->backgroundColor);
494 draw_circle_helper(area->x0 + area->width - radius,
497 BAGL_FILL_CIRCLE_0_PI2,
500 area->backgroundColor);
501 draw_circle_helper(area->x0 + radius,
502 area->y0 + area->height - radius,
504 BAGL_FILL_CIRCLE_PI_3PI2,
507 area->backgroundColor);
508 draw_circle_helper(area->x0 + area->width - radius,
509 area->y0 + area->height - radius,
511 BAGL_FILL_CIRCLE_3PI2_2PI,
514 area->backgroundColor);
551static uint16_t get_bitmap_byte_cnt(
const nbgl_font_t *font, uint8_t charId)
553 if ((charId < font->first_char) || (charId > font->
last_char)) {
558 if (charId < font->last_char) {
588 int16_t x = area->x0;
591#ifdef HAVE_UNICODE_SUPPORT
596 "nbgl_drawText: x0 = %d, y0 = %d, w = %d, h = %d, fontColor = %d, "
597 "backgroundColor=%d, text = %s\n",
603 area->backgroundColor,
606 rectArea.backgroundColor = area->backgroundColor;
609 while (textLen > 0) {
614 const uint8_t *char_buffer;
619 uint16_t char_byte_cnt;
621 uint8_t nb_skipped_bytes;
626#ifdef HAVE_UNICODE_SUPPORT
627 if (unicode_ctx == NULL) {
628 unicode_ctx = nbgl_getUnicodeFont(fontId);
631 = nbgl_getUnicodeFontCharacter(unicode);
633 if (unicodeCharacter == NULL) {
636 char_width = unicodeCharacter->
width;
637#if defined(HAVE_LANGUAGE_PACK)
638 char_buffer = unicode_ctx->
bitmap;
641 char_x_max = char_width;
646 nb_skipped_bytes = (unicodeCharacter->
x_min_offset & 7) << 3;
652 nb_skipped_bytes = 0;
655 char_y_min += (uint16_t) unicodeCharacter->
y_min_offset;
656 char_x_max -= (uint16_t) unicodeCharacter->
x_max_offset;
657 char_y_max -= (uint16_t) unicodeCharacter->
y_max_offset;
660 char_byte_cnt = nbgl_getUnicodeFontCharacterByteCount();
661 encoding = unicodeCharacter->
encoding;
668 if (unicode ==
'\f') {
672 else if (unicode ==
'\b') {
675#ifdef HAVE_UNICODE_SUPPORT
676 unicode_ctx = nbgl_getUnicodeFont(fontId);
682#ifdef HAVE_UNICODE_SUPPORT
683 unicode_ctx = nbgl_getUnicodeFont(fontId);
690 if ((unicode < font->first_char) || (unicode > font->
last_char)) {
696 char_width = character->
width;
699 char_x_max = char_width;
700 char_y_max = font->
height;
710 nb_skipped_bytes = 0;
712 char_y_min = font->
y_min;
718 char_byte_cnt = get_bitmap_byte_cnt(font, unicode);
722 rectArea.x0 = x + char_x_min;
723 rectArea.y0 = area->y0 + char_y_min;
724 rectArea.height = (char_y_max - char_y_min);
725 rectArea.width = (char_x_max - char_x_min);
729 if (!char_byte_cnt || encoding == 1) {
731 &rectArea, char_buffer, char_byte_cnt, fontColor, nb_skipped_bytes);
743static void push_bits(uint8_t *buffer, uint16_t current_bits, uint8_t bits, uint8_t nb_bits)
745 uint8_t
byte = current_bits / 8;
746 uint8_t remaining_bits = 8 - current_bits % 8;
748 if (remaining_bits >= nb_bits) {
750 buffer[byte] |= bits << (remaining_bits - nb_bits);
754 buffer[byte] |= bits >> (nb_bits - remaining_bits);
755 nb_bits -= remaining_bits;
757 buffer[
byte + 1] |= bits << (8 - nb_bits);
762static void nbgl_frontDrawQrInternal(
const nbgl_area_t *area,
766 int size = qrcodegen_getSize(
qrcode);
771 .backgroundColor = area->backgroundColor,
780 for (
int x = 0; x < size; x++) {
782 for (
int y = 0; y < size; y++) {
800 qrArea.height = 5 * size;
801 for (
int x = 0; x < size; x++) {
805 for (
int y = 0; y < size; y++) {
808 for (
int z = 0; z < 5; z++) {
820 for (
int x = 0; x < size; x++) {
823 for (
int y = 0; y < size; y++) {
858 uint8_t versionNum = (version ==
QRCODE_V10) ? 10 : 4;
859 bool ok = qrcodegen_encodeText(text,
869 nbgl_frontDrawQrInternal(area, foregroundColor, version);
873 DRAW_LOGGER,
"Impossible to draw QRCode text %s with version %d\n", text, versionNum);
#define LOG_WARN(__logger,...)
#define LOG_DEBUG(__logger,...)
void nbgl_drawIcon(nbgl_area_t *area, nbgl_transformation_t transformation, nbgl_color_map_t color_map, const nbgl_icon_details_t *icon)
Helper function to render an icon directly from its nbgl_icon_details_t structure.
#define QR_PIXEL_WIDTH_HEIGHT
nbgl_font_id_e nbgl_drawText(const nbgl_area_t *area, const char *text, uint16_t textLen, nbgl_font_id_e fontId, color_t fontColor)
This function draws the given single-line text, with the given parameters.
void nbgl_drawRoundedBorderedRect(const nbgl_area_t *area, nbgl_radius_t radiusIndex, uint8_t stroke, color_t innerColor, color_t borderColor)
This functions draws a rounded corners rectangle with a border, with the given parameters.
CCASSERT(qr_code_buffer, sizeof(QrCodeBuffer_t)<=GZLIB_UNCOMPRESSED_CHUNK)
void nbgl_drawQrCode(const nbgl_area_t *area, nbgl_qrcode_version_t version, const char *text, color_t foregroundColor)
Draws the given text into a V10 QR code (QR code version is fixed using qrcodegen_VERSION_MIN/qrcodeg...
void nbgl_drawRoundedRect(const nbgl_area_t *area, nbgl_radius_t radiusIndex, color_t innerColor)
This functions draws a rounded corners rectangle (without border), with the given parameters.
Middle Level API of the new BOLOS Graphical Library.
#define QR_V4_NB_PIX_SIZE
uint32_t nbgl_popUnicodeChar(const uint8_t **text, uint16_t *text_length, bool *is_unicode)
Get the coming unicode value on the given UTF-8 string. If the value is a simple ASCII character,...
@ BAGL_FONT_OPEN_SANS_REGULAR_11px_1bpp
@ BAGL_FONT_OPEN_SANS_EXTRABOLD_11px_1bpp
const nbgl_font_t * nbgl_getFont(nbgl_font_id_e fontId)
Font screen low-Level driver API, to draw elementary forms.
void nbgl_frontDrawLine(const nbgl_area_t *area, uint8_t dotStartIdx, color_t lineColor)
void nbgl_frontDrawImage(const nbgl_area_t *area, const uint8_t *buffer, nbgl_transformation_t transformation, nbgl_color_map_t colorMap)
void nbgl_frontDrawImageFile(const nbgl_area_t *area, const uint8_t *buffer, nbgl_color_map_t colorMap, const uint8_t *uzlib_chunk_buffer)
void nbgl_frontDrawImageRle(const nbgl_area_t *area, const uint8_t *buffer, uint32_t buffer_len, color_t fore_color, uint8_t nb_skipped_bytes)
void nbgl_frontDrawRect(const nbgl_area_t *area)
Side screen low-Level driver API, to draw elementary forms.
uint8_t nbgl_transformation_t
Represents the transformation to be applied on the bitmap before rendering This is a bitfield using m...
uint8_t nbgl_color_map_t
Represents the color_map to be used for 2BPP image, or the foreground color for 1BPP image.
nbgl_radius_t
possible radius indexes for objects
@ RADIUS_0_PIXELS
no radius (square angle)
nbgl_qrcode_version_t
possible modes for QR Code
@ QRCODE_V10
QRCode V10, can encode text len up to 1500 chars, display size = 228*228.
@ QRCODE_V4
QRCode V4, can encode text len up to 62 chars, display size = 264*264.
struct PACKED__ nbgl_icon_details_s nbgl_icon_details_t
Represents all information about an icon.
#define GZLIB_UNCOMPRESSED_CHUNK
size of gzlib uncompression buffer in bytes
#define NO_TRANSFORMATION
nbgl_bpp_t
Enum to represent the number of bits per pixel (BPP)
@ NBGL_BPP_1
1 bit per pixel
struct PACKED__ nbgl_area_s nbgl_area_t
Represents a rectangle area of the screen.
fonts nicknames to be used for various wallet size targets (non-Nano)
uint32_t width
width of character in pixels
uint32_t encoding
method used to encode bitmap data
uint32_t x_min_offset
x_min = x_min_offset
uint32_t bitmap_offset
offset of this character in chars buffer
uint32_t y_min_offset
y_min = (y_min + y_min_offset)
uint32_t x_max_offset
x_max = width - x_max_offset
uint32_t y_max_offset
y_max = (height - y_max_offset)
structure defining an ASCII font
uint8_t char_kerning
kerning for the font
uint8_t crop
If false, x_min_offset+y_min_offset=bytes to skip.
uint8_t first_char
ASCII code of the first character in bitmap and in characters fields.
uint32_t bitmap_len
Size in bytes of the associated bitmap.
uint8_t const * bitmap
array containing bitmaps of all characters
const nbgl_font_character_t *const characters
array containing definitions of all characters
uint8_t height
height of all characters in pixels
uint8_t last_char
ASCII code of the last character in bitmap and in characters fields.
uint8_t y_min
Most top Y coordinate of any char in the font.
uint8_t bpp
number of bits per pixels
structure defining a unicode character (except the bitmap)
uint32_t encoding
method used to encode bitmap data
uint32_t width
width of character in pixels
uint32_t x_min_offset
x_min = x_min_offset
uint32_t y_min_offset
y_min = (y_min + y_min_offset)
uint32_t y_max_offset
y_max = (height - y_max_offset)
uint32_t x_max_offset
x_max = width - x_max_offset
uint32_t bitmap_offset
offset of this character in chars buffer
uint8_t crop
If false, x_min_offset+y_min_offset=bytes to skip.
uint8_t y_min
Most top Y coordinate of any char in the font.
uint8_t height
height of all characters in pixels
const nbgl_font_unicode_t * font
const nbgl_icon_details_t * leftCircle
const nbgl_icon_details_t * leftDisc