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
121 = {&C_half_disc_left_40px_1bpp, &C_half_circle_left_40px_1bpp};
122#elif SMALL_BUTTON_RADIUS == 32
124 = {&C_half_disc_left_64px_1bpp, &C_half_circle_left_64px_1bpp};
129#if SMALL_BUTTON_RADIUS == 20
134#if COMMON_RADIUS == 28
139#if SMALL_BUTTON_RADIUS == 32
144#if COMMON_RADIUS == 40
149#if COMMON_RADIUS == 44
170#ifdef SCREEN_SIZE_WALLET
171static void draw_circle_helper(
int x0,
186 if (borderColor == innerColor) {
187 half_icon = PIC(radiusIcons[radiusIndex]->leftDisc);
190#if NB_COLOR_BITS == 1
193 half_icon = PIC(radiusIcons[radiusIndex]->leftCircle);
195 area.width = half_icon->width;
196 area.height = half_icon->height;
204 area.x0 = x0 - half_icon->width;
211static void draw_circle_helper(
int x_center,
219 const uint8_t *quarter_buffer = NULL;
226 area.width = area.height = radiusValues[radiusIndex];
228 case BAGL_FILL_CIRCLE_3PI2_2PI:
231 quarter_buffer = (borderColor == innerColor) ? quarter_disc_3px_180_1bpp
232 : quarter_circle_3px_180_1bpp;
234 case BAGL_FILL_CIRCLE_PI_3PI2:
235 area.x0 = x_center - area.width;
237 quarter_buffer = (borderColor == innerColor) ? quarter_disc_3px_270_1bpp
238 : quarter_circle_3px_270_1bpp;
240 case BAGL_FILL_CIRCLE_0_PI2:
242 area.y0 = y_center - area.width;
243 quarter_buffer = (borderColor == innerColor) ? quarter_disc_3px_90_1bpp
244 : quarter_circle_3px_90_1bpp;
246 case BAGL_FILL_CIRCLE_PI2_PI:
247 area.x0 = x_center - area.width;
248 area.y0 = y_center - area.width;
250 = (borderColor == innerColor) ? quarter_disc_3px_1bpp : quarter_circle_3px_1bpp;
276 "nbgl_drawRoundedRect x0 = %d, y0 = %d, width =%d, height =%d\n",
283 radius = radiusValues[radiusIndex];
295 rectArea.x0 = area->x0;
296 rectArea.y0 = area->y0;
297 rectArea.width = area->width;
298 rectArea.height = area->height;
299 rectArea.backgroundColor = innerColor;
306#ifdef SCREEN_SIZE_WALLET
309 draw_circle_helper(area->x0,
315 area->backgroundColor);
316 draw_circle_helper(area->x0 + area->width,
322 area->backgroundColor);
324 if (radiusIndex == RADIUS_1_PIXEL) {
328 draw_circle_helper(area->x0 + radius,
331 BAGL_FILL_CIRCLE_PI2_PI,
334 area->backgroundColor);
335 draw_circle_helper(area->x0 + area->width - radius,
338 BAGL_FILL_CIRCLE_0_PI2,
341 area->backgroundColor);
342 draw_circle_helper(area->x0 + radius,
343 area->y0 + area->height - radius,
345 BAGL_FILL_CIRCLE_PI_3PI2,
348 area->backgroundColor);
349 draw_circle_helper(area->x0 + area->width - radius,
350 area->y0 + area->height - radius,
352 BAGL_FILL_CIRCLE_3PI2_2PI,
355 area->backgroundColor);
380 "nbgl_drawRoundedBorderedRect: innerColor = %d, borderColor = %d, backgroundColor=%d\n",
383 area->backgroundColor);
386 radius = radiusValues[radiusIndex];
394 DRAW_LOGGER,
"nbgl_drawRoundedBorderedRect forbidden radius index =%d\n", radiusIndex);
397 rectArea.backgroundColor = innerColor;
400 rectArea.x0 = area->x0;
401 rectArea.y0 = area->y0;
402 rectArea.width = area->width;
403 rectArea.height = area->height;
406 if ((innerColor == borderColor) && (borderColor == area->backgroundColor)) {
411#ifdef SCREEN_SIZE_WALLET
412 uint16_t circle_width = 0;
415 circle_width = half_icon->width;
417 if ((2 * circle_width) < area->width) {
418 if ((area->height - stroke) > VERTICAL_ALIGNMENT) {
420 rectArea.height = stroke;
421 rectArea.width = area->width - 2 * circle_width;
422 rectArea.x0 += circle_width;
424 rectArea.y0 = area->y0 + area->height - stroke;
430 for (i = 0; i < stroke; i++) {
431 pattern |= 1 << (7 - i);
433 for (i = area->height - stroke; i < area->height; i++) {
434 pattern |= 1 << (7 - i);
442 if ((2 * radius) < area->height) {
443 rectArea.x0 = area->x0;
444 rectArea.y0 = area->y0;
445 rectArea.width = stroke;
446 rectArea.height = area->height;
447 rectArea.backgroundColor = area->backgroundColor;
449 rectArea.x0 = area->x0 + area->width - stroke;
454 draw_circle_helper(area->x0,
460 area->backgroundColor);
461 draw_circle_helper(area->x0 + area->width,
467 area->backgroundColor);
470 rectArea.x0 = area->x0 + radius;
471 rectArea.y0 = area->y0;
472 rectArea.width = area->width - 2 * radius;
473 rectArea.height = stroke;
474 rectArea.backgroundColor = borderColor;
476 rectArea.y0 = area->y0 + area->height - stroke;
478 if ((2 * radius) < area->height) {
479 rectArea.x0 = area->x0;
480 rectArea.y0 = area->y0 + radius;
481 rectArea.width = stroke;
482 rectArea.height = area->height - 2 * radius;
483 rectArea.backgroundColor = area->backgroundColor;
485 rectArea.x0 = area->x0 + area->width - stroke;
491 draw_circle_helper(area->x0 + radius,
494 BAGL_FILL_CIRCLE_PI2_PI,
497 area->backgroundColor);
498 draw_circle_helper(area->x0 + area->width - radius,
501 BAGL_FILL_CIRCLE_0_PI2,
504 area->backgroundColor);
505 draw_circle_helper(area->x0 + radius,
506 area->y0 + area->height - radius,
508 BAGL_FILL_CIRCLE_PI_3PI2,
511 area->backgroundColor);
512 draw_circle_helper(area->x0 + area->width - radius,
513 area->y0 + area->height - radius,
515 BAGL_FILL_CIRCLE_3PI2_2PI,
518 area->backgroundColor);
555static uint16_t get_bitmap_byte_cnt(
const nbgl_font_t *font, uint8_t charId)
557 if ((charId < font->first_char) || (charId > font->
last_char)) {
562 if (charId < font->last_char) {
592 int16_t x = area->x0;
595#ifdef HAVE_UNICODE_SUPPORT
600 "nbgl_drawText: x0 = %d, y0 = %d, w = %d, h = %d, fontColor = %d, "
601 "backgroundColor=%d, text = %s\n",
607 area->backgroundColor,
610 rectArea.backgroundColor = area->backgroundColor;
613 while (textLen > 0) {
618 const uint8_t *char_buffer;
623 uint16_t char_byte_cnt;
625 uint8_t nb_skipped_bytes;
630#ifdef HAVE_UNICODE_SUPPORT
631 if (unicode_ctx == NULL) {
632 unicode_ctx = nbgl_getUnicodeFont(fontId);
635 = nbgl_getUnicodeFontCharacter(unicode);
637 if (unicodeCharacter == NULL) {
640 char_width = unicodeCharacter->
width;
641#if defined(HAVE_LANGUAGE_PACK)
642 char_buffer = unicode_ctx->
bitmap;
645 char_x_max = char_width;
650 nb_skipped_bytes = (unicodeCharacter->
x_min_offset & 7) << 3;
656 nb_skipped_bytes = 0;
659 char_y_min += (uint16_t) unicodeCharacter->
y_min_offset;
660 char_x_max -= (uint16_t) unicodeCharacter->
x_max_offset;
661 char_y_max -= (uint16_t) unicodeCharacter->
y_max_offset;
664 char_byte_cnt = nbgl_getUnicodeFontCharacterByteCount();
665 encoding = unicodeCharacter->
encoding;
672 if (unicode ==
'\f') {
676 else if (unicode ==
'\b') {
679#ifdef HAVE_UNICODE_SUPPORT
680 unicode_ctx = nbgl_getUnicodeFont(fontId);
686#ifdef HAVE_UNICODE_SUPPORT
687 unicode_ctx = nbgl_getUnicodeFont(fontId);
694 if ((unicode < font->first_char) || (unicode > font->
last_char)) {
700 char_width = character->
width;
703 char_x_max = char_width;
704 char_y_max = font->
height;
714 nb_skipped_bytes = 0;
716 char_y_min = font->
y_min;
722 char_byte_cnt = get_bitmap_byte_cnt(font, unicode);
726 rectArea.x0 = x + char_x_min;
727 rectArea.y0 = area->y0 + char_y_min;
728 rectArea.height = (char_y_max - char_y_min);
729 rectArea.width = (char_x_max - char_x_min);
733 if (!char_byte_cnt || encoding == 1) {
735 &rectArea, char_buffer, char_byte_cnt, fontColor, nb_skipped_bytes);
747static void push_bits(uint8_t *buffer, uint16_t current_bits, uint8_t bits, uint8_t nb_bits)
749 uint8_t
byte = current_bits / 8;
750 uint8_t remaining_bits = 8 - current_bits % 8;
752 if (remaining_bits >= nb_bits) {
754 buffer[byte] |= bits << (remaining_bits - nb_bits);
758 buffer[byte] |= bits >> (nb_bits - remaining_bits);
759 nb_bits -= remaining_bits;
761 buffer[
byte + 1] |= bits << (8 - nb_bits);
766static void nbgl_frontDrawQrInternal(
const nbgl_area_t *area,
770 int size = qrcodegen_getSize(
qrcode);
775 .backgroundColor = area->backgroundColor,
784 for (
int x = 0; x < size; x++) {
786 for (
int y = 0; y < size; y++) {
804 qrArea.height = 5 * size;
805 for (
int x = 0; x < size; x++) {
809 for (
int y = 0; y < size; y++) {
812 for (
int z = 0; z < 5; z++) {
824 for (
int x = 0; x < size; x++) {
827 for (
int y = 0; y < size; y++) {
862 uint8_t versionNum = (version ==
QRCODE_V10) ? 10 : 4;
863 bool ok = qrcodegen_encodeText(text,
873 nbgl_frontDrawQrInternal(area, foregroundColor, version);
877 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