mirror of
https://github.com/zlgopen/awtk.git
synced 2025-05-08 19:44:45 +08:00
improve docs
This commit is contained in:
parent
f155b93b14
commit
4b277c13b1
@ -1,8 +1,45 @@
|
||||
# 利用 app_helper 编写 SConstruct
|
||||
|
||||
编写 SConstruct 是一件繁琐的事情。我们把一些公共的功能,提取到 app\_helper 中,让 SConstruct 稍微简化一点:
|
||||
AWTK 项目中有 SConstruct 文件,该文件是 Scons 的编译脚本。当开发者需要在程序中使用依赖库或者进行自定义预处理时,需要遵循 Python 语法编写 SConstruct 文件,这是一件繁琐的事情。
|
||||
|
||||
## 一、示例
|
||||
为简化 SConstruct 的编写,AWTK 把一些公共功能提取到 awtk/scripts/app_helper_base.py 中,并且在项目目录下的 scripts/app_helper.py 中导入 app_helper_base.py,让开发者可直接在项目的 SConstruct 文件中调用这些函数。
|
||||
|
||||
## 1 相关函数
|
||||
|
||||
app_helper.py 提供了下表中的函数,具体用法请参考 awtk/docs/app_helper_usage.md。
|
||||
|
||||
| 函数名称 | 说明 |
|
||||
| ---------------------- | ---------------------------------- |
|
||||
| add_deps | 增加依赖的第三方库 |
|
||||
| add_libs | 增加依赖的库 |
|
||||
| set_dll_def | 设置动态库的 def 文件名 |
|
||||
| add_cpppath | 增加头文件搜索路径 |
|
||||
| add_libpath | 增加库的搜索路径 |
|
||||
| add_cxxflags | 增加C++预处理参数 |
|
||||
| add_ccflags | 增加C 预处理参数 |
|
||||
| add_linkflags | 增加链接参数 |
|
||||
| add_platform_libs | 增加特定平台的需要的库 |
|
||||
| add_platform_cpppath | 增加特定平台的需要的头文件搜索路径 |
|
||||
| add_platform_libpath | 增加特定平台的需要的库搜索路径 |
|
||||
| add_platform_ccflags | 增加特定平台的需要的C 预处理参数 |
|
||||
| add_platform_cxxflags | 增加特定平台的需要的C++预处理参数 |
|
||||
| add_platform_linkflags | 增加特定平台的需要的链接参数 |
|
||||
|
||||
> 上表中的函数实现在 awtk/scripts/app_helper_base.py 中。
|
||||
|
||||
## 2 示例
|
||||
|
||||
使用 app_helper.py 首先需要在SConstruct中导入它,然后调用 Helper 函数得到helper对象,最后使用 helper 对象调用上一节的函数。
|
||||
|
||||
例如,在项目中使用 SQLite 软件库(SQL数据库引擎),静态链接库以及头文件的目录结构如下:
|
||||
|
||||
```bash
|
||||
项目目录/
|
||||
|-- 3rd/sqlite3/sqlite3.h
|
||||
|-- lib/sqlite3.lib
|
||||
```
|
||||
|
||||
在项目目录下的 SConstruct 文件中调用 add_libs() 函数增加 sqlite3.lib 依赖库,并且调用 add_cpppath() 函数增加该依赖库头文件的搜索路径,代码如下:
|
||||
|
||||
```python
|
||||
import os
|
||||
@ -11,95 +48,53 @@ import scripts.app_helper as app
|
||||
helper = app.Helper(ARGUMENTS);
|
||||
helper.add_libs(['sqlite3']).add_cpppath([os.path.join(helper.APP_ROOT, '3rd')]).call(DefaultEnvironment)
|
||||
|
||||
helper.SConscript(['src/SConscript', '3rd/sqlite3/SConscript'])
|
||||
SConscript(['src/SConscript', '3rd/sqlite3/SConscript'])
|
||||
```
|
||||
|
||||
## 二、helper API 介绍
|
||||
需要注意的是:
|
||||
|
||||
* use\_std\_cxx 指定 C++ 编译器的版本。
|
||||
1. 本示例中将静态链接库 sqlite3.lib 放在项目目录的 lib 文件夹下,AWTK 默认将该路径添加到库的搜索路径中。如果开发者将静态链接库放在其他路径,则还需要调用 add_libpath() 函数将该路径添加到库的搜索路径中。
|
||||
2. helper 支持链式调用,call 函数需要放到最后。
|
||||
|
||||
```
|
||||
helper.use_std_cxx(17)
|
||||
## 3 特殊函数
|
||||
|
||||
调用 app_helper.py 提供的函数,通常只需要传入文件或目录对应的路径,但有个别函数的还需要传入其他参数,包括 add_deps 和 add_platform_ 开头的所有函数,下面举例说明。
|
||||
|
||||
(1)add_deps() 函数原型如下:
|
||||
|
||||
```python
|
||||
def add_deps(self, DEPENDS_LIBS):
|
||||
```
|
||||
|
||||
* add\_deps 增加依赖的第三方库
|
||||
调用 add_deps() 函数增加依赖的第三方库,代码如下:
|
||||
|
||||
```python
|
||||
DEPENDS_LIBS = [
|
||||
{
|
||||
"root" : '../awtk-restful-httpd',
|
||||
'shared_libs': ['httpd'],
|
||||
'static_libs': []
|
||||
}
|
||||
{
|
||||
"root" : '../awtk-restful-httpd',
|
||||
'shared_libs': ['httpd'],
|
||||
'static_libs': []
|
||||
}
|
||||
]
|
||||
helper.add_deps(DEPENDS_LIBS)
|
||||
```
|
||||
|
||||
* add\_libs 增加依赖的库。
|
||||
"root"为第三方库的路径,支持相对路径和绝对路径;"shared_libs"为动态链接库;"static_libs"为静态链接库。
|
||||
|
||||
```
|
||||
helper.add_libs(['sqlite3'])
|
||||
(2)add_platform_libs() 函数原型如下:
|
||||
|
||||
```python
|
||||
def add_platform_libs(self, plat, PLATFORM_LIBS)
|
||||
```
|
||||
|
||||
* set\_dll\_def 设置动态库的 def 文件名。
|
||||
调用 add_platform_libs() 函数增加 Windows 平台下的 ws2_32.lib 库,代码如下:
|
||||
|
||||
```
|
||||
helper.set_dll_def('src/table_view.def')
|
||||
```
|
||||
|
||||
* add\_cpppath 增加头文件搜索路径。
|
||||
|
||||
```
|
||||
helper.add_cpppath([os.path.join(helper.APP_ROOT, '3rd')])
|
||||
```
|
||||
|
||||
* add\_libpath 增加库的搜索路径。
|
||||
|
||||
* add\_cxxflags 增加 C++预处理参数。
|
||||
|
||||
* add\_ccflags 增加 C 预处理参数。
|
||||
|
||||
* add\_linkflags 增加链接参数。
|
||||
|
||||
* add\_platform\_libs 增加特定平台的需要的库。
|
||||
|
||||
```
|
||||
```python
|
||||
helper.add_platform_libs('Windows', ['ws2_32'])
|
||||
```
|
||||
|
||||
* add\_platform\_cpppath 增加特定平台的需要的头文件搜索路径。
|
||||
plat参数为特定平台,取值如下:Windows、Linux 和 Darwin,分别表示 Windows 平台、Linux 平台和 macOS 平台。PLATFORM_LIBS 参数为库的名称。其他 add_platform_ 开头的函数用法也类似。
|
||||
|
||||
* add\_platform\_libpath 增加特定平台的需要的库搜索路径。
|
||||
|
||||
* add\_platform\_ccflags 增加特定平台的需要的 C 预处理参数。
|
||||
|
||||
* add\_platform\_cxxflags 增加特定平台的需要的 C++预处理参数。
|
||||
|
||||
* add\_platform\_linkflags 增加特定平台的需要的链接参数。
|
||||
|
||||
> 所有路径均为列表(数组)格式。
|
||||
|
||||
## 三、注意事项
|
||||
|
||||
* 平台相关的函数,plat 的取值:
|
||||
|
||||
* Windows 表示 Windows
|
||||
* Linux 表示 Linux
|
||||
* Darwin 表示 MacOS
|
||||
|
||||
* helper 支持链式调用,call 函数需要放到最后。
|
||||
|
||||
```
|
||||
helper.add_libs(['sqlite3']).add_cpppath([os.path.join(helper.APP_ROOT, '3rd')]).call(DefaultEnvironment)
|
||||
```
|
||||
|
||||
## 四、参考
|
||||
|
||||
* [如何引用第三方库](how_to_use_3rd_libs.md)
|
||||
* [编写跨平台的代码](cross_platform_programming.md)
|
||||
|
||||
* https://github.com/zlgopen/awtk-hello/blob/master/SConstruct
|
||||
|
||||
* https://github.com/zlgopen/awtk-mvvm-c-hello/blob/master/SConstruct
|
||||
|
||||
* https://github.com/zlgopen/awtk-widget-table-view/blob/master/SConstruct
|
||||
> 1. [awtk-hello](https://github.com/zlgopen/awtk-hello/blob/master/SConstruct)
|
||||
> 2. [awtk-mvvm-c-hello](https://github.com/zlgopen/awtk-mvvm-c-hello/blob/master/SConstruct)
|
||||
> 3. [awtk-widget-table-view](https://github.com/zlgopen/awtk-widget-table-view/blob/master/SConstruct)
|
||||
|
29
docs/awtk_font.md
Normal file
29
docs/awtk_font.md
Normal file
@ -0,0 +1,29 @@
|
||||
# AWTK 中支持的字体
|
||||
|
||||
AWTK 支持显示以下两种字体:
|
||||
|
||||
1. 矢量字库,通常为 .ttf、.otf 格式的文件,AWTK 默认采用 stb 库将矢量字库解析为字模(位图)。
|
||||
2. 点阵字,即已经解析好的位图字体。
|
||||
|
||||
它们的优缺点如下:
|
||||
|
||||
| 类型 | 优点 | 缺点 |
|
||||
| -------- | ---------------------------------------------------------- | -------------------------------------------------------------------------- |
|
||||
| 矢量字库 | 管理方便,占用的 flash 空间小 | 整个字库文件都需要加载到内存中,且需要消耗性能解码,同时解码时存在内存峰值 |
|
||||
| 点阵字 | 可裁剪掉 AWTK 中的字体解码模块,显示时无需解码,加载速度快 | 由于提前解码好,所以非常占用 flash 空间 |
|
||||
|
||||
## 1 使用 AWTK 中的工具裁剪字体
|
||||
|
||||
如果需要对矢量字库进行裁剪或者生成点阵字,可以使用 AWTK 内置的字体工具,使用方法可以查看 [font_gen](https://github.com/zlgopen/awtk/tree/master/tools/font_gen)。
|
||||
|
||||
## 2 使用 AWTK Designer 裁剪字体
|
||||
|
||||
使用 AWTK Designer 创建项目后,字体文件一般存储项目目录的 `design/default/fonts` 中,其中包含以下目录或文件:
|
||||
|
||||
| 目录/文件 | 作用 |
|
||||
| ----------- | ------------------------------------ |
|
||||
| config | 存放裁剪字体文件的配置 |
|
||||
| origin | 存放被裁剪前的原始字体文件 |
|
||||
| default.ttf | 项目当前使用的被裁剪后的缺省矢量字库 |
|
||||
|
||||
使用 AWTK Designer 可以裁剪字体文件与生成点阵字文件,详情请参阅 [awtk文档](https://awtk.zlg.cn/docs) 中 "FAQ常见问题" 里的 "AWTK Designer" 章节。
|
@ -1,5 +1,8 @@
|
||||
# 最新动态
|
||||
|
||||
2022/11/29
|
||||
* 完善文档(感谢泽武提供补丁)
|
||||
|
||||
2022/11/28
|
||||
* demoui 1M资源版去除部分资源,让其维持在1M以内(感谢兆坤提供补丁)。
|
||||
* 修改demoui 1M资源版界面(感谢兆坤提供补丁)。
|
||||
|
@ -2,18 +2,29 @@
|
||||
|
||||
在有的应用程序中,按键和触屏时,需要给用户提供某种反馈:
|
||||
|
||||
* 反馈的方式通常是声音或震动。
|
||||
- 反馈的方式通常是声音或震动。
|
||||
- 声音的类型可能与当前的按键有关。比如拨号界面,按下不同的数字会播放不同的声音。
|
||||
- 在同一个应用,不同场景的需求也可能不一样,所以需要全局开启或关闭反馈。
|
||||
|
||||
* 声音的类型可能与当前的按键有关。比如拨号界面,按下不同的数字会播放不同的声音。
|
||||
由于 AWTK 本身没有提供震动和声音的接口,所以 AWTK 提供了一个 ui_feedback 接口,开发者可以设置回调函数,去播放声音或震动。
|
||||
|
||||
* 在同一个应用,不同场景的需求也可能不一样,所以需要全局开启或关闭反馈。
|
||||
## 1 反馈回调函数
|
||||
|
||||
由于AWTK 本身没有提供震动和声音的接口,所以 AWTK 提供了一个 ui_feedback 接口,开发者可以设置回调函数,去播放声音或震动。
|
||||
反馈回调函数的原型和初始化函数如下:
|
||||
|
||||
回调函数的原型和初始化函数如下:
|
||||
|
||||
```
|
||||
```c
|
||||
/**
|
||||
* @method ui_on_feedback_t
|
||||
* 反馈回调函数。
|
||||
*
|
||||
* @param {void*} ctx 回调函数的上下文,即ui_feedback_init中传递的ctx。
|
||||
* @param {widget_t*} widget 设置feedback属性的控件对象。
|
||||
* @param {event_t*} evt 事件对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
typedef ret_t (*ui_on_feedback_t)(void* ctx, widget_t* widget, event_t* evt);
|
||||
|
||||
/**
|
||||
* @method ui_feedback_init
|
||||
* 初始化。
|
||||
@ -28,7 +39,50 @@ typedef ret_t (*ui_on_feedback_t)(void* ctx, widget_t* widget, event_t* evt);
|
||||
ret_t ui_feedback_init(ui_on_feedback_t on_feedback, void* ctx);
|
||||
```
|
||||
|
||||
通常只是部分控件需要提供反馈,因此控件缺省情况下不提供反馈功能。需要把控件的feedback属性设置为TRUE,当有按键(按下和弹起)和触屏事件(按下和弹起)发生在该控件上时,才会调用开发者设置的回调函数。
|
||||
通常只是部分控件需要提供反馈,因此控件缺省情况下不提供反馈功能。需要把控件的 feedback 属性设置为 TRUE,当有按键(按下和弹起)和触屏事件(按下和弹起)发生在该控件上时,才会调用开发者设置的回调函数。
|
||||
|
||||
在回调函数中,开发者可以根据事件的类型、当前设置和控件的其它属性,来决定如何反馈。
|
||||
|
||||
## 2 示例
|
||||
|
||||
由于 AWTK 没有提供震动和播放声音的接口,所以这里通过修改文本的方式展现该功能,要实现上面的功能点很简单,其步骤如下:
|
||||
|
||||
(1) 在 UI 文件中设置控件的"feedback"属性为 true,在这里需要设置"button"按钮的 feedback="true",代码如下:
|
||||
|
||||
```xml
|
||||
<window>
|
||||
<button name="button" x="60%" y="60%" w="20%" h="40" text="inc" feedback="true"/>
|
||||
<label name="label" x="c" y="60%" w="20%" h="40" text=""/>
|
||||
</window>
|
||||
```
|
||||
|
||||
(2) 在C代码中调用 ui_feedback_init 接口初始化,代码如下:
|
||||
|
||||
```c
|
||||
static ret_t ui_on_btn_feedback(void* ctx, widget_t* widget, event_t* evt) {
|
||||
widget_t* win = (widget_t*)ctx;
|
||||
widget_t* label = widget_lookup(win, "label", TRUE);
|
||||
const char* name = widget_get_prop_str(widget, WIDGET_PROP_NAME, "");
|
||||
|
||||
if (tk_str_eq(name, "button")) {
|
||||
if (evt->type == EVT_POINTER_DOWN) {
|
||||
widget_set_text_utf8(label, "point down");
|
||||
} else if (evt->type == EVT_POINTER_UP) {
|
||||
widget_set_text_utf8(label, "point up");
|
||||
}
|
||||
}
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
/* 初始化 */
|
||||
ret_t home_page_init(widget_t* win, void* ctx) {
|
||||
(void)ctx;
|
||||
return_value_if_fail(win != NULL, RET_BAD_PARAMS);
|
||||
|
||||
widget_foreach(win, visit_init_child, win);
|
||||
ui_feedback_init(ui_on_btn_feedback, win);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -1,10 +1,28 @@
|
||||
# 如何启用鼠标指针
|
||||
|
||||
## 1. 启用鼠标指针
|
||||
## 1 启用鼠标指针
|
||||
|
||||
启用鼠标指针,需要定义宏 ENABLE\_CURSOR。
|
||||
|
||||
## 2. 控件的缺省鼠标指针
|
||||
## 2 在应用程序启用鼠标指针
|
||||
|
||||
如果要在自己的应用程序中启用鼠标指针,可以按下面步骤:
|
||||
|
||||
(1) 添加鼠标指针图片,如"cursor.png",将其放到类似design/default/images/xx的目录下。
|
||||
|
||||
(2) 调用 window_manager_set_cursor 设置鼠标指针,如:
|
||||
|
||||
```c
|
||||
window_manager_set_cursor(window_manager(), "cursor");
|
||||
```
|
||||
|
||||
> 上面函数中的"cursor",对应鼠标图片的名称,两者名称需要一致
|
||||
|
||||
## 3 指针图片的要求
|
||||
|
||||
指针的形状有多种,比如普通指针、十字、文本选择和等待等等。为了简化处理,在绘制指针时,AWTK会把图片的中心定位到鼠标的当前位置,在制作指针图片时,请考虑这一点。
|
||||
|
||||
## 4 控件的缺省鼠标指针
|
||||
|
||||
控件的缺省鼠标指针由 vtable 的 pointer_cursor 属性指定。如 edit 的鼠标指针:
|
||||
|
||||
@ -29,24 +47,23 @@ TK_DECL_VTABLE(edit) = {.size = sizeof(edit_t),
|
||||
|
||||
> 控件的缺省鼠标指针在 AWTK 内部写定了,开发者可以换图片来改变鼠标指针的形状。
|
||||
|
||||
## 3. 为单个控件指定鼠标指针。
|
||||
## 5 为单个控件指定鼠标指针。
|
||||
|
||||
为单个控件指定鼠标指针,只需要指定控件的 pointer_cursor 属性即可。如:
|
||||
|
||||
```xml
|
||||
<label x="0" y="0" w="100%" h="100%" text="up/down key change focus" pointer_cursor="cursor_hand"/>
|
||||
```
|
||||
|
||||
```
|
||||
|
||||
## 4. 等待状态的鼠标指针
|
||||
|
||||
## 6 等待状态的鼠标指针
|
||||
|
||||
下列两个函数用于开始和结束等待鼠标指针。
|
||||
|
||||
开始等待鼠标指针后:
|
||||
|
||||
* 如果 ignore\_user\_input 为 TRUE,窗口忽略所有输入事件。
|
||||
|
||||
* 鼠标移动时不再自动切换鼠标指针。
|
||||
- 如果 ignore\_user\_input 为 TRUE,窗口忽略所有输入事件。
|
||||
- 鼠标移动时不再自动切换鼠标指针。
|
||||
|
||||
```c
|
||||
/**
|
||||
|
183
docs/how_to_load_external_image_and_font.md
Normal file
183
docs/how_to_load_external_image_and_font.md
Normal file
@ -0,0 +1,183 @@
|
||||
# 如何加载外部图片和字库
|
||||
|
||||
在嵌入式平台下,有些开发板的 Flash 空间比较紧张,运行 AWTK 应用程序的时候,可能会出现 Flash 不够用的情况。此时可以将占用空间比较大的图片和字体资源,放到其他存储介质上(如:SD卡)。
|
||||
|
||||
在 AWTK 中,存放图片或者字体都有默认的目录结构,如:图片存放在 default/images/xx 目录下,字体存放在 default/fonts 目录下。如果需要加载其他目录的图片或者字体,AWTK 也提供了相应的方法,下面介绍如何在有文件系统和无文件系统时,加载外部图片和字体。
|
||||
|
||||
## 1 有文件系统
|
||||
|
||||
有文件系统时,如果需要加载非 AWTK 默认目录结构中的图片或字体,可采用"file:// + 图片或字体所在路径"的形式,具体内容请看下文。
|
||||
|
||||
### 1.1 加载外部图片
|
||||
|
||||
例如,要在 home_page 页面显示 E:/designer.png 和 awtk.png(目录结构如下)两张图片。
|
||||
|
||||
```bash
|
||||
Demo
|
||||
|-- design/
|
||||
|-- res/
|
||||
|-- my-res/awtk.png
|
||||
```
|
||||
|
||||
有下面两种实现方式:
|
||||
|
||||
(1)XML文件方式,修改XML文件内容如下:
|
||||
|
||||
```xml
|
||||
<window name="home_page ">
|
||||
<image name="image1" x="0" y="0" w="50" h="50" draw_type="default" image="file://E:/designer.png"/>
|
||||
<image name="image" x="0" y="60" w="50" h="50" draw_type="default" image="file://my-res/awtk.png"/>
|
||||
</window>
|
||||
```
|
||||
|
||||
(2)C代码方式,在C代码中可通过调用 image_set_image() 函数实现,代码如下:
|
||||
|
||||
```c
|
||||
widget_t* image = widget_lookup(win, "image1", TRUE);
|
||||
image_set_image(image, "file://my-res/awtk.png");
|
||||
```
|
||||
|
||||
### 1.2 加载外部字体
|
||||
|
||||
要实现加载外部字体 E:/default.ttf,步骤如下:
|
||||
|
||||
步骤一:修改 res/assets/__assets_default.inc 资源文件,将:
|
||||
|
||||
```c
|
||||
assets_manager_preload(am, ASSET_TYPE_FONT, "default");
|
||||
```
|
||||
|
||||
修改为:
|
||||
|
||||
```c
|
||||
assets_manager_preload(am, ASSET_TYPE_FONT, "file://E:/default.ttf");
|
||||
```
|
||||
|
||||
步骤二:调用 system_info_set_default_font 函数设置缺省字体,代码如下:
|
||||
|
||||
```c
|
||||
system_info_set_default_font(system_info(), "file://E:/default.ttf");
|
||||
```
|
||||
|
||||
## 2 无文件系统
|
||||
|
||||
在无文件系统中,如果需要加载非 AWTK 默认目录结构中的图片或字体,可以将图片或字体数据作为参数传给 assets_manager_add_data() 函数,该函数将这些数据添加到 AWTK 资源管理器中,然后就可以通过文件名的方式使用图片或字体了。
|
||||
|
||||
### 2.1 相关函数
|
||||
|
||||
assets_manager_add_data() 函数说明:
|
||||
|
||||
- 函数原型:
|
||||
|
||||
```c
|
||||
/**
|
||||
* @method assets_manager_add_data
|
||||
* 向资源管理器中增加一个资源data。
|
||||
* 备注:同一份资源多次调用会出现缓存叠加的问题,导致内存泄露
|
||||
* @param {assets_manager_t*} am asset manager对象。
|
||||
* @param {const char*} name 待增加的资源的名字。
|
||||
* @param {uint16_t} type 待增加的资源的主类型枚举。
|
||||
* @param {uint16_t} subtype 待增加的资源的子类型枚举。
|
||||
* @param {uint8_t*} buff 待增加的资源的data数据。
|
||||
* @param {uint32_t} size 待增加的资源的data数据长度。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t assets_manager_add_data(assets_manager_t* am, const char* name, uint16_t type,
|
||||
uint16_t subtype, uint8_t* buff, uint32_t size);
|
||||
```
|
||||
|
||||
type参数资源主类型取值详见下表:
|
||||
|
||||
| 资源主类型 | 说明 |
|
||||
| -------------------- | -------------- |
|
||||
| ASSET_TYPE_NONE | 无效资源 |
|
||||
| **ASSET_TYPE_FONT** | **字体资源** |
|
||||
| **ASSET_TYPE_IMAGE** | **图片资源** |
|
||||
| ASSET_TYPE_STYLE | 窗体样式资源 |
|
||||
| ASSET_TYPE_UI | UI数据资源 |
|
||||
| ASSET_TYPE_XML | XML数据资源 |
|
||||
| ASSET_TYPE_STRINGS | 字符串数据资源 |
|
||||
| ASSET_TYPE_SCRIPT | JS等脚本资源 |
|
||||
| ASSET_TYPE_DATA | 其它数据资源 |
|
||||
|
||||
subtype 参数字体资源子类型详见下表:
|
||||
|
||||
| 资源的主类型枚举 | 说明 |
|
||||
| -------------------- | -------- |
|
||||
| ASSET_TYPE_FONT_NONE | 无效字体 |
|
||||
| ASSET_TYPE_FONT_TTF | TTF字体 |
|
||||
| ASSET_TYPE_FONT_BMP | 位图字体 |
|
||||
|
||||
subtype参数图片资源子类型详见下表:
|
||||
|
||||
| 图片资源子类型 | 说明 |
|
||||
| ------------------------ | ----------------- |
|
||||
| ASSET_TYPE_IMAGE_NONE | 未知图片类型 |
|
||||
| ASSET_TYPE_IMAGE_RAW | Raw图片类型 |
|
||||
| **ASSET_TYPE_IMAGE_BMP** | **位图图片类型** |
|
||||
| **ASSET_TYPE_IMAGE_PNG** | **PNG图片类型** |
|
||||
| **ASSET_TYPE_IMAGE_JPG** | **JPG图片类型** |
|
||||
| ASSET_TYPE_IMAGE_BSVG | BSVG图片类型 |
|
||||
| ASSET_TYPE_IMAGE_GIF | GIF图片类型 |
|
||||
| ASSET_TYPE_IMAGE_WEBP | WEBP图片类型 |
|
||||
| ASSET_TYPE_IMAGE_LZ4 | LZ4压缩的图片类型 |
|
||||
| ASSET_TYPE_IMAGE_OTHER | 其它图片类型 |
|
||||
|
||||
### 2.2 加载外部图片
|
||||
|
||||
例如,要在 home_page 页面显示 E:/awtk.png 这张图片,实现步骤如下:
|
||||
|
||||
(1)添加图片。调用函数 assets_manager_add_data() 向资源管理中添加图片资源,代码如下:
|
||||
|
||||
> 注:由于此处是在 PC 上演示,所以调用了 file_read() 函数读取图片数据,在实际的嵌入式应用场景中,需要通过其他方式读取图片数据。
|
||||
|
||||
```c
|
||||
uint32_t size = 0;
|
||||
uint8_t* data = (uint8_t*)file_read("E:/awtk.png", &size);
|
||||
assets_manager_add_data(assets_manager(), "awtk",
|
||||
ASSET_TYPE_IMAGE,ASSET_TYPE_IMAGE_PNG, data, size);
|
||||
```
|
||||
|
||||
(2)使用图片。在上面的步骤(1)中,已经向 AWTK 资源管理器中添加好了 awtk.png 图片,在 XML 文件或者 C 代码中可以通过指定图片文件名的方式使用图片。
|
||||
|
||||
例如,要在 XML 文件中使用 awtk.png 这张图,代码如下:
|
||||
|
||||
```xml
|
||||
<window name="home_page ">
|
||||
<image name="image" x="0" y="60" w="50" h="50" draw_type="default" image="awtk"/>
|
||||
</window>
|
||||
```
|
||||
|
||||
### 2.3 加载外部字体
|
||||
|
||||
例如,要将 E:/default_full.ttf 字体加载到应用程序中,代码如下,实现步骤如下:
|
||||
|
||||
步骤一:获取字体数据。(此处为了方便演示调用 file_read() 函数读取字体,也可以用其他方式读取字体)。
|
||||
|
||||
步骤二:调用函数 assets_manager_add_data() 函数向资源管理中添加字体资源。
|
||||
|
||||
步骤三:调用 font_manager_add_font() 函数向字体管理器中添加字体。
|
||||
|
||||
步骤四:使用字体。调用 system_info_set_default_font() 函数设置默认字体为 default_full,应用程序将使用该字体。
|
||||
|
||||
```c
|
||||
#include "font_loader/font_loader_truetype.h"
|
||||
|
||||
uint32_t size = 0;
|
||||
uint8_t* data = (uint8_t*)file_read("E:/default_full.ttf", &size);
|
||||
assets_manager_add_data(assets_manager(), "default_full", ASSET_TYPE_FONT,
|
||||
ASSET_TYPE_FONT_TTF,data, size);
|
||||
uint32_t i = 0;
|
||||
uint32_t nr = assets_manager()->assets.size;
|
||||
const asset_info_t** all = (const asset_info_t**)(assets_manager()->assets.elms);
|
||||
|
||||
for (i = 0; i < nr; i++) {
|
||||
const asset_info_t* res = all[i];
|
||||
if (res->subtype == ASSET_TYPE_FONT_TTF && tk_str_eq(res->name, "default_full")) {
|
||||
font_manager_add_font(font_manager(),
|
||||
font_truetype_create(res->name, res->data, res->size));
|
||||
system_info_set_default_font(system_info(), "default_full");
|
||||
}
|
||||
}
|
||||
```
|
@ -1,29 +1,43 @@
|
||||
# 如何显示上下文菜单(俗称右键菜单)
|
||||
|
||||
* 1.注册 EVT\_CONTEXT\_MENU 事件
|
||||
如果需要实现鼠标右键弹出菜单,可以使用 popup 窗口设计菜单 UI 界面,并且通过 AWTK 提供 EVT_CONTEXT_MENU 事件实现该功能,具体步骤如下:
|
||||
|
||||
```c
|
||||
widget_on(win, EVT_CONTEXT_MENU, on_context_menu, win);
|
||||
(1)使用 popup 窗口完成界面设计,作为弹出的菜单。在 popup 窗口的UI文件中,设置 self_layout 属性为"menu"类型,然后设置 close_when_click_outside 属性为"true",表示点击到菜单外时关闭菜单,代码如下:
|
||||
|
||||
```xml
|
||||
<!-- awtk/design/default/ui/menu_point.xml -->
|
||||
<popup style="dark" self_layout="menu(w=128,h=90)" close_when_click_outside="true">
|
||||
...
|
||||
</popup>
|
||||
```
|
||||
|
||||
* 2.实现事件处理函数,在其中打开菜单窗口(建议用 popup 窗口)
|
||||
(2)完成菜单的界面设计后,在源代码中注册对应控件的 EVT_CONTEXT_MENU 事件,例如此处为"open:menu_point"按钮注册该事件,在事件的回调函数中打开步骤(1)中设计好的菜单 UI 文件,代码如下:
|
||||
|
||||
```c
|
||||
/* awtk/demos/demo_ui_app.c */
|
||||
static ret_t on_context_menu(void* ctx, event_t* e) {
|
||||
pointer_event_t* evt = pointer_event_cast(e);
|
||||
widget_t* menu = popup_create(NULL, evt->x, evt->y, 128, 100);
|
||||
widget_t* b1 = button_create(menu, 2, 2, 124, 30);
|
||||
widget_t* b2 = button_create(menu, 2, 34, 124, 30);
|
||||
widget_t* b3 = button_create(menu, 2, 66, 124, 30);
|
||||
open_window("menu_point", NULL);
|
||||
|
||||
widget_set_text_utf8(b1, "Copy");
|
||||
widget_set_text_utf8(b2, "Paste");
|
||||
widget_set_text_utf8(b3, "Cut");
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
popup_set_close_when_click(menu, TRUE);
|
||||
static ret_t install_one(void* ctx, const void* iter) {
|
||||
widget_t* widget = WIDGET(iter);
|
||||
widget_t* win = widget_get_window(widget);
|
||||
|
||||
if (widget->name != NULL) {
|
||||
const char* name = widget->name;
|
||||
if (strstr(name, "open:") != NULL) {
|
||||
widget_on(widget, EVT_CLICK, on_open_window, (void*)(name + 5));
|
||||
widget_on(widget, EVT_LONG_PRESS, on_open_window, (void*)(name + 5));
|
||||
if (tk_str_eq(name, "open:menu_point")) {
|
||||
widget_on(widget, EVT_CONTEXT_MENU, on_context_menu, win);
|
||||
}
|
||||
...
|
||||
return RET_OK;
|
||||
}
|
||||
```
|
||||
|
||||
* [完整例子](https://github.com/zlgopen/awtk-c-demos/blob/master/demos/context_menu.c)
|
||||
(3)运行 awtk/bin/demoui,打开"ContextMenu"页面,鼠标右键点击"Point"按钮,效果如下图所示。
|
||||
|
||||

|
||||
|
63
docs/how_to_use_hardware_image_decoding.md
Normal file
63
docs/how_to_use_hardware_image_decoding.md
Normal file
@ -0,0 +1,63 @@
|
||||
# 如何使用硬件图像解码
|
||||
|
||||
AWTK 默认采用 stb 库进行软件图像解码,全靠 CPU 计算。硬件解码是指将图像解码的工作分配给专门的硬件来处理,减轻 CPU 的计算量,从而提高图像绘制的性能。
|
||||
|
||||
## 1 AWTK 解码图片的流程
|
||||
|
||||
不同平台的解码流程可能会有区别,在 AWTK 中,用户需要自己实现硬件解码的接口,然后调用 image_loader_register 函数注册该接口,后续 AWTK 程序在进行解码时会自动调用该接口解码图片。
|
||||
|
||||
```c
|
||||
/**
|
||||
* @method image_loader_register
|
||||
* 注册图片加载器。
|
||||
*
|
||||
* @annotation ["static"]
|
||||
* @param {image_loader_t*} loader loader对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t image_loader_register(image_loader_t* loader);
|
||||
```
|
||||
|
||||
此处以获取 jpg 图片为例展示 AWTK 是如何获取图片的:
|
||||
|
||||

|
||||
|
||||
> 注:
|
||||
> 1. 上图中的 image_manager_get_bitimp 函数是 AWTK 提供的获取图片功能,接口详见:awtk/src/base/image_manager.c。
|
||||
> 2. 上图中的 image_loader_load_image 函数是 AWTK 提供的加载图片接口,接口详见:awtk/src/base/image_loader.h。
|
||||
|
||||
## 2 STM32 平台案例
|
||||
|
||||
本节以 AWTK 针对 STM32F767igtx 为例,大致讲解如何将硬件解码接口集成到 AWTK 中,移植层源码可前往 [GitHub](https://guihub.com/zlgopen/awtk-stm32f767igtx-raw) 下载。
|
||||
|
||||
步骤一:用户需根据实际使用的硬件平台实现 jpg 图像硬件解码的接口,然后定义一个 image_loader_t 的对象,重载对象中的 load 函数,代码如下:
|
||||
|
||||
```c
|
||||
/* awtk-stm32f767igtx-raw/awtk-port/stm32_jpg_image_loader.c */
|
||||
/* jpg硬件解码函数 */
|
||||
static ret_t image_loader_stm32_jpg_load(image_loader_t *l,
|
||||
const asset_info_t *asset,
|
||||
bitmap_t *image) {
|
||||
/* 实现jpg硬件解码,具体实现视硬件决定 */
|
||||
}
|
||||
|
||||
static const image_loader_t stm32_jpg_image_loader = {
|
||||
.load = image_loader_stm32_jpg_load};
|
||||
|
||||
image_loader_t *image_loader_stm32_jpg() {
|
||||
return (image_loader_t *)&stm32_jpg_image_loader;
|
||||
}
|
||||
```
|
||||
|
||||
步骤二:在 LCD 初始化时顺便注册上一步骤中创建的 image_loader_t 对象,代码如下:
|
||||
|
||||
```c
|
||||
/* awtk-stm32f767igtx-raw/awtk-port/main_loop_stm32_raw.c */
|
||||
/* 在LCD初始化时调用注册函数 */
|
||||
lcd_t* platform_create_lcd(wh_t w, wh_t h) {
|
||||
image_loader_register(image_loader_stm32_jpg());
|
||||
return stm32f767_create_lcd(w, h);
|
||||
}
|
||||
```
|
||||
|
@ -1,24 +1,155 @@
|
||||
# 如何使用 mutable\_image 控件
|
||||
|
||||
有时候,需要把一个视频或者摄像头的数据绘画到屏幕上面。
|
||||
如果需要将视频数据或者摄像头采集到的画面显示到屏幕上,可以使用 mutable_image 控件来实现该功能。该控件主要提供了 mutable_image_set_prepare_image 函数注册一个回调函数,该回调函数在每次绘制之前被调用,用于准备下一帧要显示的图片。
|
||||
|
||||
这个时候就可以使用 mutable\_image 控件来实现该功能了。
|
||||
## 1 相关函数
|
||||
|
||||
在使用 mutable_image 控件的时候,通常涉及到下面几个函数。
|
||||
|
||||
## 一、基本用法
|
||||
(1)mutable_image_set_prepare_image 函数
|
||||
|
||||
一般情况下用户只需要通过 mutable\_image\_set\_prepare\_image 函数注册绘制 bitmap 的函数就可以了,例如下面示例中注册 mutable\_image\_prepare\_image 函数,该函数不断的给 mutable\_image 控件的 bitmap 填充红色,用户也可以在该函数中绘画其他的图像数据,就可以达到动态播放视频或者摄像头的效果。
|
||||
|
||||
#### 备注:
|
||||
|
||||
> 一般情况下 mutable\_image 控件的 bitmap 的位图格式是 lcd 的格式。
|
||||
|
||||
#### 示例:
|
||||
- 函数原型:
|
||||
|
||||
```c
|
||||
/**
|
||||
* @method mutable_image_set_prepare_image
|
||||
* 设置prepare_image回调函数。
|
||||
*
|
||||
* prepare_image回调函数在每次绘制之前被调用,用于准备下一帧要显示的图片。
|
||||
* 比如获取摄像头的预览图片,将其设置到image参数中。
|
||||
*
|
||||
* 注意:在回调函数中,只能修改图片的内容,不用修改图片的大小和格式,如果不匹配请先转换。
|
||||
*
|
||||
* @param {widget_t*} widget mutable_image对象。
|
||||
* @param {mutable_image_prepare_image_t} prepare_image 准备图片的回调函数。
|
||||
* @param {void*} prepare_image_ctx prepare_image回调函数的上下文。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t mutable_image_set_prepare_image(widget_t* widget,
|
||||
mutable_image_prepare_image_t prepare_image, void* prepare_image_ctx);
|
||||
```
|
||||
#include "awtk.h"
|
||||
#include "ext_widgets/mutable_image/mutable_image.h"
|
||||
|
||||
mutable_image_prepare_image_t 的定义如下:
|
||||
|
||||
```c
|
||||
typedef ret_t (*mutable_image_prepare_image_t)(void* ctx, bitmap_t* image);
|
||||
```
|
||||
|
||||
(2)bitmap_create_ex 函数
|
||||
|
||||
- 函数原型:
|
||||
|
||||
```c
|
||||
/**
|
||||
* @method bitmap_create_ex
|
||||
* 创建图片对象。
|
||||
* @annotation ["constructor", "scriptable", "gc"]
|
||||
* @param {uint32_t} w 宽度。
|
||||
* @param {uint32_t} h 高度。
|
||||
* @param {uint32_t} line_length 每一行实际占用的内存,一般情况下为w\*bpp,可填写默认值0。
|
||||
* @param {bitmap_format_t} format 格式。
|
||||
*
|
||||
* @return {bitmap_t*} 返回bitmap对象。
|
||||
*/
|
||||
bitmap_t* bitmap_create_ex(uint32_t w, uint32_t h, uint32_t line_length,
|
||||
bitmap_format_t format);
|
||||
```
|
||||
|
||||
format 参数位图格式常量详见下表:
|
||||
|
||||
| 名称 | 说明 |
|
||||
| ------------------- | ------------------------------------------------------ |
|
||||
| BITMAP_FMT_NONE | 无效格式 |
|
||||
| BITMAP_FMT_RGBA8888 | 一个像素占用4个字节,RGBA占一个字节,按内存地址递增 |
|
||||
| BITMAP_FMT_ABGR8888 | 一个像素占用4个字节,ABGR占一个字节,按内存地址递增 |
|
||||
| BITMAP_FMT_BGRA8888 | 一个像素占用4个字节,BGRA占一个字节,按内存地址递增 |
|
||||
| BITMAP_FMT_ARGB8888 | 一个像素占用4个字节,ARGB占一个字节,按内存地址递增 |
|
||||
| BITMAP_FMT_RGB565 | 一个像素占用2个字节,RGB分别占用5,6,5位,按内存地址递增 |
|
||||
| BITMAP_FMT_BGR565 | 一个像素占用2个字节,BGR分别占用5,6,5位,按内存地址递增 |
|
||||
| BITMAP_FMT_RGB888 | 一个像素占用3个字节,RGB占一个字节,按内存地址递增 |
|
||||
| BITMAP_FMT_BGR888 | 一个像素占用3个字节,RGB占一个字节,按内存地址递增 |
|
||||
| BITMAP_FMT_GRAY | 一个像素占用1个字节 |
|
||||
| BITMAP_FMT_MONO | 一个像素占用1比特 |
|
||||
|
||||
(3)image_fill 函数
|
||||
|
||||
- 函数原型:
|
||||
|
||||
```c
|
||||
/**
|
||||
* @method image_fill
|
||||
* 用颜色绘制指定的区域。
|
||||
* @param {bitmap_t*} dst 目标图片对象。
|
||||
* @param {const rect_t*} dst_r 要填充的目标区域。
|
||||
* @param {color_t} c 颜色。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败,返回失败则上层用软件实现。
|
||||
*/
|
||||
ret_t image_fill(bitmap_t* dst, rect_t* dst_r, color_t c);
|
||||
```
|
||||
|
||||
(4)image_copy 函数
|
||||
|
||||
- 函数原型:
|
||||
|
||||
```c
|
||||
/**
|
||||
* @method image_copy
|
||||
* 把图片指定的区域拷贝到framebuffer中。
|
||||
* @param {bitmap_t*} dst 目标图片对象。
|
||||
* @param {bitmap_t*} src 源图片对象。
|
||||
* @param {const rect_t*} src_r 要拷贝的区域。
|
||||
* @param {xy_t} dx 目标位置的x坐标。
|
||||
* @param {xy_t} dy 目标位置的y坐标。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败,返回失败则上层用软件实现。
|
||||
*/
|
||||
ret_t image_copy(bitmap_t* dst, bitmap_t* src, rect_t* src_r, xy_t dx, xy_t dy);
|
||||
```
|
||||
|
||||
## 2 基本用法
|
||||
|
||||
可以通过下面两种方式使用 mutable_image 控件,两者完成的功能都是一样的,设置屏幕的颜色为蓝色,效果如下图所示:
|
||||
|
||||

|
||||
|
||||
### 2.1 示例一
|
||||
|
||||
直接操作位图数据 image_data,然后往 image_data 设置相应的颜色值,image_data 的大小 = 位图的高度 \* bitmap_get_line_length(每一行实际占用的内存,一般情况下为 w * bpp,其中 w 表示位图的高度,bpp 表示一个像素占用字节数)。image_data 的位图数据格式要与当前 LCD 保持一致,可以调用 lcd_get_desired_bitmap_format 函数获取当前LCD位图数据格式,例如:
|
||||
|
||||
```c
|
||||
bitmap_format_t format = lcd_get_desired_bitmap_format(c->lcd);
|
||||
```
|
||||
|
||||
其中,bitmap_format_t 的定义可参考上面中的 format 参数说明或者参考 `awtk/src/base/types_def.h`文件。
|
||||
|
||||
- 如果 format = BITMAP_FMT_BGR565,表示一个像素占用 2 个字节,BGR 分别占用 5,6,5 位,按内存地址递 增,设置 image_data 的颜色值为蓝色数据格式如下:
|
||||
|
||||
```c
|
||||
image_data[0] = 0x1f; //第一个像素
|
||||
image_data[1] = 0x00; //第一个像素
|
||||
image_data[2] = 0x1f; //第二个像素
|
||||
image_data[3] = 0x00; //第二个像素
|
||||
...
|
||||
```
|
||||
|
||||
- 如果 format = BITMAP_FMT_BGRA8888,表示一个像素占用 4 个字节,BGRA 占一个字节,按内存地址递增,设置 image_data 的颜色值为蓝色数据格式如下:
|
||||
|
||||
```c
|
||||
image_data[0] = 0x1f; //第一个像素
|
||||
image_data[1] = 0x00; //第一个像素
|
||||
image_data[2] = 0x00; //第一个像素
|
||||
image_data[3] = 0xff; //第一个像素
|
||||
```
|
||||
|
||||
AWTK 中默认使用的 LCD 的格式为 BGR565,对应的数据格式请看下图
|
||||
|
||||

|
||||
|
||||
实现代码如下:
|
||||
|
||||
```c
|
||||
ret_t mutable_image_prepare_image(void* ctx, bitmap_t* image) {
|
||||
uint32_t i = 0;
|
||||
uint32_t bpp = 0;
|
||||
@ -26,39 +157,30 @@ ret_t mutable_image_prepare_image(void* ctx, bitmap_t* image) {
|
||||
uint8_t* image_data = NULL;
|
||||
bpp = bitmap_get_bpp(image);
|
||||
size = image->h * bitmap_get_line_length(image);
|
||||
|
||||
#ifdef TK_GRAPHIC_BUFFER_H
|
||||
/* 新版本 AWTK 使用 bitmap_lock_buffer_for_write 函数来获取位图的数据 */
|
||||
image_data = bitmap_lock_buffer_for_write(image);
|
||||
#else
|
||||
/* 旧版本的 AWTK 直接通过 bitmap 成员变量就可以获取位图的数据 */
|
||||
image_data = (uint8_t*)(image->data);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 假设 lcd 的格式为 BGRA8888 ,那么 bpp 应该为4
|
||||
* image_data 是 mutable_image 控件的 bitmap 的位图数据
|
||||
/*
|
||||
* LCD 的格式为 BGR565 ,那么 bpp 应该为 2
|
||||
* image_data是 mutable_image 控件的 bitmap 的位图数据,数据格式与LCD保持一致
|
||||
* image_data大小 = image->h * bitmap_get_line_length(每一行实际占用的内存,一般情况下为w*bpp)
|
||||
* 这里给 image_data 设置为蓝色,当然也可以设置摄像头数据或者视频数据
|
||||
*/
|
||||
for(;i < size; i += bpp, image_data += bpp) {
|
||||
image_data[0] = 0xff;
|
||||
image_data[1] = 0x00;
|
||||
image_data[2] = 0x00;
|
||||
image_data[3] = 0xff;
|
||||
for (; i < size; i += bpp, image_data += bpp) {
|
||||
image_data[0] = 0x1f;
|
||||
image_data[1] = 0x00;
|
||||
}
|
||||
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t application_init() {
|
||||
|
||||
tk_ext_widgets_init();
|
||||
|
||||
widget_t* win = window_create(NULL, 0, 0, 0, 0);
|
||||
|
||||
|
||||
/* 创建 mutable_image 控件 */
|
||||
widget_t* mutable = mutable_image_create(win, 0, 0, win->w, win->h);
|
||||
|
||||
|
||||
/* 注册 mutable_image 控件的绘制图像回调函数 */
|
||||
mutable_image_set_prepare_image(mutable, mutable_image_prepare_image, NULL);
|
||||
|
||||
@ -66,36 +188,74 @@ ret_t application_init() {
|
||||
}
|
||||
```
|
||||
|
||||
> 完整的用法请参考:https://github.com/zlgopen/awtk-c-demos/blob/master/demos/mutable_image.c
|
||||
### 2.2 示例二
|
||||
|
||||
调用 bitmap_create_ex 创建图片对象,图片对象创建好后,调用 image_fill 函数往图片对象填充颜色值。最后调用 image_copy 函数负责将要显示的图片复制到目标图片中(该图片对象由 mutable_image 控件自动生成和销毁),代码如下:
|
||||
|
||||
## 二、支持硬件图层融合用法
|
||||
```c
|
||||
static ret_t mutable_image_prepare_image(void* ctx, bitmap_t* image) {
|
||||
bitmap_t* src = (bitmap_t*)ctx;
|
||||
rect_t r = rect_init(0, 0, image->w, image->h);
|
||||
|
||||
在某些平台下,支持多个 lcd 的硬件 framebuffer ,这些硬件 framebuffer 可以在硬件绘画的时候做合成到 lcd ,这样子可以速度会软件合成要快的多,所以 mutable\_image 控件也支持该情况。
|
||||
color_t color;
|
||||
color.rgba.r = 0;
|
||||
color.rgba.g = 0;
|
||||
color.rgba.b = 0xff;
|
||||
color.rgba.a = 0xff;
|
||||
|
||||
注意:该用法只适用于多个 lcd 硬件 framebuffer 的平台,如果单 framebuffer 的平台就只能使用上面提供的基本用法了。
|
||||
image_fill(src, &r, color);
|
||||
image_copy(image, src, &r, 0, 0);
|
||||
|
||||
> 备注:
|
||||
>
|
||||
> 1. AWTK 的 lcd 类型必须是 32 位色的(RGBA 或者 BGRA 的类型)。
|
||||
> 2. 需要定义 WITH_LCD_CLEAR_ALPHA 宏,让 AWTK 支持刷新透明区域的机制和让 AWTK 支持背景色为透明的混合算法。
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
> 特别说明:
|
||||
>
|
||||
> 1. 定义 WITH_LCD_CLEAR_ALPHA 宏会降低 AWTK 的性能。
|
||||
> 2. AWTK 支持刷新透明区域的机制就可以支持 window 背景色为透明或者半透明的效果,其原理是在绘图之前对脏矩形区域刷一层全透明的颜色。(主要是解决透明背景的残影问题)
|
||||
> 3. AWTK 支持背景色为透明的混合算法,该算法会比背景色为不透明的混合算法更加消耗性能。(背景色为透明,需要比背景色不透明的每个像素点增加好几个乘除法的运算,但是如果背景色本身为不透明就会退化为原来的背景色不透明的混合算法)
|
||||
ret_t application_init() {
|
||||
widget_t* mutable_image = NULL;
|
||||
bitmap_t* src = NULL;
|
||||
widget_t* win = window_create(NULL, 0, 0, 0, 0);
|
||||
canvas_t* c = widget_get_canvas(win);
|
||||
|
||||
#### 1. mutable\_image 控件用法
|
||||
/* XXX: 解码图片的格式和 lcd 的格式保持一致,才能获得最高的性能 */
|
||||
bitmap_format_t format = lcd_get_desired_bitmap_format(c->lcd);
|
||||
src = bitmap_create_ex(win->w, win->h, 0, format);
|
||||
|
||||
如果调用了 mutable\_image\_set\_framebuffer 函数设置硬件 framebuffer 了, mutable\_image 控件就不会在 AWTK 的 GUI 上面显示了,而且由于 mutable\_image 控件的刷新函数受到 AWTK 的消息循环机制影响,所以 mutable\_image 控件帧率和 AWTK 的帧率一样,但是好处是用户只需要简单的把数据刷到 mutable\_image 控件上面就可以了,剩下的交给 AWTK 处理就好了。
|
||||
|
||||
#### 示例:
|
||||
mutable_image = mutable_image_create(win, 0, 0, win->w, win->h);
|
||||
mutable_image_set_prepare_image(mutable_image, mutable_image_prepare_image, src);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
```
|
||||
#include "awtk.h"
|
||||
#include "ext_widgets/mutable_image/mutable_image.h"
|
||||
|
||||
> 完整示例请参考 [mutable_image.c](https://github.com/zlgopen/awtk-c-demos/blob/master/demos/mutable_image.c)。
|
||||
|
||||
## 3 硬件图层融合用法
|
||||
|
||||
在某些平台下,支持 LCD 有多个硬件 FrameBuffer,这些硬件 FrameBuffer 可以在硬件绘制时合成到 LCD 上显示,可将这些 FrameBuffer 理解为多个图层,图层融合后绘制到 LCD 上,这样的速度比软件合成要快很多,因此 mutable_image 控件也支持硬件图层融合用法。
|
||||
|
||||
> 注:硬件图层融合用法只适用于支持 LCD 有多个硬件 FrameBuffer 的平台。
|
||||
|
||||
使用硬件图层融合用法需满足以下要求:
|
||||
|
||||
- AWTK 的 LCD 类型必须是 32 位色的 RGBA 或 BGRA;
|
||||
- 定义宏 WITH_LCD_CLEAR_ALPHA,让 AWTK 支持刷新透明区域,并支持背景色为透明的混合算法。
|
||||
|
||||
需要注意的是:
|
||||
|
||||
1. 定义宏 WITH_LCD_CLEAR_ALPHA 会降低 AWTK 的性能;
|
||||
2. AWTK 支持刷新透明区域,即支持 window 背景色为透明或半透明的效果,其原理是在绘图之前在矩形区域刷一层全透明的颜色;
|
||||
3. AWTK 支持背景色为透明的混合算法,该算法会比背景色为不透明的混合算法更加消耗性能(背景色为透明,需要比背景色不透明的每个像素点增加好几个乘除法的运算,但是如果背景色本身为不透明就会退化为原来的背景色不透明的混合算法)。
|
||||
|
||||
### 3.1 示例
|
||||
|
||||
硬件图层融合用法相较于基本用法不同的地方有三点:
|
||||
|
||||
- 硬件图层融合用法需要 LCD 类型为 32 位色的 RGBA 或 BGRA;
|
||||
- 需要有 LCD 的硬件 FrameBuffer 的地址,该地址通常由硬件平台指定;
|
||||
- 需要调用 mutable_image_set_framebuffe r函数设置硬件 FrameBuffer。
|
||||
|
||||
调用 mutable_image_set_framebuffer 函数设置硬件 FrameBuffer后,mutable_image 控件不会在 AWTK 的 GUI 上显示,但由于 mutable_image 控件的刷新函数受到 AWTK 消息循环机制的影响,所以 mutable_image 控件的帧率和 AWTK 的帧率一样,但优点是用户只需要把图像数据刷新到 mutable_image 控件上即可,接下来的过程由 AWTK 处理,代码如下:
|
||||
|
||||
```c
|
||||
/* 假设 DEVICE_FB 宏的地址为 lcd 的硬件 framebuffer 地址 */
|
||||
#define DEVICE_FB (uint8_t*)0XC0000000
|
||||
|
||||
@ -106,21 +266,14 @@ ret_t mutable_image_prepare_image(void* ctx, bitmap_t* image) {
|
||||
uint8_t* image_data = NULL;
|
||||
bpp = bitmap_get_bpp(image);
|
||||
size = image->h * bitmap_get_line_length(image);
|
||||
|
||||
#ifdef TK_GRAPHIC_BUFFER_H
|
||||
/* 新版本 AWTK 使用 bitmap_lock_buffer_for_write 函数来获取位图的数据 */
|
||||
image_data = bitmap_lock_buffer_for_write(image);
|
||||
#else
|
||||
/* 旧版本的 AWTK 直接通过 bitmap 成员变量就可以获取位图的数据 */
|
||||
image_data = (uint8_t*)(image->data);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 把带有透明度的蓝色填充到 lcd 的硬件 framebuffer 中
|
||||
* 把带有透明度的蓝色填充到 LCD 的硬件 FrameBuffer 中
|
||||
* image_data 是 mutable_image 控件的 bitmap 的位图数据
|
||||
* 这里的 image 的位图格式和长宽分别,是在 mutable_image_set_framebuffer 函数中设置的
|
||||
* 这里的 image 的位图格式和长宽是在 mutable_image_set_framebuffer 函数中设置的
|
||||
* 这里给 image_data 设置为蓝色,当然也可以设置摄像头数据或者视频数据
|
||||
* 这里的 image_data 的地址就是上面 lcd 的硬件 framebuffer 地址
|
||||
* 这里的 image_data 的地址就是上面 LCD 的硬件 FrameBuffer 地址
|
||||
*/
|
||||
for(;i < size; i += bpp, image_data += bpp) {
|
||||
image_data[0] = 0xff;
|
||||
@ -128,33 +281,24 @@ ret_t mutable_image_prepare_image(void* ctx, bitmap_t* image) {
|
||||
image_data[2] = 0x00;
|
||||
image_data[3] = 0xa0;
|
||||
}
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t application_init() {
|
||||
|
||||
tk_ext_widgets_init();
|
||||
|
||||
widget_t* win = window_create(NULL, 0, 0, 0, 0);
|
||||
|
||||
/* 创建 mutable_image 控件 */
|
||||
widget_t* mutable = mutable_image_create(win, 0, 0, win->w, win->h);
|
||||
|
||||
/* 注册 mutable_image 控件的绘制图像回调函数 */
|
||||
mutable_image_set_prepare_image(mutable, mutable_image_prepare_image, NULL);
|
||||
|
||||
/* mutable_image 控件设置位图格式为 BGRA8888 的 lcd 的硬件 framebuffer,并且长宽分别为 win->w 和 win->h 。 */
|
||||
mutable_image_set_framebuffer(mutable, win->w, win->h, BITMAP_FMT_BGRA8888, DEVICE_FB)
|
||||
/* mutable_image 控件设置位图格式为 BGRA8888 的 LCD 的硬件 FrameBuffer */
|
||||
mutable_image_set_framebuffer(mutable, win->w, win->h, BITMAP_FMT_BGRA8888, DEVICE_FB);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. 直接刷硬件方法
|
||||
### 3.2 直接刷新硬件 FrameBuffer
|
||||
|
||||
如果嵌入式支持多线程的话,可以使用一条线程支持刷到其中一个硬件图层中,然后另外一条线程给 AWTK 运行 GUI。
|
||||
若嵌入式平台支持多线程,可以使用一条线程绘制视频数据到其中一个硬件图层上,然后使用另外一条线程绘制 AWTK 的 GUI。该方法的优点是视频的刷新率不会受到 AWTK 的帧率影响,就算 AWTK 的 GUI 出现卡顿现象,也不会导致视频卡顿。
|
||||
|
||||
这个方法的好处是视频的刷新率不会受到 AWTK 的帧率影响,就算 AWTK 的 GUI 很卡,也不会导致视频卡顿的问题,如果硬件图层支持各种格式的透传的话,例如视频数据为 YUV 的话,就可以省下 YUV 格式转换的消耗问题,因为 mutable_image 控件只支持 RGBA8888, BGRA8888,RGB888,BGR888,RGB565,BGR565。
|
||||
|
||||
但是需要用户对嵌入式底层认识更多的要求一些。
|
||||
由于 mutable_image 控件只支持 RGBA8888、BGRA8888、RGB888、BGR888、RGB565、BGR565 格式的图像,因此当视频数据为 YUV 格式的图像时,就需要开发者在程序中将 YUV 图像转换为 mutable_image 控件支持的图像格式,再绘制到控件上。若硬件图层支持各种格式的透传,例如支持 YUV 图像,那么就可以节省格式转换所消耗的时间与资源。
|
||||
|
@ -1,65 +1,63 @@
|
||||
# 如何使用 packed 图片
|
||||
|
||||
## 1. 介绍
|
||||
## 1 介绍
|
||||
|
||||
有时我们把多张小图片打包成一张大图片,这种做法在游戏行业和串口屏经常使用。这样做有以下几个原因:
|
||||
|
||||
* 美术做图方便。
|
||||
|
||||
* 现存的资源就是这样,懒得去切图。
|
||||
|
||||
* 在有 GPU 的时候,可以在一定程度提高性能。
|
||||
- 美术做图方便。
|
||||
- 现存的资源就是这样,懒得去切图。
|
||||
- 在有 GPU 的时候,可以在一定程度提高性能。
|
||||
|
||||
最新的 AWTK 对 packed 图片提供了支持。本文介绍一下如何使用 packed 的图片。
|
||||
|
||||
## 2. 如何指定 packed 图片中的子图
|
||||
## 2 如何指定 packed 图片中的子图
|
||||
|
||||
在 style 中指定图片名称时,用#分隔图片名称和子图区域。指定子图区域的方式有以下几种:
|
||||
在 style 中指定图片名称时,用#分隔图片名称和子图区域,符号"#"之前是大图片的名称,符号"#"之后是设置子图区域的字符串。指定子图区域的方式有以下几种:
|
||||
|
||||
* 空字符串。表示使用控件当前的 xywh 来决定子图的位置和大小。如:
|
||||
- 空字符串。表示使用控件当前的 xywh 来决定子图的位置和大小。如:
|
||||
|
||||
```
|
||||
<pressed bg_image="image_packed_fg#"/>
|
||||
```xml
|
||||
<pressed bg_image="image_packed_fg#"/>
|
||||
```
|
||||
|
||||
> 如果当前控件的区域是 (10, 20, 30, 40),那么子图的区域也是 (10, 20, 30, 40)。
|
||||
> 注:如果当前控件的区域是 (10, 20, 30, 40),那么子图的区域也是 (10, 20, 30, 40)。
|
||||
|
||||
* g。表示使用控件当前的 xywh 来决定子图的位置和大小,xy 转换成全局坐标。如:
|
||||
- g。表示使用控件当前的 xywh 来决定子图的位置和大小,xy 转换成全局坐标。如:
|
||||
|
||||
```
|
||||
<pressed bg_image="image_packed_fg#g"/>
|
||||
```xml
|
||||
<pressed bg_image="image_packed_fg#g"/>
|
||||
```
|
||||
|
||||
> 如果当前控件的区域是 (10, 20, 30, 40),相对于窗口的坐标是 50, 60,那么子图的区域就是 (50, 60, 30, 40)。
|
||||
> 注:如果当前控件的区域是 (10, 20, 30, 40),相对于窗口的坐标是 50, 60,那么子图的区域就是 (50, 60, 30, 40)。
|
||||
|
||||
* xywh(x,y,w,h) 指定子图的绝对坐标。如:
|
||||
- xywh(x,y,w,h) 指定子图的绝对坐标。如:
|
||||
|
||||
```xml
|
||||
<pressed bg_image="image_packed_fg#xywh(106,0,106,54)"/>
|
||||
```
|
||||
<pressed bg_image="image_packed_fg#xywh(106,0,106,54)"/>
|
||||
```
|
||||
> 那么子图的区域就是 (106,0,106,54)
|
||||
> 注:那么子图的区域就是 (106,0,106,54)
|
||||
|
||||
* grid(rows,cols,row,col) 将图片划分为 rows 行 cols 列等大小的网格。row 和 col 指定使用哪一格的子图。如:
|
||||
- grid(rows,cols,row,col) 将图片划分为 rows 行 cols 列等大小的网格。row 和 col 指定使用哪一格的子图。如:
|
||||
|
||||
```
|
||||
<pressed bg_image="image_packed_fg#grid(4,3,0,2)"/
|
||||
```xml
|
||||
<pressed bg_image="image_packed_fg#grid(4,3,0,2)"/
|
||||
```
|
||||
|
||||
> 如果图片大小是 80x60,那么子图的区域就是 (40,0,20,20)
|
||||
> 注:如果图片大小是 80x60,那么子图的区域就是 (40,0,20,20)
|
||||
|
||||
## 3. 示例
|
||||
## 3 示例
|
||||
|
||||
这里有两张图片:
|
||||
此处准备两张packed图片,正常时的效果图片名称为image_packed_bg,颜色浅一点;按下时的效果图片名称为image_packed_fg,颜色深一点。
|
||||
|
||||
* 正常时的效果
|
||||
- 正常时的效果
|
||||
|
||||

|
||||

|
||||
|
||||
* 按下时的效果
|
||||
- 按下时的效果
|
||||
|
||||

|
||||

|
||||
|
||||
> 两张图看起来有些相近,第二张是把第一张调暗后得到的,不过运行起来后按下效果很明显的。
|
||||
> 注:两张图看起来有些相近,第二张是把第一张调暗后得到的,不过运行起来后按下效果很明显的。
|
||||
|
||||
### 3.1 UI 文件
|
||||
|
||||
@ -84,14 +82,12 @@
|
||||
|
||||
### 3.2 Style 文件
|
||||
|
||||
* 使用第一张图为 view 的背景图。按钮在正常情况什么都不用显示。
|
||||
- 使用第一张图为 view 的背景图。按钮在正常情况什么都不用显示。
|
||||
- 按钮在 pressed 状态下背景用指定区域的图片。
|
||||
- 本例子演示来各种用法。通常使用缺省用法即可:
|
||||
|
||||
* 按钮在 pressed 状态下背景用指定区域的图片。
|
||||
|
||||
* 本例子演示来各种用法。通常使用缺省用法即可:
|
||||
|
||||
```
|
||||
<pressed bg_image="image_packed_fg#" />
|
||||
```xml
|
||||
<pressed bg_image="image_packed_fg#" />
|
||||
```
|
||||
|
||||
```xml
|
||||
@ -152,14 +148,13 @@
|
||||
</view>
|
||||
```
|
||||
|
||||
### 3.3 运行示例
|
||||
### 3.3 运行例程
|
||||
|
||||
```
|
||||
```bash
|
||||
./bin/preview_ui design/default/ui/image_packed.xml
|
||||
```
|
||||
|
||||
## 4. 限制
|
||||
|
||||
* 目前只能在 style 中使用。
|
||||
|
||||
* draw\_type 只支持 default|scale|center|icon 等几种。
|
||||
- 目前只能在 style 中使用。
|
||||
- draw\_type 只支持 default|scale|center|icon 等几种。
|
||||
|
BIN
docs/images/BGR565.png
Normal file
BIN
docs/images/BGR565.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.2 KiB |
BIN
docs/images/get_image.png
Normal file
BIN
docs/images/get_image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
BIN
docs/images/image_packed_bg.jpg
Normal file
BIN
docs/images/image_packed_bg.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.2 KiB |
BIN
docs/images/image_packed_fg.jpg
Normal file
BIN
docs/images/image_packed_fg.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.5 KiB |
BIN
docs/images/mutable_image.png
Normal file
BIN
docs/images/mutable_image.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 19 KiB |
BIN
docs/images/popup_menu.png
Normal file
BIN
docs/images/popup_menu.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 99 KiB |
@ -1,70 +1,57 @@
|
||||
## LCD 旋转(横屏与竖屏)
|
||||
# LCD 旋转
|
||||
|
||||
有时开发板上接的 LCD 方向和我们需要的不同,比如 LCD 缺省是横屏显示的,但我们需要竖屏的效果。如果无法通过修改硬件来实现旋转,就只能用软件来实现了。AWKT 目前对双帧缓冲的情况有完善的支持,对基于寄存器的 LCD 需要在驱动中进行配置。
|
||||
|
||||
> 旋转最好由硬件或驱动来做,否则性能会有大弧度下降。本文档提供的方案,主要用于开发前期使用。
|
||||
> 注:旋转最好由硬件或驱动来做,否则性能会有大幅度下降。本文档提供的方案,主要用于开发前期使用。
|
||||
|
||||
### 一、使用方法
|
||||
## 1 使用方法
|
||||
|
||||
1. 首先在初始化时,用 tk\_init 指定 LCD 的大小(这里 LCD 的大小是实际大小,不是旋转之后的大小)。
|
||||
### 1.1 使用 AWTK Designer 实现
|
||||
|
||||
```
|
||||
/**
|
||||
* @method tk_init
|
||||
* 初始化 TK。
|
||||
* @global
|
||||
* @scriptable no
|
||||
* @param {wh_t} w LCD 宽度。
|
||||
* @param {wh_t} h LCD 高度。
|
||||
*
|
||||
* @return {ret_t} 返回 RET_OK 表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t tk_init(wh_t w, wh_t h);
|
||||
在 AWTK Designer 左下角点击"项目设置",在"LCD 旋转设置"一栏中选择旋转角度后点击"确认"即可。
|
||||
|
||||
### 1.2 使用 C 代码实现
|
||||
|
||||
在 `src/main.c`文件中定义一个宏,示例与宏的取值如下:
|
||||
|
||||
| 宏 | 作用 |
|
||||
| ------------------- | -------------- |
|
||||
| LCD_ORIENTATION_90 | 逆时针旋转90° |
|
||||
| LCD_ORIENTATION_180 | 逆时针旋转180° |
|
||||
| LCD_ORIENTATION_270 | 逆时针旋转270° |
|
||||
|
||||
```c
|
||||
/* 逆时针旋转90° */
|
||||
#define APP_LCD_ORIENTATION LCD_ORIENTATION_90
|
||||
```
|
||||
|
||||
2. 然后用 tk\_set\_lcd\_orientation 来设置 LCD 的旋转角度。
|
||||
> 该宏需要在"#include "awtk_main.inc""前进行定义。
|
||||
|
||||
```
|
||||
/**
|
||||
* @method tk_set_lcd_orientation
|
||||
* 设置屏幕的旋转方向 (XXX: 目前仅支持 0 度和 90 度)。
|
||||
* @global
|
||||
*
|
||||
* @return {ret_t} 返回 RET_OK 表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t tk_set_lcd_orientation(lcd_orientation_t orientation);
|
||||
```
|
||||
### 1.3 快速旋转模式
|
||||
|
||||
> 参考:demos/demo_main.c
|
||||
AWTK 内部还提供了快速旋转模式,该机制能在旋转时保持较高的效率(和没有旋转时的运行效率几乎一样),但是兼容性比较差,具体如何使用请参考 [如何使用高效的屏幕旋转](https://github.com/zlgopen/awtk/tree/master/docs/how_to_use_fast_lcd_portrait.md)
|
||||
|
||||
_____
|
||||
## 2 不同 LCD 实现方式对旋转的支持
|
||||
|
||||
AWTK 目前支持 3 种 LCD 实现方式,不同的实现方式对旋转的支持有所不同,下面我们一一介绍。
|
||||
|
||||
### 二、基于寄存器的 LCD(lcd\_reg)
|
||||
### 2.1 基于寄存器的 LCD(lcd\_reg)
|
||||
|
||||
基于寄存器的 LCD(lcd\_reg),调用 tk\_set\_lcd\_orientation 只是做了两件事:
|
||||
1. 对触摸事件的坐标进行转换。
|
||||
2. 设置窗口管理器的大小为旋转之后的大小。
|
||||
|
||||
* 1. 对触摸事件的坐标进行转换。
|
||||
一般的 LCD 器件可以在驱动中设置像素的扫描顺序,在初始化时设置一下即可(未测试过),所以 AWTK 并没有对像素进行相应旋转。
|
||||
|
||||
* 2. 设置窗口管理器的大小为旋转之后的大小。
|
||||
> 注:参考:http://www.cnblogs.com/amanlikethis/p/3872515.html
|
||||
|
||||
一般的 LCD 器件可以在驱动中设置像素的扫描顺序,在初始化时设置一下即可(驱动我不太熟悉,没有测试过),所以 AWTK 并没有对像素进行相应旋转。
|
||||
### 2.2 基于 FrameBuffer 的 LCD(lcd\_mem)
|
||||
|
||||
> 参考:http://www.cnblogs.com/amanlikethis/p/3872515.html
|
||||
1. 对触摸事件的坐标进行转换。
|
||||
2. 设置窗口管理器的大小为旋转之后的大小。
|
||||
3. offline fb 为旋转之后的大小,online fb 为原始大小。在 lcd flush 时需要进行旋转(在没有硬件旋转减速的情况下,会增加一点性能开销)。
|
||||
4. 在进行平移窗口动画时。AWTK 将图片直接贴到 online fb 上,处于性能的考虑,在截图时进行旋转,在贴图时直接拷贝。所以在 lcd\_mem\_draw\_image 和 lcd\_mem\_take\_snapshot 两个函数中做了处理。
|
||||
|
||||
### 二、基于 FrameBuffer 的 LCD(lcd\_mem)
|
||||
### 2.3 基于 VGCanvas 的 LCD(lcd\_vgcanvas)
|
||||
|
||||
基于 FrameBuffer 的 LCD(lcd\_mem),AWTK 对旋转 90/180/270 度做了支持。调用 tk\_set\_lcd\_orientation 后 AWTK 会做以下几件事:
|
||||
|
||||
* 1. 对触摸事件的坐标进行转换。
|
||||
|
||||
* 2. 设置窗口管理器的大小为旋转之后的大小。
|
||||
|
||||
* 3.offline fb 为旋转之后的大小,online fb 为原始大小。在 lcd flush 时需要进行旋转(在没有硬件旋转减速的情况下,会增加一点性能开销)。
|
||||
|
||||
* 4. 在进行平移窗口动画时。AWTK 将图片直接贴到 online fb 上,处于性能的考虑,在截图时进行旋转,在贴图时直接拷贝。所以在 lcd\_mem\_draw\_image 和 lcd\_mem\_take\_snapshot 两个函数中做了处理。
|
||||
|
||||
### 三、基于 VGCanvas 的 LCD(lcd\_vgcanvas)
|
||||
|
||||
> 最新版本已经支持旋转。
|
||||
1. 对触摸事件的坐标进行转换。
|
||||
2. 矢量画布绘制时,旋转坐标。
|
||||
|
Loading…
x
Reference in New Issue
Block a user