This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Bug: nrf_gfx_print font_color should be uint32_t, not uint16_t

The rest of the nrf_gfx library uses uint32_ts for color, but for some reason the nrf_gfx_print function uses a uint16_t.

The fix requires changing the color type in nrf_gfx_print along with the write_character & pixel_draw static functions.

  • Hello,

    Thank you for reporting this. Indeed, it looks like a bug to me. I will forward this to our SDK team.

    Best regards,

    Edvin

  • While someone is looking at this bug, I also improved the algorithm in the 'write_character' function to aggregate writes to adjacent pixels, switching from using 'pixel_draw' to use 'rect_draw' where possible. For my display (ILI9488 talking via SPI), this drastically decreases the traffic to the device, especially on larger font sizes. Given that CPU cycles are cheaper than peripheral access, I suspect this will help basically every device.

    static void write_character(nrf_lcd_t const *p_instance,
                                nrf_gfx_font_desc_t const *p_font,
                                uint8_t character,
                                uint16_t *p_x,
                                uint16_t y,
                                uint32_t font_color) {
        uint8_t char_idx = character - p_font->startChar;
        uint16_t bytes_in_line = CEIL_DIV(p_font->charInfo[char_idx].widthBits, 8);
    
        if (character == ' ') {
            *p_x += p_font->height / 2;
            return;
        }
    
        uint16_t contiguous_pixels = 0;
    
        for (uint16_t i = 0; i < p_font->height; i++) {
            for (uint16_t j = 0; j < bytes_in_line; j++) {
                for (uint8_t k = 0; k < 8; k++) {
                    if ((1 << (7 - k)) &
                        p_font->data[p_font->charInfo[char_idx].offset + i * bytes_in_line + j]) {
                        contiguous_pixels += 1;
                    } else if (contiguous_pixels) {    // This pixel isn't selected, but previous pixel was.
                        uint16_t x = *p_x + j * 8 + k - 1 - contiguous_pixels;
                        if (contiguous_pixels == 1) {
                            pixel_draw(p_instance, x, y + i, font_color);
                        } else {
                            rect_draw(p_instance, x, y + i, contiguous_pixels, 1, font_color);
                        }
                        contiguous_pixels = 0;
                    }
                }
            }
            // At the end of the line, draw any undrawn pixels.
            if (contiguous_pixels) {
                uint16_t x = *p_x + bytes_in_line - 1 - contiguous_pixels;
                if (contiguous_pixels == 1) {
                    pixel_draw(p_instance, x, y + i, font_color);
                } else {
                    rect_draw(p_instance, x, y + i, contiguous_pixels, 1, font_color);
                }
                contiguous_pixels = 0;
            }
        }
    
        *p_x += p_font->charInfo[char_idx].widthBits + p_font->spacePixels;
    }

    Feel free to use this in the SDK (I relinquish any copyright) if it suits.

Related