圆形 (Geometry Circle)
概述
圆形控件是一个轻量级的 GUI 绘图组件,专门用于在用户界面中绘制圆形图形。该控件提供了简洁易用的 API ,支持自定义圆形的中心位置、半径、颜色等属性,能够创建各种圆形 UI 元素。

核心功能
描述 |
API |
|---|---|
创建控件 |
|
设置属性 |
|
设置位置 |
|
设置半径 |
|
设置颜色 |
|
设置描边 |
|
清除描边 |
|
设置外发光 |
|
清除外发光 |
|
设置不透明度 |
|
注册点击事件回调 |
|
旋转变换 |
|
缩放变换 |
|
平移变换 |
|
设置径向渐变 |
|
设置角度渐变 |
|
添加渐变色点 |
|
清除渐变色 |
圆形特性
圆形控件具有以下几何特性:
圆心定位: 通过中心点坐标精确定位
半径控制: 支持任意大小的半径值
完美圆形: 确保绘制完美的几何圆形
边界处理: 自动处理圆形与边界的裁剪
内部描边: 描边向圆形内部扩展,不改变控件尺寸
外发光
控件可选地绘制一圈外发光。它是独立的一层,画在本体下方,本体的填充和描边 都不受影响。
gui_color_t glow = gui_rgba(80, 200, 255, 160);
gui_circle_set_glow(circle, glow, 12); /* 12 像素模糊半径 */
gui_circle_clear_glow(circle);
颜色的 alpha 即发光强度;blur_radius 单位为像素,钳到 1..32,传 0 等同
关闭。改颜色或强度只重绘,不重建掩膜。
掩膜按一条径向条块绕中心旋转四次存储,所以大小取决于半径和模糊半径, 而不是圆的面积。中心区域为空,完全不存储。
限制与圆角矩形相同:发光可以溢出父容器;本体滚出屏幕后留在屏内的发光, 要等该区域下一次重绘才会清掉。
渐变色填充
圆形控件支持径向渐变和角度渐变两种渐变色填充方式,可以创建丰富的视觉效果。

渐变类型
支持 2 种渐变类型:
CIRCLE_GRADIENT_RADIAL: 径向渐变(从圆心向外)
CIRCLE_GRADIENT_ANGULAR: 角度渐变(沿圆周方向)
渐变色工作原理
径向渐变:颜色从圆心向边缘线性插值
角度渐变:颜色沿圆周角度方向线性插值
支持最多 8 个颜色停止点(color stops)
颜色停止点的位置用 0.0 ~ 1.0 的归一化值表示
像素颜色通过在相邻颜色停止点之间进行线性插值计算得出
采用有序抖动(Ordered Dithering)算法消除 RGB565 格式的色阶问题
使用步骤
创建圆形控件
调用
gui_circle_set_radial_gradient()设置径向渐变,或调用gui_circle_set_angular_gradient()设置角度渐变调用
gui_circle_add_gradient_stop()添加颜色停止点(至少需要 2 个)可选:调用
gui_circle_clear_gradient()清除渐变设置
关键要点
径向渐变: 适合创建光晕、太阳等从中心向外发散的效果
角度渐变: 适合创建彩虹圆环、色轮等沿圆周变化的效果
无缝循环: 对于角度渐变,起始颜色和结束颜色应相同,以实现无缝的颜色循环
颜色插值: 支持 RGBA 颜色空间的线性插值,包括透明度通道
抗色阶: 针对 RGB565 显示屏优化,使用抖动算法消除色阶
性能优化: 对非渐变场景几乎无性能影响
特性亮点
高性能: 采用优化的圆形绘制算法,确保流畅的渲染性能
抗锯齿: 支持边缘抗锯齿,提供平滑的圆形边缘效果
灵活配置: 支持自定义半径、位置和颜色
透明度支持: 支持 RGBA 颜色格式,可创建半透明圆形效果
轻量级: 内存占用小,适合嵌入式系统和资源受限环境
动态更新: 支持运行时动态修改位置和样式
矩阵变换: 支持旋转、缩放、平移等矩阵变换操作,可创建椭圆和复杂变换效果
应用场景
圆形控件适用于以下场景:
状态指示器: 创建圆形状态指示灯
用户头像: 实现圆形用户头像显示
图标设计: 绘制各种圆形图标元素
进度指示: 创建圆形进度条或加载动画
按钮设计: 实现圆形交互按钮
装饰元素: 作为 UI 界面的装饰性圆形元素
数据可视化: 用于饼图、雷达图等数据可视化组件
椭圆绘制: 利用缩放变换创建椭圆形状
变换动画: 利用旋转、缩放、平移实现复杂的动画效果
配置说明
要使用圆形控件,需要在配置文件中启用相应的宏定义:
通过 menuconfig 启用 Kconfig 选项:
cd simulator/win32
menuconfig ../../Kconfig.gui
选择 Geometry CIRCLE Demo ( CONFIG_REALTEK_BUILD_REAL_LITE_CIRCLE ),保存到 simulator/win32/.config。
#define CONFIG_REALTEK_BUILD_REAL_LITE_CIRCLE 1
完整示例
#include "gui_components_init.h"
#include "gui_circle.h"
static void gui_circle_cb(gui_obj_t *obj)
{
gui_log("gui_circle_cb: %s\n", obj->name);
}
// Gradient circle examples
void example_circle_gradient(void *parent)
{
// Example 1: Radial gradient (center to edge, white to blue)
gui_circle_t *circle1 = gui_circle_create(parent, "circle_radial",
120, 120, 80,
gui_rgba(255, 255, 255, 255));
gui_circle_set_radial_gradient(circle1);
gui_circle_add_gradient_stop(circle1, 0.0f, gui_rgba(255, 255, 255, 255)); // White center
gui_circle_add_gradient_stop(circle1, 1.0f, gui_rgba(0, 0, 255, 255)); // Blue edge
// Example 2: Radial gradient with multiple colors (sun effect)
gui_circle_t *circle2 = gui_circle_create(parent, "circle_sun",
320, 120, 80,
gui_rgba(255, 255, 0, 255));
gui_circle_set_radial_gradient(circle2);
gui_circle_add_gradient_stop(circle2, 0.0f, gui_rgba(255, 255, 255, 255)); // White center
gui_circle_add_gradient_stop(circle2, 0.3f, gui_rgba(255, 255, 0, 255)); // Yellow
gui_circle_add_gradient_stop(circle2, 0.7f, gui_rgba(255, 128, 0, 255)); // Orange
gui_circle_add_gradient_stop(circle2, 1.0f, gui_rgba(255, 0, 0, 255)); // Red edge
// Example 3: Angular gradient (rainbow around circle)
gui_circle_t *circle3 = gui_circle_create(parent, "circle_angular",
120, 320, 80,
gui_rgba(255, 0, 0, 255));
gui_circle_set_angular_gradient(circle3, 0, 360);
gui_circle_add_gradient_stop(circle3, 0.00f, gui_rgba(255, 0, 0, 255)); // Red
gui_circle_add_gradient_stop(circle3, 0.17f, gui_rgba(255, 127, 0, 255)); // Orange
gui_circle_add_gradient_stop(circle3, 0.33f, gui_rgba(255, 255, 0, 255)); // Yellow
gui_circle_add_gradient_stop(circle3, 0.50f, gui_rgba(0, 255, 0, 255)); // Green
gui_circle_add_gradient_stop(circle3, 0.67f, gui_rgba(0, 0, 255, 255)); // Blue
gui_circle_add_gradient_stop(circle3, 0.83f, gui_rgba(75, 0, 130, 255)); // Indigo
gui_circle_add_gradient_stop(circle3, 1.00f, gui_rgba(255, 0, 0, 255)); // Red (seamless)
// Example 4: Radial gradient with transparency (glow effect)
gui_circle_t *circle4 = gui_circle_create(parent, "circle_glow",
320, 320, 80,
gui_rgba(0, 255, 0, 255));
gui_circle_set_radial_gradient(circle4);
gui_circle_add_gradient_stop(circle4, 0.0f, gui_rgba(0, 255, 0, 255)); // Opaque green
gui_circle_add_gradient_stop(circle4, 0.5f, gui_rgba(0, 255, 0, 180)); // Semi-transparent
gui_circle_add_gradient_stop(circle4, 1.0f, gui_rgba(0, 255, 0, 50)); // Nearly transparent
}
static int geometry_circle_demo_init(void)
{
const uint32_t W = 480, H = 480;
const uint32_t big_d = 368;
const uint32_t small_d = 66;
const uint32_t margin = 36;
gui_circle_t *big_circle = gui_circle_create(gui_obj_get_root(), "big_circle", W / 2,
H / 2, big_d / 2, gui_rgba(0, 255,
0, 255));
gui_circle_set_stroke(big_circle, 8.0f, gui_rgba(255, 255, 255, 255));
gui_circle_create(gui_obj_get_root(), "top_left", margin + small_d / 2, margin + small_d / 2,
small_d / 2,
gui_rgba(255, 0, 0, 255));
gui_circle_create(gui_obj_get_root(), "top_right", W - margin - small_d / 2,
margin + small_d / 2, small_d / 2,
gui_rgba(0, 255, 0, 255));
gui_circle_create(gui_obj_get_root(), "bottom_left", margin + small_d / 2,
H - margin - small_d / 2, small_d / 2,
gui_rgba(0, 0, 255, 255));
gui_circle_create(gui_obj_get_root(), "bottom_right", W - margin - small_d / 2,
H - margin - small_d / 2, small_d / 2,
gui_rgba(0, 0, 255, 150));
gui_obj_add_event_cb(big_circle, (gui_event_cb_t)gui_circle_cb, GUI_EVENT_TOUCH_CLICKED, NULL);
// Uncomment to show gradient examples
// example_circle_gradient(gui_obj_get_root());
return 0;
}
GUI_INIT_APP_EXPORT(geometry_circle_demo_init);
API
Defines
-
M_SQRT1_2 0.707106781186547524401f
1/sqrt(2)
Enums
Functions
-
gui_circle_t *gui_circle_create(void *parent, const char *name, int x, int y, int radius, gui_color_t color)
Create a circle widget.
- 参数:
parent -- Parent widget.
name -- Widget name.
x -- X coordinate of circle center.
y -- Y coordinate of circle center.
radius -- Circle radius.
color -- Circle color.
- 返回:
Pointer to the created circle widget.
-
void gui_circle_set_style(gui_circle_t *circle, int x, int y, int radius, gui_color_t color)
Set circle style.
- 参数:
circle -- Circle widget pointer.
x -- X coordinate of circle center.
y -- Y coordinate of circle center.
radius -- Circle radius.
color -- Circle color.
-
void gui_circle_set_position(gui_circle_t *circle, int x, int y)
Set circle position.
- 参数:
circle -- Circle widget pointer.
x -- X coordinate of circle center.
y -- Y coordinate of circle center.
-
void gui_circle_set_radius(gui_circle_t *circle, int radius)
Set circle radius.
- 参数:
circle -- Circle widget pointer.
radius -- Circle radius.
-
void gui_circle_set_opacity(gui_circle_t *circle, uint8_t opacity)
Set the opacity of the circle widget.
- 参数:
circle -- Pointer to the circle widget.
opacity -- Opacity value (0-255).
-
void gui_circle_set_color(gui_circle_t *circle, gui_color_t color)
Set circle color.
- 参数:
circle -- Circle widget pointer.
color -- Circle color.
-
void gui_circle_set_stroke(gui_circle_t *circle, float width, gui_color_t color)
Set an inset stroke for the circle.
- 参数:
circle -- Circle widget pointer.
width -- Stroke width in pixels. A non-positive value disables stroke.
color -- Stroke color.
-
void gui_circle_clear_stroke(gui_circle_t *circle)
Disable the circle stroke.
- 参数:
circle -- Circle widget pointer.
-
void gui_circle_set_glow(gui_circle_t *circle, gui_color_t color, uint8_t blur_radius)
Draw an outer glow around the circle.
The glow is a separate layer drawn under the body: the body's own fill and stroke are untouched, and changing the glow does not rebuild them.
Its colour's alpha is the strength, so a dimmer glow is a lower alpha rather than a different blur. Changing colour or strength repaints without rebuilding the mask; changing the radius or blur radius rebuilds it.
- 参数:
circle -- Circle widget pointer.
color -- Glow colour; alpha 0 switches the glow off.
blur_radius -- Blur radius in pixels, clamped to 1..32. 0 switches the glow off.
-
void gui_circle_clear_glow(gui_circle_t *circle)
Remove the circle's outer glow.
- 参数:
circle -- Circle widget pointer.
-
void gui_circle_on_click(gui_circle_t *circle, void *callback, void *parameter)
Set click callback for the circle.
- 参数:
circle -- Circle widget pointer.
callback -- Callback function.
parameter -- Callback parameter.
-
void gui_circle_rotate(gui_circle_t *circle, float degrees)
Apply rotation transformation to the circle widget.
- 参数:
circle -- Circle widget pointer.
degrees -- Rotation angle in degrees (clockwise).
-
void gui_circle_scale(gui_circle_t *circle, float scale_x, float scale_y)
Apply scale transformation to the circle widget.
- 参数:
circle -- Circle widget pointer.
scale_x -- Scale factor in X direction.
scale_y -- Scale factor in Y direction.
-
void gui_circle_translate(gui_circle_t *circle, float tx, float ty)
Apply translation transformation to the circle widget.
- 参数:
circle -- Circle widget pointer.
tx -- Translation in X direction (pixels).
ty -- Translation in Y direction (pixels).
-
void gui_circle_set_radial_gradient(gui_circle_t *circle)
Set radial gradient for circle widget (from center to edge).
- 参数:
circle -- Circle widget pointer.
-
void gui_circle_set_angular_gradient(gui_circle_t *circle, float start_angle, float end_angle)
Set angular gradient for circle widget (along circumference).
- 参数:
circle -- Circle widget pointer.
start_angle -- Start angle in degrees.
end_angle -- End angle in degrees.
-
void gui_circle_add_gradient_stop(gui_circle_t *circle, float position, gui_color_t color)
Add color stop to circle gradient.
- 参数:
circle -- Circle widget pointer.
position -- Position of color stop (0.0 to 1.0).
color -- Color at circle stop.
-
void gui_circle_clear_gradient(gui_circle_t *circle)
Clear gradient and use solid color.
- 参数:
circle -- Circle widget pointer.
-
struct gui_circle_t
Circle widget structure.
Public Members
-
gui_obj_t base
Base widget.
-
gui_geometry_parts_t parts
Non-overlapping pieces: the solid centre square and four strips drawn from one payload — or one image.
-
int x
Center X coordinate relative to widget.
-
int y
Center Y coordinate relative to widget.
-
int radius
Circle radius.
-
gui_color_t color
Circle color.
-
float stroke_width
Inset stroke width. Zero disables stroke.
-
gui_color_t stroke_color
Stroke color.
-
uint8_t opacity_value
Opacity value.
-
uint32_t checksum
Checksum for change detection.
-
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 circle fill.
-
bool use_gradient
Flag to enable gradient rendering.
-
gui_circle_gradient_type_t gradient_type
Gradient type.
-
gui_matrix_t last_matrix
-
gui_color_t glow_color
Glow colour; its alpha is the strength.
-
uint8_t glow_blur
Glow blur radius; 0 disables the glow.
-
struct gui_geometry_glow *glow
Glow state, allocated on first use.
-
gui_obj_t base
-
struct circle_desc_t
Identity of a cached circle payload.
Everything that changes a pixel goes in here and nothing else does; notably position stays out, since it only ever reaches the draw_img matrix. Gradient parts pass the whole struct, solid ones stop short of the gradient — see circle_desc_len().
Public Members
-
uint32_t part
gui_circle_part_t.
-
int32_t radius
Circle radius.
-
int32_t size_a
Payload width.
-
int32_t size_b
Payload height.
-
uint32_t color
ARGB baked into the pixels; alpha only when A8.
-
uint32_t is_a8
Non-zero when the payload is a coverage mask.
-
uint32_t gradient_type
CIRCLE_GRADIENT_*, or UINT32_MAX for none.
-
float stroke_width
Inset stroke width, 0 for none.
-
uint32_t stroke_color
ARGB stroke baked into the pixels; 0 for none.
-
Gradient gradient
Only present when gradient_type is set.
-
uint32_t part
-
struct circle_geom_t
Geometry shared by every piece of one circle, centred at (radius, radius).
The split is a solid centre square of side 2 * half, and around it four strips of band x (2 * half + band) laid out like a pinwheel.
halfis the largest value whose square still lies fully inside the fill, so the centre is one solid colour.