18 #include "qrcodegen.h"
34 #define QR_PIXEL_WIDTH_HEIGHT 4
46 #define qrcode ((QrCodeBuffer_t *) ramBuffer)->qrcode
47 #define tempBuffer ((QrCodeBuffer_t *) ramBuffer)->tempBuffer
48 #define QrDrawBuffer ((QrCodeBuffer_t *) ramBuffer)->QrDrawBuffer
58 #ifndef SCREEN_SIZE_WALLET
59 static const uint8_t quarter_disc_3px_1bpp[] = {0xEC, 0xFF};
60 static const uint8_t quarter_disc_3px_90_1bpp[] = {0x2F, 0xFF};
61 static const uint8_t quarter_disc_3px_180_1bpp[] = {0x9B, 0xFF};
62 static const uint8_t quarter_disc_3px_270_1bpp[] = {0xFA, 0x00};
64 static const uint8_t quarter_circle_3px_1bpp[] = {0x4C, 0x00};
65 static const uint8_t quarter_circle_3px_90_1bpp[] = {0x0D, 0x00};
66 static const uint8_t quarter_circle_3px_180_1bpp[] = {0x19, 0x00};
67 static const uint8_t quarter_circle_3px_270_1bpp[] = {0x58, 0x00};
71 static const uint8_t radiusValues[] = {
72 #ifdef SCREEN_SIZE_WALLET
85 #ifdef SCREEN_SIZE_WALLET
87 static const uint8_t *topQuarterDiscs[] = {
88 C_quarter_disc_top_left_32px_1bpp_bitmap,
90 C_quarter_disc_top_left_40px_1bpp_bitmap,
92 C_quarter_disc_top_left_44px_1bpp_bitmap
96 static const uint8_t *bottomQuarterDiscs[] = {
97 C_quarter_disc_bottom_left_32px_1bpp_bitmap,
99 C_quarter_disc_bottom_left_40px_1bpp_bitmap,
101 C_quarter_disc_bottom_left_44px_1bpp_bitmap
106 static const uint8_t *topQuarterCircles[] = {
107 C_quarter_circle_top_left_32px_1bpp_bitmap,
109 C_quarter_circle_top_left_40px_1bpp_bitmap,
111 C_quarter_circle_top_left_44px_1bpp_bitmap
115 static const uint8_t *bottomQuarterCircles[] = {
116 C_quarter_circle_bottom_left_32px_1bpp_bitmap,
118 C_quarter_circle_bottom_left_40px_1bpp_bitmap,
120 C_quarter_circle_bottom_left_44px_1bpp_bitmap
138 static void draw_circle_helper(
int x_center,
146 const uint8_t *quarter_buffer = NULL;
153 area.width = area.height = radiusValues[radiusIndex];
154 #ifdef SCREEN_SIZE_WALLET
155 if (borderColor == innerColor) {
157 quarter_buffer = (
const uint8_t *) PIC(topQuarterDiscs[radiusIndex]);
160 quarter_buffer = (
const uint8_t *) PIC(bottomQuarterDiscs[radiusIndex]);
165 quarter_buffer = (
const uint8_t *) PIC(topQuarterCircles[radiusIndex]);
168 quarter_buffer = (
const uint8_t *) PIC(bottomQuarterCircles[radiusIndex]);
178 area.x0 = x_center - area.width;
184 area.y0 = y_center - area.width;
188 area.x0 = x_center - area.width;
189 area.y0 = y_center - area.width;
198 quarter_buffer = (borderColor == innerColor) ? quarter_disc_3px_180_1bpp
199 : quarter_circle_3px_180_1bpp;
202 area.x0 = x_center - area.width;
204 quarter_buffer = (borderColor == innerColor) ? quarter_disc_3px_270_1bpp
205 : quarter_circle_3px_270_1bpp;
209 area.y0 = y_center - area.width;
210 quarter_buffer = (borderColor == innerColor) ? quarter_disc_3px_90_1bpp
211 : quarter_circle_3px_90_1bpp;
214 area.x0 = x_center - area.width;
215 area.y0 = y_center - area.width;
217 = (borderColor == innerColor) ? quarter_disc_3px_1bpp : quarter_circle_3px_1bpp;
243 "nbgl_drawRoundedRect x0 = %d, y0 = %d, width =%d, height =%d\n",
250 radius = radiusValues[radiusIndex];
262 rectArea.x0 = area->x0 + radius;
263 rectArea.y0 = area->y0;
264 rectArea.width = area->width - (2 * radius);
265 rectArea.height = area->height;
266 rectArea.backgroundColor = innerColor;
273 rectArea.x0 = area->x0;
274 rectArea.y0 = area->y0 + radius;
275 rectArea.width = radius;
276 rectArea.height = area->height - (2 * radius);
279 rectArea.x0 = area->x0 + area->width - radius;
280 rectArea.y0 = area->y0 + radius;
281 rectArea.width = radius;
282 rectArea.height = area->height - (2 * radius);
285 #ifdef SCREEN_SIZE_NANO
286 if (radiusIndex == RADIUS_1_PIXEL) {
291 draw_circle_helper(area->x0 + radius,
297 area->backgroundColor);
298 draw_circle_helper(area->x0 + area->width - radius,
304 area->backgroundColor);
305 draw_circle_helper(area->x0 + radius,
306 area->y0 + area->height - radius,
311 area->backgroundColor);
312 draw_circle_helper(area->x0 + area->width - radius,
313 area->y0 + area->height - radius,
318 area->backgroundColor);
342 "nbgl_drawRoundedBorderedRect: innerColor = %d, borderColor = %d, backgroundColor=%d\n",
345 area->backgroundColor);
348 radius = radiusValues[radiusIndex];
356 DRAW_LOGGER,
"nbgl_drawRoundedBorderedRect forbidden radius index =%d\n", radiusIndex);
359 rectArea.backgroundColor = innerColor;
362 if ((innerColor == borderColor) && (borderColor == area->backgroundColor)) {
363 rectArea.x0 = area->x0;
364 rectArea.y0 = area->y0;
365 rectArea.width = area->width;
366 rectArea.height = area->height;
371 if ((2 * radius) < area->width) {
372 rectArea.x0 = area->x0 + radius;
373 rectArea.y0 = area->y0;
374 rectArea.width = area->width - (2 * radius);
375 rectArea.height = area->height;
380 if ((2 * radius) < area->height) {
381 rectArea.x0 = area->x0;
382 rectArea.y0 = area->y0 + radius;
383 rectArea.width = radius;
384 rectArea.height = area->height - (2 * radius);
386 rectArea.x0 = area->x0 + area->width - radius;
387 rectArea.y0 = area->y0 + radius;
393 #ifdef SCREEN_SIZE_WALLET
399 else if (stroke == 2) {
403 else if (stroke == 3) {
407 else if (stroke == 4) {
415 rectArea.x0 = area->x0 + radius;
416 rectArea.y0 = area->y0;
417 rectArea.width = area->width - 2 * radius;
420 rectArea.x0 = area->x0 + radius;
421 rectArea.y0 = area->y0 + area->height - 4;
424 rectArea.x0 = area->x0 + radius;
425 rectArea.y0 = area->y0;
426 rectArea.width = area->width - 2 * radius;
427 rectArea.height = stroke;
428 rectArea.backgroundColor = borderColor;
430 rectArea.y0 = area->y0 + area->height - stroke;
433 if ((2 * radius) < area->height) {
434 rectArea.x0 = area->x0;
435 rectArea.y0 = area->y0 + radius;
436 rectArea.width = stroke;
437 rectArea.height = area->height - 2 * radius;
438 rectArea.backgroundColor = borderColor;
440 rectArea.x0 = area->x0 + area->width - stroke;
446 draw_circle_helper(area->x0 + radius,
452 area->backgroundColor);
453 draw_circle_helper(area->x0 + area->width - radius,
459 area->backgroundColor);
460 draw_circle_helper(area->x0 + radius,
461 area->y0 + area->height - radius,
466 area->backgroundColor);
467 draw_circle_helper(area->x0 + area->width - radius,
468 area->y0 + area->height - radius,
473 area->backgroundColor);
511 if ((charId < font->first_char) || (charId > font->
last_char)) {
516 if (charId < font->last_char) {
549 #ifdef HAVE_UNICODE_SUPPORT
554 "nbgl_drawText: x0 = %d, y0 = %d, w = %d, h = %d, fontColor = %d, "
555 "backgroundColor=%d, text = %s\n",
561 area->backgroundColor,
564 rectArea.backgroundColor = area->backgroundColor;
567 while (textLen > 0) {
584 #ifdef HAVE_UNICODE_SUPPORT
585 if (unicode_ctx == NULL) {
586 unicode_ctx = nbgl_getUnicodeFont(fontId);
589 = nbgl_getUnicodeFontCharacter(unicode);
591 if (unicodeCharacter == NULL) {
594 char_width = unicodeCharacter->
width;
595 #if defined(HAVE_LANGUAGE_PACK)
596 char_buffer = unicode_ctx->
bitmap;
599 char_x_max = char_width;
604 nb_skipped_bytes = (unicodeCharacter->
x_min_offset & 7) << 3;
610 nb_skipped_bytes = 0;
618 char_byte_cnt = nbgl_getUnicodeFontCharacterByteCount();
619 encoding = unicodeCharacter->
encoding;
626 if (unicode ==
'\f') {
630 else if (unicode ==
'\b') {
633 #ifdef HAVE_UNICODE_SUPPORT
634 unicode_ctx = nbgl_getUnicodeFont(fontId);
640 #ifdef HAVE_UNICODE_SUPPORT
641 unicode_ctx = nbgl_getUnicodeFont(fontId);
648 if ((unicode < font->first_char) || (unicode > font->
last_char)) {
654 char_width = character->
width;
657 char_x_max = char_width;
658 char_y_max = font->
height;
668 nb_skipped_bytes = 0;
670 char_y_min = font->
y_min;
676 char_byte_cnt = get_bitmap_byte_cnt(font, unicode);
680 rectArea.x0 = x + char_x_min;
681 rectArea.y0 = area->y0 + char_y_min;
682 rectArea.height = (char_y_max - char_y_min);
683 rectArea.width = (char_x_max - char_x_min);
687 if (!char_byte_cnt || encoding == 1) {
689 &rectArea, char_buffer, char_byte_cnt, fontColor, nb_skipped_bytes);
700 static void nbgl_frontDrawQrInternal(
const nbgl_area_t *area,
704 int size = qrcodegen_getSize(
qrcode);
709 .backgroundColor = area->backgroundColor,
717 for (
int x = 0; x < size; x++) {
719 for (
int y = 0; y < size; y++) {
740 for (
int y = 0; y < size; y++) {
742 for (
int x = 0; x < size; x++) {
770 bool ok = qrcodegen_encodeText(text,
780 nbgl_frontDrawQrInternal(area, foregroundColor, version);
784 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.
@ BAGL_FILL_CIRCLE_PI_3PI2
@ BAGL_FILL_CIRCLE_3PI2_2PI
@ BAGL_FILL_CIRCLE_PI2_PI
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_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_frontDrawHorizontalLine(const nbgl_area_t *area, uint8_t mask, color_t lineColor)
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 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