# 10. 裁剪功能案例

AWTK 全功能开启时,如果编译选项为 -Os (不包含调试信息),此时 ROM 占用大概为 2MB。需要注意的是,因为项目资源(字体、图片、UI文件等)占用的 ROM 是根据实际情况而定的,所以本章节讨论的裁剪只针对代码文件,不包含资源文件。

在 ROM 较少的板子上,通常要根据实际需求裁剪掉 AWTK 的部分功能,降低 ROM 占用,但这势必会造成功能缺失,并且某些功能被裁减后也会降低性能或者绘图效果,功能模块介绍可查看本文附录二。

# 10.1 中资源平台的裁剪案例

在中资源平台上,除了输入法需要裁剪以外,其他功能基本都可以使用。输入法本身的代码并不多,但是输入法资源(比如输入法字典、联想字库等)却很大,例如 AWTK 中的谷歌输入法的资源约占用 1MB 多。

本章将 AWTK 针对 STM32F492igtx 平台的 移植层 (opens new window) 作为中资源平台上的裁剪案例,该平台的资源如下:

  • 片内 ROM:1MB;
  • 片内 RAM:512KB;
  • 片外 RAM:32MB。

# 10.1.1 awtk_config.h 的宏

下面是 STM32F492igtx 移植层中的宏配置,此处定义了 WITH_IME_NULLWITHOUT_SUGGEST_WORDS,它们的作用分别是不启用输入法但是支持使用软键盘,以及不使用联想词组。

/* awtk_port/awtk_config.h */
/* 嵌入式系统有自己的main函数时,请定义本宏 */
#define USE_GUI_MAIN 1

/* 如果支持png/jpeg图片,请定义本宏 */
#define WITH_STB_IMAGE 1

/* 如果支持Truetype字体,请定义本宏 */
#define WITH_STB_FONT 1

/* 如果定义本宏,使用标准的UNICODE换行算法,除非资源极为有限,请定义本宏 */
#define WITH_UNICODE_BREAK 1

/* 如果定义本宏,将图片解码成BGRA8888格式,否则解码成RGBA8888的格式 */
#define WITH_BITMAP_BGRA 1

/* 如果定义本宏,将不透明的PNG图片解码成BGR565格式,建议定义 */
#define WITH_BITMAP_BGR565 1

/* 如果ROM空间较小,不足以放大字体文件时,请定义本宏 */
#define WITH_MINI_FONT 1

/* 如果启用STM32 G2D硬件加速,请定义本宏 */
#define WITH_STM32_G2D 1

/* 如果启用VGCANVAS,而且没有OpenGL硬件加速,请定义本宏 */
#define WITH_NANOVG_AGGE 1

/* 如果启用VGCANVAS,请定义本宏 */
#define WITH_VGCANVAS 1

/* 如果启用输入法,但不想启用联想功能,请定义本宏 */
#define WITHOUT_SUGGEST_WORDS 1

/* 如果不启用输入法,但支持软键盘,请定义本宏 */
#define WITH_IME_NULL 1

# 10.1.2 需添加到工程中的代码

在裁剪时候需要注意一些问题,如果开启了某些功能后,需要把相关的代码添加在项目中。

  1. STM32F492igtx 移植层中定义了宏 WITH_VGCANVAS 和宏 WITH_NANOVG_AGGE,说明支持矢量画布功能,需要添加的文件详见本文附录二中的矢量画布模块。

  2. 如果定义了宏 WITH_NULL_IM,说明不需要软键盘了,可以把 awtk/src/ext_widgets/keyboard 目录中的代码去掉,并且把 awtk/src/ext_widgets/ext_widgets.c 文件中 keyboard 相关的代码注册代码注释掉。

根据实际裁剪情况,需添加到工程中编译的 AWTK 代码详见下文 8.3 章节。

# 10.2 低资源平台的裁剪案例

AWTK 不太建议在低资源平台上运行,ROM 过小会限制 AWTK 的功能和控件,而 RAM 过小会导致 AWTK 的效率降低,并且还会导致部分功能无法使用。

本章将 AWTK 针对 STM32F103ze 平台的 移植层 (opens new window) 作为低资源平台上的裁剪案例,该平台的资源如下:

  • 片内 ROM:1MB;
  • 片内 RAM:64KB;

需要注意的是,虽然 ROM 有 1MB,但是 RAM 只有 64KB(这 64KB 还需要包括显存),并且本案例中会把的项目的 ROM 裁剪到 150KB 左右(不包含项目资源)。

# 10.2.1 awtk_config.h 的宏

由于 103 的项目中 RAM 只有 64KB,所以这里采用了片段式显存的方案,详情可参考 awtk/docs/lcd.md,下面分配了 8 * 1024 * 2 字节作为片段式显存,然后给 AWTK 分配了 4 * 6000 字节作为运行内存。

/* 嵌入式系统有自己的main函数时,请定义本宏 */
 #define USE_GUI_MAIN 1

/* 如果需要支持预先解码的位图字体,请定义本宏。一般只在RAM极小时,才启用本宏 */
#define WITH_BITMAP_FONT 1

/* 如果不需输入法,请定义本宏 */
#define WITH_NULL_IM 1

/* 如果出现wcsxxx之类的函数没有定义,请定义该宏 */
#define WITH_WCSXXX 1

/* AWTK 只保留基本功能和控件 */
#define AWTK_LITE 1

/* 如果想裁剪 AWTK 的基本控件,请定义本宏 */
// #define AWTK_NOGUI 1

/* 如果内存不足以提供完整的 FrameBuffer,请定义本宏(单位:像素个数) */
 #define FRAGMENT_FRAME_BUFFER_SIZE 8 * 1024

按照上述宏定义,在编译选项为 -O0 时,ROM 占用约为 230KB,如果编译选项改为 -O2 或者 -O3,ROM 会低于 200KB。

# 10.2.2 裁剪多余的部分

AWTK_LITE 宏主要实现了下列功能的裁剪:

定义的宏 作用
WITH_NULL_IM 裁剪了输入法和软键盘
WITHOUT_LAYOUT 裁剪了布局算法
WITHOUT_CLIPBOARD 裁剪了剪切板模块
WITHOUT_EXT_WIDGETS 裁剪了扩展控件
WITHOUT_INPUT_METHOD 裁剪输入法全局对象
WITHOUT_WINDOW_ANIMATORS 裁剪了窗口动画
WITHOUT_WIDGET_ANIMATORS 裁剪了控件动画
WITHOUT_DIALOG_HIGHLIGHTER 裁剪对话框高亮模块

接下来,移除多余的部分可以进一步降低 ROM 占用,在最新的 AWTK 中可以不需要做下面的操作,因为宏 AWTK_LITE 宏已经做了。

首先,可以裁剪掉 fscript 模块,该模块是一个简单的脚本引擎,通常给 awtk-mvvm (opens new window) 使用,普通的 AWTK 程序并不需要,裁剪步骤如下:

  1. 在 STM32F103ze 移植层中,移除 fscript.c 文件。
  2. 把 awtk_global.c 文件中关于 fscript 的代码删除。
  3. 修改 widget.c 文件中的 widget_exec_code 函数,代码如下:
/* awtk/src/base/widget.c */
static ret_t widget_exec_code(void* ctx, event_t* evt) {
  return RET_OK;
}

重新编译后,ROM 大小会降到 210KB 左右。

接下来,如果项目没有用到圆角矩形效果,还可以裁剪掉该功能,修改 canvas.c 文件,代码如下:

/* awtk/src/base/canvas.c */

/* 1.注释掉该文件 */
// #include "ffr_draw_rounded_rect.inc"  

/* 2. 修改以下相关函数,去掉实现代码 */
ret_t canvas_fill_rounded_rect(/*...*/) { /* 此处表示省略参数,下文类似 */
  return RET_FAIL;
}

ret_t canvas_stroke_rounded_rect(/*...*/) {
  return RET_FAIL;
}

ret_t canvas_fill_rounded_rect_ex(/*...*/) {
  return RET_FAIL;
}

ret_t canvas_stroke_rounded_rect_ex(/*...*/) {
  return RET_FAIL;
}

重新编译后,ROM 大小会降到 200KB 左右,并且占用内存也减少了 3KB。

最后,我们继续裁剪离线画布功能,这个功能常用于窗口动画以及控件截图,在内存紧缺时用处不大,裁剪该功能首先需要注释掉 canvas.c 文件中的以下代码:

/* awtk/src/base/canvas.c */
// #include "canvas_offline.inc"

然后,修改 window_manager_default.c 文件中两个函数,代码如下:

/* awtk/src/window_manager/window_manager_default.c  */
ret_t window_manager_default_snap_curr_window(/*...*/) {
  return RET_NOT_IMPL;
}

ret_t window_manager_default_snap_prev_window(/*...*/) {
  return RET_NOT_IMPL;
}

重新编译后,ROM 大小已降为 190KB,接着把编译选项改成 -O2,会降至 150KB,如果定义宏 AWTK_NOGUI,还可以进一步降到 130KB,但这会裁剪掉基本控件,导致 UI 文件无法正常显示。

# 10.3 要添加到工程的文件

AWTK 在嵌入式下的核心代码结构与需要添加到工程中的代码文件详见本文 1.4 章节中的表格。