Geometry Arc

Overview

The Geometry Arc widget is a lightweight GUI drawing component designed for rendering arcs and circular shapes in user interfaces. It provides a simple and user-friendly API to customize arc properties such as start angle, end angle, line width, and color, addressing various arc drawing requirements.



Core Features

Description

API

Create Widget

gui_arc_create()

Set Position

gui_arc_set_position()

Set Radius

gui_arc_set_radius()

Set Color

gui_arc_set_color()

Set Opacity

gui_arc_set_opacity()

Set Start Angle

gui_arc_set_start_angle()

Set End Angle

gui_arc_set_end_angle()

Set Line Width

gui_arc_set_line_width()

Register Click Event Callback

gui_arc_on_click()

Rotation Transform

gui_arc_rotate()

Scale Transform

gui_arc_scale()

Translation Transform

gui_arc_translate()

Set Angular Gradient

gui_arc_set_angular_gradient()

Add Gradient Stop

gui_arc_add_gradient_stop()

Clear Gradient

gui_arc_clear_gradient()

Arc Group Features

Description

API

Create Arc Group

gui_arc_group_create()

Add Arc to Group

gui_arc_group_add_arc()

Set Gradient for Arc

gui_arc_group_set_gradient()

Add Gradient Stop

gui_arc_group_add_gradient_stop()

Angle Description

The arc uses a standard mathematical coordinate system for angles:

  • : Points to 3 o'clock (due east)

  • 90°: Points to 6 o'clock (due south)

  • 180°: Points to 9 o'clock (due west)

  • 270°: Points to 12 o'clock (due north)

Gradient Fill

The arc widget supports angular gradient color filling, enabling smooth color transitions along the arc's angular direction.



How Gradient Works

  • Gradient colors are linearly interpolated along the arc's angular direction

  • Supports up to 8 color stops

  • Color stop positions are represented as normalized values from 0.0 to 1.0, where 0.0 corresponds to the start angle and 1.0 corresponds to the end angle

  • Pixel colors are computed through linear interpolation between adjacent color stops

  • Uses angular gradient approach, providing smooth color transitions along the arc's angular direction

Usage Steps

  1. Create an arc widget

  2. Call gui_arc_set_angular_gradient() to set the gradient range

  3. Call gui_arc_add_gradient_stop() to add color stops (minimum 2 required)

  4. Optional: Call gui_arc_clear_gradient() to clear gradient settings

Key Points

  • Seamless Loop: For a full circle (0° to 360°), the start and end colors should be identical to achieve seamless color cycling

  • Color Interpolation: Supports linear interpolation in RGBA color space, including the alpha channel

  • Performance Optimization: Uses a color lookup table (LUT) for pre-computation, ensuring efficient rendering performance

Features Highlights

  • High Performance: Utilizes optimized rendering algorithms for smooth performance

  • Anti-Aliasing: Supports anti-aliasing for smooth visual effects

  • Flexible Configuration: Allows customization of angle range, line width, and color

  • Lightweight: Minimal memory footprint, suitable for embedded systems and resource-constrained environments

  • Ring Support: Automatically draws a full circle when start and end angles differ by 360°

  • Matrix Transforms: Supports rotation, scale, and translation matrix transforms for complex arc effects

  • Batch Rendering: Arc Group widget enables batch rendering of multiple static arcs for improved performance

Arc Group Widget

The Arc Group widget is designed for batch rendering multiple static arcs in a single buffer, significantly improving rendering performance by reducing hardware transfer operations.

Performance Benefits

  • Reduced Transfer Overhead: Combines multiple arcs into one buffer, reducing DMA / GPU transfer calls

  • Optimized for Static Content: Ideal for background arcs that don't change frequently

  • Memory Efficient: Shares a single buffer for multiple arcs

Use Cases

  • Activity rings (fitness tracking displays)

  • Multi-layer progress indicators

  • Dashboard backgrounds with multiple circular elements

  • Static decorative arc patterns

Limitations

  • Maximum 8 arcs per group (configurable via MAX_ARCS_IN_GROUP)

  • All arcs in a group share the same buffer and are rendered together

  • Best suited for static or infrequently changing content

Use Cases

The arc widget is useful in scenarios such as:

  • Progress Indicators: Displaying loading progress, battery levels, etc.

  • Dashboard Gauges: Constructing speedometers, thermometers, etc.

  • Data Visualization: Showing proportional data, statistical charts

  • User Interface Decoration: As decorative elements in the interface

  • State Indicators: Representing system statuses, connection statuses, etc.

  • Transform Animations: Leverage rotation, scale, and translation for complex arc animation effects

Configuration Instructions

To use the arc widget, enable the corresponding macro in the configuration file:

Enable the Kconfig option via menuconfig:

cd win32_sim
menuconfig ../Kconfig.gui

Select Geometry ARC Demo ( CONFIG_REALTEK_BUILD_REAL_LITE_ARC ), then save to win32_sim/.config.

#define CONFIG_REALTEK_BUILD_REAL_LITE_ARC 1

Complete Example

#include "guidef.h"
#include "gui_components_init.h"
#include "gui_arc.h"
#include "gui_arc_group.h"
#include "gui_rect.h"
#include "gui_circle.h"

static void create_activity_rings(float center_x, float center_y)
{
    // bg track color
    gui_color_t track_color_move     = gui_rgba(52, 14, 11, 200);
    gui_color_t track_color_exercise = gui_rgba(16, 37, 17, 200);
    gui_color_t track_color_stand    = gui_rgba(17, 32, 52, 200);
    // fg color
    gui_color_t col_move     = gui_rgba(255, 0, 0, 255);  // Move red
    gui_color_t col_exercise = gui_rgba(0, 255, 0, 255);  // Exercise green
    gui_color_t col_stand    = gui_rgba(0, 0, 255, 255);  // Stand blue

    // circle radius and thickness
    float outer_radius = 163.0f; float outer_thickness = 22.0f;
    float mid_radius   = 136.5f; float mid_thickness   = 22.0f;
    float inner_radius = 110.0f; float inner_thickness = 22.0f;

    uint16_t start_angle = 0;
    // background rings
    gui_arc_t *ring_move = gui_arc_create(gui_obj_get_root(), "test_ring_move", center_x,
                                          center_y, outer_radius, 0, 360, outer_thickness,
                                          track_color_move);
    gui_arc_t *ring_exercise = gui_arc_create(gui_obj_get_root(), "test_ring_exercise",
                                              center_x, center_y, mid_radius, 0, 360, mid_thickness,
                                              track_color_exercise);
    gui_arc_t *ring_stand = gui_arc_create(gui_obj_get_root(), "test_ring_stand", center_x,
                                           center_y, inner_radius, 0, 360, inner_thickness,
                                           track_color_stand);

    GUI_UNUSED(ring_move);
    GUI_UNUSED(ring_exercise);
    GUI_UNUSED(ring_stand);
    // arc style
    gui_arc_t *arc_move = gui_arc_create(gui_obj_get_root(), "test_arc_move", center_x,
                                         center_y, outer_radius,
                                         start_angle, start_angle + 252.0f, outer_thickness, col_move);
    gui_arc_t *arc_exercise = gui_arc_create(gui_obj_get_root(), "test_arc_exercise",
                                             center_x, center_y, mid_radius,
                                             start_angle, start_angle + 72.0f, mid_thickness, col_exercise);
    gui_arc_t *arc_stand = gui_arc_create(gui_obj_get_root(), "test_arc_stand", center_x,
                                          center_y, inner_radius,
                                          start_angle, start_angle + 198.0f, inner_thickness, col_stand);
    GUI_UNUSED(arc_move);
    GUI_UNUSED(arc_exercise);
    GUI_UNUSED(arc_stand);
}
void example_arc_gradient(void *parent)
{
    // Example 1: Simple two-color angular gradient (red to blue)
    // NOTE: Arc is 0-360 (full circle), but gradient is 0-361 (exceeds 360)
    // This allows the end cap to show gradient color for smooth transition
    gui_arc_t *arc1 = gui_arc_create(parent, "arc_gradient_1",
                                     120, 120, 80,    // center x, y, radius
                                     270, 270,          // start angle, end angle (FULL CIRCLE)
                                     20,              // line width
                                     gui_rgba(255, 0, 0, 255)); // fallback color (red)

    // Set angular gradient with span > 360 for end cap gradient
    gui_arc_set_angular_gradient(arc1, 270, 270);
    gui_arc_add_gradient_stop(arc1, 0.0f, gui_rgba(255, 0, 0, 255));     // Red
    gui_arc_add_gradient_stop(arc1, 1.0f, gui_rgba(0, 0, 255, 255));     // Blue


    // Example 2: Multi-color rainbow gradient (full circle, seamless loop)
    gui_arc_t *arc2 = gui_arc_create(parent, "arc_gradient_2",
                                     320, 120, 80,
                                     0, 360,
                                     20,
                                     gui_rgba(255, 0, 0, 255)); // fallback color (red)

    gui_arc_set_angular_gradient(arc2, 0, 360);

    // Redistribute color stops with 7 intervals, step ~0.142
    // Key point: 0.0f and 1.0f must be the same color (Red) for seamless loop

    // 1. Red (start)
    gui_arc_add_gradient_stop(arc2, 0.00f, gui_rgba(255, 0, 0, 255));

    // 2. Orange
    gui_arc_add_gradient_stop(arc2, 0.14f, gui_rgba(255, 127, 0, 255));

    // 3. Yellow
    gui_arc_add_gradient_stop(arc2, 0.28f, gui_rgba(255, 255, 0, 255));

    // 4. Green
    gui_arc_add_gradient_stop(arc2, 0.42f, gui_rgba(0, 255, 0, 255));

    // 5. Blue
    gui_arc_add_gradient_stop(arc2, 0.57f, gui_rgba(0, 0, 255, 255));

    // 6. Indigo
    gui_arc_add_gradient_stop(arc2, 0.71f, gui_rgba(75, 0, 130, 255));

    // 7. Violet - not at 1.0f to leave space for transition back to red
    gui_arc_add_gradient_stop(arc2, 0.85f, gui_rgba(148, 0, 211, 255));

    // 8. Red (end) - must return to red to eliminate seam
    gui_arc_add_gradient_stop(arc2, 1.00f, gui_rgba(255, 0, 0, 255));



    // Example 3: Gradient with transparency (fade effect)
    gui_arc_t *arc3 = gui_arc_create(parent, "arc_gradient_3",
                                     120, 320, 80,
                                     45, 315,
                                     25,
                                     gui_rgba(0, 255, 0, 255)); // fallback color (green)

    gui_arc_set_angular_gradient(arc3, 45, 315);
    gui_arc_add_gradient_stop(arc3, 0.0f, gui_rgba(0, 255, 0, 255));     // Opaque green
    gui_arc_add_gradient_stop(arc3, 0.5f, gui_rgba(0, 255, 255, 255));   // Cyan
    gui_arc_add_gradient_stop(arc3, 1.0f, gui_rgba(0, 255, 0, 51));      // Transparent green (alpha=51)


    // Example 4: Progress bar style gradient
    gui_arc_t *arc4 = gui_arc_create(parent, "arc_gradient_4",
                                     320, 320, 80,
                                     -90, 180,        // Start from top
                                     30,
                                     gui_rgba(0, 255, 0, 255)); // fallback color (green)

    gui_arc_set_angular_gradient(arc4, -90, 180);
    gui_arc_add_gradient_stop(arc4, 0.0f, gui_rgba(255, 0, 0, 255));     // Red (start)
    gui_arc_add_gradient_stop(arc4, 0.5f, gui_rgba(255, 255, 0, 255));   // Yellow (middle)
    gui_arc_add_gradient_stop(arc4, 1.0f, gui_rgba(0, 255, 0, 255));     // Green (end)
}

void example_arc_group(void *parent)
{
    // Example: Arc Group for batch rendering multiple static arcs
    // This is useful for background rings that don't change frequently
    // Performance benefit: Reduces DMA/GPU transfer calls by combining multiple arcs into one buffer

    float center_x = 240.0f;
    float center_y = 240.0f;

    // Calculate bounding box for the arc group
    float outer_radius = 163.0f;
    float outer_thickness = 22.0f;
    int box_size = (int)(outer_radius + outer_thickness / 2 + 2) * 2 + 4;
    int box_x = (int)center_x - box_size / 2;
    int box_y = (int)center_y - box_size / 2;

    // Create arc group for background rings
    gui_arc_group_t *bg_group = gui_arc_group_create(parent, "bg_rings",
                                                     box_x, box_y, box_size, box_size);

    float group_cx = box_size / 2.0f, group_cy = group_cx;

    // Add first arc (outer ring) with gradient
    int arc0 = gui_arc_group_add_arc(bg_group, group_cx, group_cy,
                                     163.0f, 0, 360, 22.0f, gui_rgba(50, 50, 50, 255));
    gui_arc_group_set_gradient(bg_group, arc0, 0, 360);
    gui_arc_group_add_gradient_stop(bg_group, arc0, 0.0f, gui_rgba(60, 0, 0, 100));
    gui_arc_group_add_gradient_stop(bg_group, arc0, 0.5f, gui_rgba(80, 20, 20, 100));
    gui_arc_group_add_gradient_stop(bg_group, arc0, 1.0f, gui_rgba(60, 0, 0, 100));

    // Add second arc (middle ring) with gradient
    int arc1 = gui_arc_group_add_arc(bg_group, group_cx, group_cy,
                                     136.5f, 0, 360, 22.0f, gui_rgba(50, 50, 50, 255));
    gui_arc_group_set_gradient(bg_group, arc1, 0, 360);
    gui_arc_group_add_gradient_stop(bg_group, arc1, 0.0f, gui_rgba(0, 60, 0, 100));
    gui_arc_group_add_gradient_stop(bg_group, arc1, 0.5f, gui_rgba(20, 80, 20, 100));
    gui_arc_group_add_gradient_stop(bg_group, arc1, 1.0f, gui_rgba(0, 60, 0, 100));

    // Add third arc (inner ring) with gradient
    int arc2 = gui_arc_group_add_arc(bg_group, group_cx, group_cy,
                                     110.0f, 0, 360, 22.0f, gui_rgba(50, 50, 50, 255));
    gui_arc_group_set_gradient(bg_group, arc2, 0, 360);
    gui_arc_group_add_gradient_stop(bg_group, arc2, 0.0f, gui_rgba(0, 20, 60, 100));
    gui_arc_group_add_gradient_stop(bg_group, arc2, 0.5f, gui_rgba(20, 40, 80, 100));
    gui_arc_group_add_gradient_stop(bg_group, arc2, 1.0f, gui_rgba(0, 20, 60, 100));

    // Create foreground arcs separately (these can change dynamically)
    gui_arc_t *arc_move = gui_arc_create(parent, "fg_arc_move", center_x, center_y,
                                         163.0f, 0, 252.0f, 22.0f, gui_rgba(255, 0, 0, 255));
    gui_arc_set_angular_gradient(arc_move, 0, 252.0f);
    gui_arc_add_gradient_stop(arc_move, 0.0f, gui_rgba(250, 17, 79, 255));
    gui_arc_add_gradient_stop(arc_move, 1.0f, gui_rgba(255, 100, 150, 255));

    gui_arc_t *arc_exercise = gui_arc_create(parent, "fg_arc_exercise", center_x, center_y,
                                             136.5f, 0, 72.0f, 22.0f, gui_rgba(0, 255, 0, 255));
    gui_arc_set_angular_gradient(arc_exercise, 0, 72.0f);
    gui_arc_add_gradient_stop(arc_exercise, 0.0f, gui_rgba(164, 255, 4, 255));
    gui_arc_add_gradient_stop(arc_exercise, 1.0f, gui_rgba(255, 255, 0, 255));

    gui_arc_t *arc_stand = gui_arc_create(parent, "fg_arc_stand", center_x, center_y,
                                          110.0f, 0, 198.0f, 22.0f, gui_rgba(0, 0, 255, 255));
    gui_arc_set_angular_gradient(arc_stand, 0, 198.0f);
    gui_arc_add_gradient_stop(arc_stand, 0.0f, gui_rgba(0, 255, 255, 255));
    gui_arc_add_gradient_stop(arc_stand, 1.0f, gui_rgba(0, 150, 255, 255));

    GUI_UNUSED(bg_group);
    GUI_UNUSED(arc_move);
    GUI_UNUSED(arc_exercise);
    GUI_UNUSED(arc_stand);
}

static int geometry_demo_init(void)
{

    // float center_x = 480 / 2.0f;
    // float center_y = 480 / 2.0f;
    // create_activity_rings(center_x, center_y);
    // example_arc_gradient(gui_obj_get_root());
    example_arc_group(gui_obj_get_root());

    return 0;
}

GUI_INIT_APP_EXPORT(geometry_demo_init);

API

Functions

gui_arc_t *gui_arc_create(void *parent, const char *name, int x, int y, int radius, float start_angle, float end_angle, float line_width, gui_color_t color)

Create a new arc widget.

Parameters:
  • parent -- Parent widget or NULL for top-level widget.

  • name -- Name of the widget.

  • x -- Center X coordinate.

  • y -- Center Y coordinate.

  • radius -- Arc radius.

  • start_angle -- Start angle in degrees.

  • end_angle -- End angle in degrees.

  • line_width -- Line width.

  • color -- Arc color.

Returns:

Pointer to the created arc widget.

void gui_arc_set_position(gui_arc_t *arc, int x, int y)

Move arc geometry.

Parameters:
  • arc -- Pointer to the arc widget.

  • x -- New center X coordinate relative to widget.

  • y -- New center Y coordinate relative to widget.

void gui_arc_set_radius(gui_arc_t *arc, int radius)

Set the radius of the arc widget.

Parameters:
  • arc -- Pointer to the arc widget.

  • radius -- Arc radius.

void gui_arc_set_opacity(gui_arc_t *arc, uint8_t opacity)

Set the opacity of the arc widget.

Parameters:
  • arc -- Pointer to the arc widget.

  • opacity -- Opacity value (0-255).

void gui_arc_set_color(gui_arc_t *arc, gui_color_t color)

Set the color of the arc widget.

Parameters:
  • arc -- Pointer to the arc widget.

  • color -- Arc color.

void gui_arc_set_start_angle(gui_arc_t *arc, float start_angle)

Set the start angle of the arc widget.

Parameters:
  • arc -- Pointer to the arc widget.

  • start_angle -- Start angle in degrees.

void gui_arc_set_end_angle(gui_arc_t *arc, float end_angle)

Set the end angle of the arc widget.

Parameters:
  • arc -- Pointer to the arc widget.

  • end_angle -- End angle in degrees.

void gui_arc_set_line_width(gui_arc_t *arc, float line_width)

Set the line width of the arc widget.

Parameters:
  • arc -- Pointer to the arc widget.

  • line_width -- Line width.

void gui_arc_on_click(gui_arc_t *arc, void *callback, void *parameter)

Register click event callback for arc widget.

Parameters:
  • arc -- Pointer to the arc widget.

  • callback -- Callback function pointer.

  • parameter -- Optional parameter to pass to callback.

void gui_arc_rotate(gui_arc_t *arc, float degrees)

Apply rotation transformation to the arc widget.

Parameters:
  • arc -- Pointer to the arc widget.

  • degrees -- Rotation angle in degrees (clockwise).

void gui_arc_scale(gui_arc_t *arc, float scale_x, float scale_y)

Apply scale transformation to the arc widget.

Parameters:
  • arc -- Pointer to the arc widget.

  • scale_x -- Scale factor in X direction.

  • scale_y -- Scale factor in Y direction.

void gui_arc_translate(gui_arc_t *arc, float tx, float ty)

Apply translation transformation to the arc widget.

Parameters:
  • arc -- Pointer to the arc widget.

  • tx -- Translation in X direction (pixels).

  • ty -- Translation in Y direction (pixels).

void gui_arc_set_angular_gradient(gui_arc_t *arc, float start_angle, float end_angle)

Set angular gradient for arc widget.

Parameters:
  • arc -- Pointer to the arc widget.

  • start_angle -- Start angle for gradient (degrees).

  • end_angle -- End angle for gradient (degrees).

void gui_arc_add_gradient_stop(gui_arc_t *arc, float position, gui_color_t color)

Add color stop to arc gradient.

Parameters:
  • arc -- Pointer to the arc widget.

  • position -- Position of color stop (0.0 to 1.0).

  • color -- Color at arc stop.

void gui_arc_clear_gradient(gui_arc_t *arc)

Clear gradient and use solid color.

Parameters:

arc -- Pointer to the arc widget.

struct gui_arc_t

Arc widget structure.

Public Members

gui_obj_t base

Base widget.

draw_img_t *draw_img

Drawing image object.

uint8_t *pixel_buffer

Cached pixel buffer.

uint32_t buffer_size

Buffer size.

int buffer_w

Actual buffer width (may be optimized).

int buffer_h

Actual buffer height (may be optimized).

bool buffer_valid

Buffer cache valid flag.

DrawContext draw_ctx

Drawing context.

uint8_t opacity_value

Opacity value.

int x

Center X coordinate relative to widget.

int y

Center Y coordinate relative to widget.

int radius

Arc radius.

float start_angle

Start angle in degrees.

float end_angle

End angle in degrees.

float line_width

Line width.

gui_color_t color

Arc color (stored as uint32_t internally).

int cached_x
int cached_y
int cached_radius
float cached_start_angle
float cached_end_angle
float cached_line_width
gui_color_t cached_color
uint32_t cached_not_show
float degrees

Rotation angle in degrees.

float scale_x

Scale factor in X direction.

float scale_y

Scale factor in Y direction.

float offset_x

Translation offset in X direction.

float offset_y

Translation offset in Y direction.

Gradient *gradient

Optional gradient for arc stroke.

bool use_gradient

Flag to enable gradient rendering.

Defines

MAX_ARCS_IN_GROUP 8

Functions

gui_arc_group_t *gui_arc_group_create(void *parent, const char *name, int x, int y, int w, int h)

Create arc group widget.

Parameters:
  • parent -- Parent widget.

  • name -- Widget name.

  • x -- X position.

  • y -- Y position.

  • w -- Width.

  • h -- Height.

Returns:

Pointer to created arc group.

int gui_arc_group_add_arc(gui_arc_group_t *group, float cx, float cy, float radius, float start_angle, float end_angle, float line_width, gui_color_t color)

Add arc to group.

Parameters:
  • group -- Arc group widget.

  • cx -- Center X relative to group.

  • cy -- Center Y relative to group.

  • radius -- Arc radius.

  • start_angle -- Start angle.

  • end_angle -- End angle.

  • line_width -- Line width.

  • color -- Arc color.

Returns:

Index of added arc, or -1 if group is full.

void gui_arc_group_set_gradient(gui_arc_group_t *group, int arc_index, float start_angle, float end_angle)

Set gradient for arc in group.

Parameters:
  • group -- Arc group widget.

  • arc_index -- Index of arc (returned by add_arc).

  • start_angle -- Gradient start angle.

  • end_angle -- Gradient end angle.

void gui_arc_group_add_gradient_stop(gui_arc_group_t *group, int arc_index, float position, gui_color_t color)

Add gradient stop to arc in group.

Parameters:
  • group -- Arc group widget.

  • arc_index -- Index of arc.

  • position -- Stop position (0.0-1.0).

  • color -- Stop color.

struct arc_def_t

Arc definition for group rendering

Public Members

float cx

Center X relative to group.

float cy

Center Y relative to group.

float radius

Arc radius.

float start_angle

Start angle in degrees.

float end_angle

End angle in degrees.

float line_width

Line width.

Gradient *gradient

Optional gradient.

bool use_gradient

Use gradient flag.

gui_color_t color

Solid color (if no gradient).

struct gui_arc_group_t

Arc group widget structure

Public Members

gui_obj_t base

Base widget.

draw_img_t *draw_img

Drawing image object.

uint8_t *pixel_buffer

Cached pixel buffer.

uint32_t buffer_size

Buffer size.

bool buffer_valid

Buffer cache valid flag.

DrawContext draw_ctx

Drawing context.

uint8_t opacity_value

Opacity value.

arc_def_t arcs[MAX_ARCS_IN_GROUP]

Arc definitions.

int arc_count

Number of arcs in group.

int buffer_w

Buffer width.

int buffer_h

Buffer height.