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 |
|
Set Position |
|
Set Radius |
|
Set Color |
|
Set Opacity |
|
Set Start Angle |
|
Set End Angle |
|
Set Line Width |
|
Register Click Event Callback |
|
Rotation Transform |
|
Scale Transform |
|
Translation Transform |
|
Set Angular Gradient |
|
Add Gradient Stop |
|
Clear Gradient |
Arc Group Features
Description |
API |
|---|---|
Create Arc Group |
|
Add Arc to Group |
|
Set Gradient for Arc |
|
Add Gradient Stop |
Angle Description
The arc uses a standard mathematical coordinate system for angles:
0°: 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
Create an arc widget
Call
gui_arc_set_angular_gradient()to set the gradient rangeCall
gui_arc_add_gradient_stop()to add color stops (minimum 2 required)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).
-
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.
-
gui_obj_t base
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).
-
float cx
-
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.
-
int arc_count
-
Number of arcs in group.
-
int buffer_w
-
Buffer width.
-
int buffer_h
-
Buffer height.
-
gui_obj_t base