黑暗模式
6. 画布
本章导读:
AWTK提供了各种绘制图像的API接口,方便程序员绘制直线、矩形、椭圆等形状。也可以根据AWTK提供的API接口绘制自己想要的控件,例如饼图、柱状图等。AWTK提供了两种画布:普通和矢量图画布,通过调用这两种画布提供的画图接口,实现不同的绘图功能。
6.1 普通画布
6.1.1 简介
canvas类。普通画布可以实现一些简单的绘制功能,如:绘制水平或垂直直线、文本、图片、矩形等。如果需要绘制比较复杂一点的图形就需要使用矢量图画布,如:绘制椭圆、圆弧等。
6.1.2 函数
canvas提供的函数详见下表,具体的函数API请查看AWTK_API手册。
函数名称 | 说明 |
---|---|
canvas_begin_frame | 绘制开始 |
canvas_cast | 转换为canvas对象(供脚本语言使用) |
canvas_clear_rect | 用填充颜色填充指定矩形 |
canvas_draw_hline | 画水平线 |
canvas_draw_icon | 绘制图标 |
canvas_draw_image | 绘制图片 |
canvas_draw_image_at | 在指定位置画图 |
canvas_draw_image_ex | 绘制图片 |
canvas_draw_image_ex2 | 绘制图片 |
canvas_draw_line | 画直线 |
canvas_draw_points | 画多个点 |
canvas_draw_text | 绘制文本 |
canvas_draw_text_bidi_in_rect | 绘制文本 |
canvas_draw_text_in_rect | 绘制文本 |
canvas_draw_utf8 | 绘制文本 |
canvas_draw_utf8_in_rect | 绘制文本 |
canvas_draw_vline | 画垂直线 |
canvas_end_frame | 绘制结束 |
canvas_fill_rect | 绘制矩形 |
canvas_fill_rect_gradient | 绘制矩形 |
canvas_fill_rounded_rect | 填充区域 |
canvas_fill_rounded_rect_ex | 填充圆角矩形区域 |
canvas_fill_rounded_rect_gradient | 填充圆角矩形区域 |
canvas_fill_rounded_rect_gradient_ex | 填充圆角矩形区域 |
canvas_get_clip_rect | 获取裁剪区 |
canvas_get_font_height | 获取字体的高度 |
canvas_get_height | 获取画布的高度 |
canvas_get_text_metrics | 获取当前字体的度量信息 |
canvas_get_vgcanvas | 获取vgcanvas对象 |
canvas_get_width | 获取画布的宽度 |
canvas_init | 初始化,系统内部调用 |
canvas_measure_text | 计算文本所占的宽度 |
canvas_measure_utf8 | 计算文本所占的宽度 |
canvas_reset | 释放相关资源 |
canvas_set_assets_manager | 设置canvas的assets_manager对象 |
canvas_set_clip_rect | 设置裁剪区 |
canvas_set_clip_rect_ex | 设置裁剪区 |
canvas_set_fill_color | 设置填充颜色 |
canvas_set_fill_color_str | 设置填充颜色 |
canvas_set_font | 设置字体 |
canvas_set_font_manager | 设置canvas的font_manager对象 |
canvas_set_fps | 设置FPS |
canvas_set_global_alpha | 设置全局alpha值 |
canvas_set_stroke_color | 设置线条颜色 |
canvas_set_stroke_color_str | 设置线条颜色 |
canvas_set_text_align | 设置文本对齐方式 |
canvas_set_text_color | 设置文本颜色 |
canvas_set_text_color_str | 设置文本颜色 |
canvas_stroke_rect | 绘制矩形 |
canvas_stroke_rounded_rect | 绘制边框 |
canvas_stroke_rounded_rect_ex | 绘制边框 |
canvas_translate | 平移原点坐标 |
canvas_untranslate | 反向平移原点坐标 |
6.1.3 属性
canvas还提供了下面属性,详见下表:
属性名称 | 类型 | 说明 |
---|---|---|
assets_manager | assets_manager_t* | 资源管理器对象 |
clip_bottom | xy_t | 当前裁剪矩形的底部位置 |
clip_left | xy_t | 当前裁剪矩形的左边位置 |
clip_right | xy_t | 当前裁剪矩形的右边位置 |
clip_top | xy_t | 当前裁剪矩形的顶部位置 |
font | font_t* | 字体对象 |
font_manager | font_manager_t* | 字体管理器对象 |
font_name | char* | 当前字体名称 |
font_size | uint16_t | 当前字体大小 |
fps | uint32_t | 当前的帧率 |
global_alpha | uint8_t | 当前全局alpha |
lcd | lcd_t* | lcd对象 |
ox | xy_t | x坐标偏移 |
oy | xy_t | y坐标偏移 |
show_fps | bool_t | 是否显示帧率 |
text_align_h | align_h_t | 文本水平对齐方式 |
text_align_v | align_v_t | 文本垂直对齐方式 |
6.1.4 示例
canvas的用法与vgcanvas的类似,请参考下文6.2.4章节。
6.2 矢量图画布
6.2.1 简介
vgcanvas_t矢量图画布抽象基类。与canvas相比vgcanvas的效率要低一些,但功能也丰富些。绘制一些简单的图形,如线条、矩形等可以用canvas;复杂一点图形,如圆角矩形就用vgcanvas。
具体实现时,vgcanvas内部调用了nanovg、cairo的功能进行绘图。目前只提供了基于nanovg的实现,支持软件渲染和硬件渲染。AWTK对nanovg进行了一些改进:
- 可以用agg/agge实现软件渲染(暂时不支持文本绘制)
- 可以用bgfx使用DirectX(Windows平台)、Metal(iOS平台)和使用OpenGL,Vulkan(Linux平台)硬件加速
6.2.2 函数
vgcanvas提供的函数详见下表,具体的函数API请查看AWTK_API手册。
函数名称 | 说明 |
---|---|
vgcanvas_arc | 生成一条圆弧 |
vgcanvas_arc_to | 生成一条圆弧路径到指定点 |
vgcanvas_begin_frame | 开始绘制,系统内部调用 |
vgcanvas_begin_path | 清除之前的路径,并重新开始一条路径 |
vgcanvas_bezier_to | 生成一条三次贝塞尔曲线 |
vgcanvas_bind_fbo | 绑定 fbo 对象 |
vgcanvas_cast | 转换为vgcanvas对象(供脚本语言使用) |
vgcanvas_clear_cache | 释放vgcanvas对象的缓冲数据 |
vgcanvas_clear_rect | 用颜色清除指定矩形区域 |
vgcanvas_clip_path | 使用当前的path裁剪 |
vgcanvas_clip_rect | 矩形裁剪 |
vgcanvas_close_path | 闭合路径 |
vgcanvas_create | 创建vgcanvas |
vgcanvas_create_fbo | 创建 fbo 对象 |
vgcanvas_destroy | 销毁vgcanvas对象 |
vgcanvas_destroy_fbo | 销毁 fbo 对象 |
vgcanvas_draw_icon | 绘制图标 |
vgcanvas_draw_image | 绘制图片 |
vgcanvas_ellipse | 生成一个椭圆路径 |
vgcanvas_end_frame | 结束绘制系统内部调用 |
vgcanvas_fbo_to_bitmap | 把 fbo 对象的数据拷贝到 bitmap 中 |
vgcanvas_fill | 填充多边形 |
vgcanvas_fill_text | 绘制文本 |
vgcanvas_flush | flush |
vgcanvas_get_height | 获取高度 |
vgcanvas_get_text_metrics | 获取当前字体的度量信息 |
vgcanvas_get_width | 获取宽度 |
vgcanvas_intersect_clip_rect | 设置一个与前一个裁剪区做交集的矩形裁剪区 |
vgcanvas_is_point_in_path | 检查点是否在当前路径中 |
vgcanvas_line_to | 生成一条线段(从当前点到目标点) |
vgcanvas_measure_text | 测量文本的宽度 |
vgcanvas_move_to | 移动当前点到指定点 |
vgcanvas_paint | 用图片填充/画多边形(可能存在可移植性问题,除非必要请勿使用) |
vgcanvas_path_winding | 设置路径填充实心与否 |
vgcanvas_quad_to | 生成一条二次贝塞尔曲线 |
vgcanvas_rect | 生成一个矩形路径 |
vgcanvas_reinit | 重新初始化,系统内部调用 |
vgcanvas_reset | 重置所有状态 |
vgcanvas_reset_curr_state | 重置当前状态 |
vgcanvas_restore | 恢复上次save的状态 |
vgcanvas_rotate | 旋转 |
vgcanvas_rounded_rect | 生成一个圆角矩形路径 |
vgcanvas_save | 保存当前的状态如颜色和矩阵等信息 |
vgcanvas_scale | 缩放 |
vgcanvas_set_antialias | 设置是否启用反走样 |
vgcanvas_set_fill_color | 设置填充颜色 |
vgcanvas_set_fill_color_str | 设置填充颜色 |
vgcanvas_set_fill_gradient | 设置填充颜色为渐变色 |
vgcanvas_set_fill_linear_gradient | 设置填充颜色为线性渐变色 |
vgcanvas_set_fill_radial_gradient | 设置填充颜色为径向渐变色 |
vgcanvas_set_font | 设置字体的名称 |
vgcanvas_set_font_size | 设置字体的大小 |
vgcanvas_set_global_alpha | 设置全局透明度 |
vgcanvas_set_line_cap | 设置line cap |
vgcanvas_set_line_join | 设置line join |
vgcanvas_set_line_width | 设置线条的宽度 |
vgcanvas_set_miter_limit | 设置miter limit |
vgcanvas_set_stroke_color | 设置线条颜色 |
vgcanvas_set_stroke_color_str | 设置线条颜色 |
vgcanvas_set_stroke_gradient | 设置线条颜色为渐变色 |
vgcanvas_set_stroke_linear_gradient | 设置线条颜色为线性渐变色 |
vgcanvas_set_stroke_radial_gradient | 设置线条颜色为径向渐变色 |
vgcanvas_set_text_align | 设置文本水平对齐的方式 |
vgcanvas_set_text_baseline | 设置文本垂直对齐的方式 |
vgcanvas_set_transform | 设置变换矩阵 |
vgcanvas_stroke | 画线 |
vgcanvas_transform | 变换矩阵 |
vgcanvas_translate | 平移 |
vgcanvas_unbind_fbo | 解开绑定 fbo 对象 |
6.2.3 属性
vgcanvas还提供了下面属性,详见下表:
属性名称 | 类型 | 说明 |
---|---|---|
anti_alias | bool_t | 是否启用反走样功能 |
fill_color | color_t | 填充颜色 |
font | char* | 字体 |
font_size | float_t | 字体大小 |
global_alpha | float_t | 全局alpha |
h | wh_t | canvas的高度 |
line_cap | const char* | line_cap |
line_join | const char* | line_join |
line_width | float_t | 线宽 |
miter_limit | float_t | miter_limit |
ratio | float_t | 显示比例 |
stride | uint32_t | 一行占的字节 |
stroke_color | color_t | 线条颜色 |
text_align | const char* | 文本对齐方式 |
text_baseline | const char* | 文本基线 |
w | wh_t | canvas的宽度 |
6.2.4 示例
例如:要实现下图所示的效果,步骤如下:
步骤一:创建canvas_widget控件,并为该控件注册EVT_PAINT绘制事件的回调函数on_paint_vg。
步骤二:在on_paint_vg回调函数中调用canvas或者vgcanvas画布接口提供的函数进行重绘。
具体代码如下:
c
/* awtk/demos/demo_vg_app.c */
static ret_t on_paint_vg(void* ctx, event_t* e) {
paint_event_t* evt = (paint_event_t*)e;
canvas_t* c = evt->c;
vgcanvas_t* vg = canvas_get_vgcanvas(c);
vgcanvas_save(vg);
vgcanvas_set_line_width(vg, 1);
vgcanvas_set_stroke_color(vg, color_init(0, 0xff, 0, 0xff));
vgcanvas_set_fill_color(vg, color_init(0xff, 0, 0, 0xff));
...
return RET_OK;
}
ret_t application_init() {
widget_t* win = window_create(NULL, 0, 0, 0, 0);
widget_t* canvas = canvas_widget_create(win, 0, 0, win->w, win->h);
widget_on(canvas, EVT_PAINT, on_paint_vg, NULL);
timer_add(on_timer, win, 500);
return RET_OK;
}
完整示例请参考 demo_vg_app.c。
6.3 离线画布
6.3.1 简介
1. 在线画布
通常可以调用canvas或者vgcanvas画布接口提供的函数,将要绘制的内容显示到屏幕上,称这种方式为在线画布,并且可以通过下面几种方式实现:
(1)方式一:创建canvas_widget控件,并为该控件注册EVT_PAINT绘制事件的回调函数,在该回调函数中调用canvas或者vgcanvas画布接口提供的函数进行绘图。
完整示例请参考 demo_vg_app.c。
(2)方式二:在控件中的on_paint_self自绘函数中,调用canvas或者vgcanvas画布接口提供的函数进行绘图。
完整示例请参考 guage.c。
2. 离线画布
将canvas绘制到内存bitmap对象中,然后可以对bitmap对象做进一步处理,比如将bitmap对象保存到文件中,实现截图效果,称这种方式为离线画布。
为了解决用户离线画布的需求,在AWTK中提供了canvas_offline类供用户使用。
6.3.2 函数
canvas_offline类提供了下表中的函数,具体的函数API请查看AWTK_API手册。
函数名称 | 说明 |
---|---|
canvas_offline_begin_draw | 设置离线 canvas 开始绘图 |
canvas_offline_bitmap_move_to_new_bitmap | 把离线 canvas 的离线 bitmap 移动赋值给新的 bitmap |
canvas_offline_clear_canvas | 清除离线 canvas 所有数据,并把背景设置为全透明 |
canvas_offline_create | 创建一个离线的 canvas |
canvas_offline_custom_begin_draw | 用户自定义 canvas_offline_custom_begin_draw |
canvas_offline_custom_bitmap_move_to_new_bitmap | 用户自定义 canvas_offline_custom_bitmap_move_to_new_bitmap |
canvas_offline_custom_clear_canvas | 用户自定义 canvas_offline_custom_clear_canvas |
canvas_offline_custom_create | 用户自定义 canvas_offline_create |
canvas_offline_custom_destroy | 用户自定义 canvas_offline_custom_destroy |
canvas_offline_custom_end_draw | 用户自定义 canvas_offline_custom_end_draw |
canvas_offline_custom_flush_bitmap | 用户自定义 canvas_offline_custom_flush_bitmap |
canvas_offline_custom_get_bitmap | 用户自定义 canvas_offline_custom_get_bitmap |
canvas_offline_destroy | 释放离线 canvas 和离线 bitmap |
canvas_offline_end_draw | 设置离线 canvas 结束绘图 |
canvas_offline_flush_bitmap | 把离线 canvas 的数据放到绑定的 bitmap 中 |
canvas_offline_get_bitmap | 获取离线 canvas 的离线 bitmap |
6.3.3 属性
canvas_offline还提供了下面属性,详见下表:
属性名称 | 类型 | 说明 |
---|---|---|
bitmap | bitmap_t* | 绑定的离线 bitmap |
6.3.4 示例
例如,使用离线画布完成一个截屏的功能,其步骤如下:
步骤一:创建离线画布。调用canvas_offline_create函数创建离线画布,在离线画布内置了一个离线的bitmap位图,提供给用户使用。创建离线画布,代码如下:
c
canvas_t* canvas_offline = canvas_offline = canvas_offline_create(320, 480, BITMAP_FMT_RGBA8888);
在OpenGL模式下离线画布canvas格式只能为RGBA8888;在AGGE模式下可以为:RGBA8888、BGRA8888、RGB565和BGR5656。(其他的格式暂时不支持)
步骤二:绘图。离线画布的绘图过程和平时使用canvas或者vgcanvas绘图是一样的,只不过在绘制之前需要先调用canvas_offline_begin_draw函数开始绘图,并在绘制结束的时候调用canvas_offline_end_draw函数结束绘图。例如,把整个窗口绘制到离线画布上,代码如下:
c
bitmap_t* offline_bitmap = NULL;
canvas_offline_begin_draw(canvas_offline); /* 开始离线 canvas 绘图 */
widget_paint(window_manager(), canvas_offline); /* 把整个窗口绘制到离线的 canvas 中 */
canvas_offline_end_draw(canvas_offline); /* 结束离线 canvas 绘图 */
/* 由于需要把 bitmap 保存为 png 文件,所以需要把显存中的数据回传到内存中 */
canvas_offline_flush_bitmap(canvas_offline);
offline_bitmap = canvas_offline_get_bitmap(canvas_offline); /* 获取离线 bitmap */
bitmap_save_png(offline_bitmap, "test.png"); /* 把 bitmap 保存为 png 文件 */
步骤三:释放离线画布和绑定的离线 bitmap,代码如下:
c
canvas_offline_destroy(canvas_offline);
完整示例请参考 demo_canvas_offline.c。