Canvas

The Canvas widget provides 2D graphics rendering capabilities based on NanoVG, supporting software-accelerated rendering and multiple image output formats.



Warning

Before usage, ensure: Sufficient frame buffer memory.

Overview

GUI Canvas is a 2D drawing component based on NanoVG, providing:

  • Basic shape drawing (rectangles, circles, arcs, etc.)

  • Support for RGBA/RGB565/PNG/JPG output formats

  • NanoVG software-accelerated rendering (via AGGE backend)

  • Direct buffer output functionality

  • Blank buffer initialization support

Core Features

Creation & Initialization

  1. Using gui_canvas_create function

    Creates a NanoVG canvas widget and returns a pointer to the canvas object.

    // Example: Create 200x200 canvas
    gui_canvas_t* canvas = gui_canvas_create(
        parent,     // Parent widget pointer
        "my_canvas", // Canvas name
        NULL,       // Reserved parameter
        0, 0,       // x,y coordinates
        200, 200    // width,height
    );
    
    if (canvas == NULL) {
        // Error handling
    }
    
  2. Using gui_canvas_set_canvas_cb to set drawing callback

    Sets the redraw callback function that gets called when canvas needs refreshing.

    // Example drawing function
    static void my_draw_function(gui_canvas_t* canvas) {
        NVGcontext* vg = canvas->vg;
    
        // Draw red rectangle
        nvgBeginPath(vg);
        nvgRect(vg, 50, 50, 100, 100);
        nvgFillColor(vg, nvgRGBA(255, 0, 0, 255));
        nvgFill(vg);
    }
    
    // Set callback
    gui_canvas_set_canvas_cb(canvas, my_draw_function);
    

Manual Refresh: Set canvas->render = 1 to manually trigger redraw (callback will be called next frame).

Image Output

This function requires a pre-allocated buffer and is suitable for scenarios where repeated rendering or memory constraints are important.

// Example: Output to a pre-allocated RGBA buffer
uint8_t img_head_size = sizeof(gui_rgb_data_head_t);
uint32_t img_size = img_head_size + 640 * 480 * 4; // RGBA requires width*height*4 bytes plus header
uint8_t *buffer = gui_lower_malloc(img_size);
gui_canvas_render_to_image_buffer(
    GUI_CANVAS_OUTPUT_RGBA,
    false,
    640, 480,
    my_render_func,
    buffer);

Example Code

Complete card view usage example:

Enable macro CONFIG_REALTEK_BUILD_CANVAS in menu_config.h to run this example.

#include <math.h>
#include "guidef.h"
#include "gui_img.h"
#include "gui_obj.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "gui_server.h"
#include "gui_components_init.h"
#include "gui_canvas.h"
#include "gui_canvas_rect.h"
#include "gui_canvas_round_rect.h"
#include "gui_canvas.h"

static void draw_circle_callback(gui_canvas_t *canvas)
{
    nvgBeginPath(canvas->vg);
    nvgCircle(canvas->vg, 100, 100, 50);
    nvgFillColor(canvas->vg, nvgRGBA(255, 255, 0, 255));
    nvgFill(canvas->vg);

    nvgBeginPath(canvas->vg);
    nvgEllipse(canvas->vg, 200, 100, 80, 40);
    nvgStrokeColor(canvas->vg, nvgRGBA(0, 0, 255, 255));
    nvgStrokeWidth(canvas->vg, 2.0f);
    nvgStroke(canvas->vg);
}

void test_circle_drawing()
{
    gui_canvas_t *canvas = gui_canvas_create(gui_obj_get_root(), "test_circle", NULL, 0, 0, 300, 200);
    gui_canvas_set_canvas_cb(canvas, draw_circle_callback);
}
static void canvas_rect_cb(gui_canvas_t *canvas)
{
    NVGcontext *vg = canvas->vg;
    nvgBeginPath(vg);
    nvgRoundedRect(vg, 150, 150, 200, 180, 20);

    nvgStrokeWidth(vg, 8.0f);
    nvgStrokeColor(vg, nvgRGB(255, 0, 0));
    nvgStroke(vg);

    NVGpaint gradient = nvgLinearGradient(vg, 150, 150, 350, 330, nvgRGB(255, 0, 0), nvgRGBA(0, 255, 0,
                                          255));
    nvgFillPaint(vg, gradient);
    nvgFill(vg);
}
void test_rect_drawing()
{

    gui_canvas_t *canvas = gui_canvas_create(gui_obj_get_root(), "canvas", 0, 0, 0, 480, 480);

    gui_canvas_set_canvas_cb(canvas, canvas_rect_cb);
}
static void arc_cb(gui_canvas_t *canvas)
{
    static float  progress;
    progress += 0.01f;
    nvgArc(canvas->vg, 480 / 2, 480 / 2, 150, 0, 3.14f * (sinf(progress) + 1), NVG_CCW);
    nvgStrokeWidth(canvas->vg, 20);
    nvgStrokeColor(canvas->vg, nvgRGB(178, 34, 34));
    nvgStroke(canvas->vg);
}

void test_arc_drawing()
{
    gui_canvas_t *canvas = gui_canvas_create(gui_obj_get_root(), "test_arc", NULL, 0, 0, 480, 480);
    gui_canvas_set_canvas_cb(canvas, arc_cb);
    canvas->render = 1;
}


void test_render(NVGcontext *vg)
{
    // Draw red background
    nvgBeginPath(vg);
    nvgRect(vg, 0, 0, 480, 480);
    nvgFillColor(vg, nvgRGBA(255, 0, 0, 255));
    nvgFill(vg);

    // Draw green rectangle
    nvgBeginPath(vg);
    nvgRect(vg, 100, 100, 200, 200);
    nvgFillColor(vg, nvgRGBA(0, 255, 0, 255));
    nvgFill(vg);
}
static int app_init(void)
{
    test_rect_drawing();
    test_arc_drawing();
    test_circle_drawing();
    return 0;
}

GUI_INIT_APP_EXPORT(app_init);

API

Defines

GUI_CANVAS_OUTPUT_PNG 1
GUI_CANVAS_OUTPUT_JPG 2
GUI_CANVAS_OUTPUT_RGBA 3
GUI_CANVAS_OUTPUT_RGB565 4

Typedefs

typedef void (*gui_canvas_render_function)(NVGcontext *vg)

Functions

gui_canvas_t *gui_canvas_create(void *parent, const char *name, void *addr, int16_t x, int16_t y, int16_t w, int16_t h)

Create a canvas widget used to draw graphics in nanovg.

Parameters:
  • parent – The father widget nested in.

  • name – This widget canvas widget’s name.

  • addr – Address of the canvas.

  • x – The X-axis coordinate relative to parent widget.

  • y – The Y-axis coordinate relative to parent widget.

  • w – Width of the canvas.

  • h – Height of the canvas.

Returns:

gui_canvas_t* Pointer to the created canvas widget.

void gui_canvas_set_canvas_cb(gui_canvas_t *this_widget, void (*cb)(gui_canvas_t *this_widget))

Set the callback function for drawing specific shapes.

Parameters:
  • this_widget – This widget pointer.

  • cb – The callback function for drawing specific shapes.

void *gui_canvas_render_to_image_buffer(int format, bool compression, int image_width, int image_height, gui_canvas_render_function renderer, uint8_t *target_buffer)

Render a graphical canvas to a specified buffer in a chosen image format.

Utilizes the provided renderer function to generate graphical content within a canvas, subsequently outputting the rendered image into the designated target buffer in accordance with the specified format. Optional compression is available based on the format.

Parameters:
  • format – The format of the output image. It should be specified as one of the following options:

    • GUI_CANVAS_OUTPUT_PNG for PNG format.

    • GUI_CANVAS_OUTPUT_JPG for JPG format.

    • GUI_CANVAS_OUTPUT_RGBA for RGBA format.

    • GUI_CANVAS_OUTPUT_RGB565 for RGB565 format.

  • compression – A boolean flag indicating whether to compress the output image data. Note: Compression is only applicable for RGBA/RGB565 formats.

  • image_width – The width of the output image, specified in pixels.

  • image_height – The height of the output image, specified in pixels.

  • renderer – Function pointer to the rendering callback function, responsible for executing drawing operations within the rendering context (NVGcontext).

  • target_buffer – A pointer to the pre-allocated buffer designated for storing the rendered image data. Ensure the buffer size is adequate to hold the image data in the specified format.

Returns:

A pointer to a gui_img_t structure representing the rendered image stored in the target buffer.

struct gui_canvas_t

Canvas structure.

Public Members

gui_obj_t base
NVGcontext *vg
void (*nanovg_canvas_cb)(struct gui_canvas *this_widget)
uint8_t checksum
uint8_t render