无忧启动论坛

 找回密码
 注册
搜索
系统gho:最纯净好用系统下载站投放广告、加入VIP会员,请联系 微信:wuyouceo
查看: 5097|回复: 13
打印 上一主题 下一主题

[讨论] LVGL 在 GRUB2 上的移植

  [复制链接]
跳转到指定楼层
1#
发表于 2022-9-21 13:38:27 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 wintoflash 于 2022-10-1 13:39 编辑

效果测试:


1. 前言
LVGL 是一个适用于嵌入式设备的轻量级通用型图形库。
它使用纯 C 语言编写,无任何依赖,支持鼠标/键盘/触摸板等输入设备,支持 UTF-8,比较适合移植到 GRUB2 上。
本文用于记录我尝试移植 LVGL 改造 GRUB2 图形界面的过程,仅供参考,目前尚未完工。
目前我使用的 LVGL 版本是 v8.3,GRUB2 是 2.11-git-d9b4638,编译器是 GCC 12。
参考资料:

评分

参与人数 7无忧币 +40 收起 理由
liuzhaoyzz + 10 我已清理无意义回帖,请提前先占几个楼层。
阿弥陀佛 + 5 很给力!
纯脆entropy + 5 很给力!
879792799 + 5 大佬啊!666666
freesoft00 + 5
hilsonma + 5 期待新界面!
ksafei + 5 很给力!

查看全部评分

2#
 楼主| 发表于 2022-9-21 13:43:38 | 只看该作者
本帖最后由 wintoflash 于 2022-10-1 13:38 编辑

2. 改造 GRUB2 posix_wrap 库
修改 grub-core/lib/posix_wrap/sys/types.h,添加以下内容:
  1. typedef grub_uint64_t uintmax_t;
  2. typedef grub_int64_t intmax_t;
复制代码

修改 grub-core/lib/posix_wrap/limits.h,添加以下内容:
  1. #define INT8_MIN GRUB_SCHAR_MIN
  2. #define INT8_MAX GRUB_SCHAR_MAX
  3. #define INT16_MIN GRUB_SHRT_MIN
  4. #define INT16_MAX GRUB_SHRT_MAX
  5. #define INT32_MIN GRUB_INT32_MIN
  6. #define INT32_MAX GRUB_INT32_MAX

  7. #define UINT8_MAX GRUB_UCHAR_MAX
  8. #define UINT16_MAX GRUB_USHRT_MAX
  9. #define UINT32_MAX GRUB_UINT_MAX
复制代码

修改 grub-core/lib/posix_wrap/inttypes.h:
  1. #ifndef GRUB_POSIX_INTTYPES_H
  2. #define GRUB_POSIX_INTTYPES_H

  3. #include <sys/types.h>

  4. #define PRId32 PRIdGRUB_INT32_T
  5. #define PRIu32 PRIuGRUB_UINT32_T
  6. #define PRIx32 PRIxGRUB_UINT32_T

  7. #define PRId64 PRIdGRUB_INT64_T
  8. #define PRIu64 PRIdGRUB_UINT64_T
  9. #define PRIx64 PRIdGRUB_UINT64_T

  10. #endif
复制代码

修改 grub-core/lib/posix_wrap/stdint.h,添加以下内容:
  1. #include <limits.h>
复制代码

修改 grub-core/lib/posix_wrap/string.h, 添加以下函数:
  1. static inline int
  2. strncmp (const char *s1, const char *s2, grub_size_t n)
  3. {
  4.   return grub_strncmp (s1, s2, n);
  5. }

  6. static inline char *
  7. strcat (char *dest, const char *src)
  8. {
  9.   grub_strcpy (dest + grub_strlen (dest), src);
  10.   return dest;
  11. }
复制代码

3. 修改 GRUB2 compiler-rt
由于 LVGL 中使用到了 64 位整数除法,因此要在 i386 架构下添加 __udivmoddi4 和 __divmoddi4 这两个符号。
修改 include/grub/misc.h:
  1. #if !defined(GRUB_MACHINE_EMU) && (defined(__arm__) || defined(__ia64__) || \
  2.     (defined(__riscv) && (__riscv_xlen == 32)))
  3. #define GRUB_DIVISION_IN_SOFTWARE 1
复制代码

改为
  1. #if !defined(GRUB_MACHINE_EMU) && (defined(__arm__) || defined(__ia64__) || \
  2.     defined(__i386__) || (defined(__riscv) && (__riscv_xlen == 32)))
  3. #define GRUB_DIVISION_IN_SOFTWARE 1
复制代码

修改 gentpl.py:
  1. GROUPS["softdiv"] = GROUPS["arm"] + ["ia64_efi"] + GROUPS["riscv32"]
复制代码

改为
  1. GROUPS["softdiv"] = GROUPS["arm"] + ["ia64_efi"] + GROUPS["i386"] + GROUPS["riscv32"]
复制代码

修改 include/grub/compiler-rt.h,在 #if defined(GRUB_DIVISION_IN_SOFTWARE) && GRUB_DIVISION_IN_SOFTWARE 条件里面加入
  1. grub_uint64_t
  2. EXPORT_FUNC (__udivmoddi4) (grub_uint64_t n, grub_uint64_t d, grub_uint64_t *r);

  3. grub_int64_t
  4. EXPORT_FUNC(__divmoddi4) (grub_int64_t n, grub_int64_t d, grub_int64_t *r);
复制代码

修改 grub-core/kern/compiler-rt.c,在对应条件下加入
  1. grub_uint64_t
  2. __udivmoddi4 (grub_uint64_t n, grub_uint64_t d, grub_uint64_t *r)
  3. {
  4.   return grub_divmod64 (n, d, r);
  5. }

  6. grub_int64_t
  7. __divmoddi4 (grub_int64_t n, grub_int64_t d, grub_int64_t *r)
  8. {
  9.   return grub_divmod64s (n, d, r);
  10. }
复制代码


回复

使用道具 举报

3#
 楼主| 发表于 2022-9-21 13:52:27 | 只看该作者
本帖最后由 wintoflash 于 2022-10-1 13:37 编辑

4. 导入 LVGL 源码
在 grub-core 下建立 lvgl 文件夹
将 LVGL 源码目录下的 src 目录复制到 grub-core/lvgl/
将 LVGL 源码目录下的 lvgl.h 复制到 grub-core/lvgl/lvgl.h
创建文件夹 grub-core/lvgl/port
将 LVGL 源码目录下的 lv_conf_template.h 复制到 grub-core/lvgl/port/lv_conf.h
创建文件 grub-core/lvgl/port/module.c
  1. #include <grub/dl.h>
  2. GRUB_MOD_LICENSE ("GPLv3+");
复制代码

修改 conf/Makefile.common,添加
  1. CFLAGS_LVGL = -Wno-discarded-qualifiers -Wno-redundant-decls -Wno-nested-externs -Wno-suggest-attribute=format -Wno-shadow -Wno-incompatible-pointer-types $(CFLAGS_POSIX)
  2. CPPFLAGS_LVGL = -I$(top_builddir)/grub-core/lvgl/port -DLV_CONF_INCLUDE_SIMPLE $(CPPFLAGS_POSIX)

  3. CFLAGS_LVGLAPP = $(CFLAGS_POSIX)
  4. CPPFLAGS_LVGLAPP = $(CPPFLAGS_LVGL) -I$(top_builddir)/grub-core/lvgl
复制代码

修改 grub-core/Makefile.core.def,添加
  1. module = {
  2.   name = lvgl;
  3.   common = lvgl/port/module.c;

  4.   common = lvgl/src/core/lv_disp.c;
  5.   common = lvgl/src/core/lv_group.c;
  6.   common = lvgl/src/core/lv_indev.c;
  7.   common = lvgl/src/core/lv_indev_scroll.c;
  8.   common = lvgl/src/core/lv_obj.c;
  9.   common = lvgl/src/core/lv_obj_class.c;
  10.   common = lvgl/src/core/lv_obj_draw.c;
  11.   common = lvgl/src/core/lv_obj_pos.c;
  12.   common = lvgl/src/core/lv_obj_scroll.c;
  13.   common = lvgl/src/core/lv_obj_style.c;
  14.   common = lvgl/src/core/lv_obj_style_gen.c;
  15.   common = lvgl/src/core/lv_obj_tree.c;
  16.   common = lvgl/src/core/lv_event.c;
  17.   common = lvgl/src/core/lv_refr.c;
  18.   common = lvgl/src/core/lv_theme.c;

  19.   common = lvgl/src/draw/lv_draw_arc.c;
  20.   common = lvgl/src/draw/lv_draw.c;
  21.   common = lvgl/src/draw/lv_draw_img.c;
  22.   common = lvgl/src/draw/lv_draw_label.c;
  23.   common = lvgl/src/draw/lv_draw_line.c;
  24.   common = lvgl/src/draw/lv_draw_mask.c;
  25.   common = lvgl/src/draw/lv_draw_rect.c;
  26.   common = lvgl/src/draw/lv_draw_transform.c;
  27.   common = lvgl/src/draw/lv_draw_layer.c;
  28.   common = lvgl/src/draw/lv_draw_triangle.c;
  29.   common = lvgl/src/draw/lv_img_buf.c;
  30.   common = lvgl/src/draw/lv_img_cache.c;
  31.   common = lvgl/src/draw/lv_img_decoder.c;
  32.   common = lvgl/src/draw/sw/lv_draw_sw.c;
  33.   common = lvgl/src/draw/sw/lv_draw_sw_arc.c;
  34.   common = lvgl/src/draw/sw/lv_draw_sw_blend.c;
  35.   common = lvgl/src/draw/sw/lv_draw_sw_dither.c;
  36.   common = lvgl/src/draw/sw/lv_draw_sw_gradient.c;
  37.   common = lvgl/src/draw/sw/lv_draw_sw_img.c;
  38.   common = lvgl/src/draw/sw/lv_draw_sw_letter.c;
  39.   common = lvgl/src/draw/sw/lv_draw_sw_line.c;
  40.   common = lvgl/src/draw/sw/lv_draw_sw_polygon.c;
  41.   common = lvgl/src/draw/sw/lv_draw_sw_rect.c;
  42.   common = lvgl/src/draw/sw/lv_draw_sw_transform.c;
  43.   common = lvgl/src/draw/sw/lv_draw_sw_layer.c;

  44.   common = lvgl/src/font/lv_font.c;
  45.   common = lvgl/src/font/lv_font_fmt_txt.c;
  46.   common = lvgl/src/font/lv_font_loader.c;
  47.   common = lvgl/src/font/lv_font_dejavu_16_persian_hebrew.c;
  48.   common = lvgl/src/font/lv_font_montserrat_8.c;
  49.   common = lvgl/src/font/lv_font_montserrat_10.c;
  50.   common = lvgl/src/font/lv_font_montserrat_12.c;
  51.   common = lvgl/src/font/lv_font_montserrat_12_subpx.c;
  52.   common = lvgl/src/font/lv_font_montserrat_14.c;
  53.   common = lvgl/src/font/lv_font_montserrat_16.c;
  54.   common = lvgl/src/font/lv_font_montserrat_18.c;
  55.   common = lvgl/src/font/lv_font_montserrat_20.c;
  56.   common = lvgl/src/font/lv_font_montserrat_22.c;
  57.   common = lvgl/src/font/lv_font_montserrat_24.c;
  58.   common = lvgl/src/font/lv_font_montserrat_26.c;
  59.   common = lvgl/src/font/lv_font_montserrat_28.c;
  60.   common = lvgl/src/font/lv_font_montserrat_28_compressed.c;
  61.   common = lvgl/src/font/lv_font_montserrat_30.c;
  62.   common = lvgl/src/font/lv_font_montserrat_32.c;
  63.   common = lvgl/src/font/lv_font_montserrat_34.c;
  64.   common = lvgl/src/font/lv_font_montserrat_36.c;
  65.   common = lvgl/src/font/lv_font_montserrat_38.c;
  66.   common = lvgl/src/font/lv_font_montserrat_40.c;
  67.   common = lvgl/src/font/lv_font_montserrat_42.c;
  68.   common = lvgl/src/font/lv_font_montserrat_44.c;
  69.   common = lvgl/src/font/lv_font_montserrat_46.c;
  70.   common = lvgl/src/font/lv_font_montserrat_48.c;
  71.   common = lvgl/src/font/lv_font_simsun_16_cjk.c;
  72.   common = lvgl/src/font/lv_font_unscii_8.c;
  73.   common = lvgl/src/font/lv_font_unscii_16.c;

  74.   common = lvgl/src/hal/lv_hal_disp.c;
  75.   common = lvgl/src/hal/lv_hal_indev.c;
  76.   common = lvgl/src/hal/lv_hal_tick.c;

  77.   common = lvgl/src/misc/lv_anim.c;
  78.   common = lvgl/src/misc/lv_anim_timeline.c;
  79.   common = lvgl/src/misc/lv_area.c;
  80.   common = lvgl/src/misc/lv_async.c;
  81.   common = lvgl/src/misc/lv_bidi.c;
  82.   common = lvgl/src/misc/lv_color.c;
  83.   common = lvgl/src/misc/lv_fs.c;
  84.   common = lvgl/src/misc/lv_gc.c;
  85.   common = lvgl/src/misc/lv_ll.c;
  86.   common = lvgl/src/misc/lv_log.c;
  87.   common = lvgl/src/misc/lv_lru.c;
  88.   common = lvgl/src/misc/lv_math.c;
  89.   common = lvgl/src/misc/lv_mem.c;
  90.   common = lvgl/src/misc/lv_printf.c;
  91.   common = lvgl/src/misc/lv_style.c;
  92.   common = lvgl/src/misc/lv_style_gen.c;
  93.   common = lvgl/src/misc/lv_timer.c;
  94.   common = lvgl/src/misc/lv_tlsf.c;
  95.   common = lvgl/src/misc/lv_txt.c;
  96.   common = lvgl/src/misc/lv_txt_ap.c;
  97.   common = lvgl/src/misc/lv_utils.c;

  98.   common = lvgl/src/widgets/lv_arc.c;
  99.   common = lvgl/src/widgets/lv_bar.c;
  100.   common = lvgl/src/widgets/lv_btn.c;
  101.   common = lvgl/src/widgets/lv_btnmatrix.c;
  102.   common = lvgl/src/widgets/lv_canvas.c;
  103.   common = lvgl/src/widgets/lv_checkbox.c;
  104.   common = lvgl/src/widgets/lv_dropdown.c;
  105.   common = lvgl/src/widgets/lv_img.c;
  106.   common = lvgl/src/widgets/lv_label.c;
  107.   common = lvgl/src/widgets/lv_line.c;
  108.   common = lvgl/src/widgets/lv_roller.c;
  109.   common = lvgl/src/widgets/lv_slider.c;
  110.   common = lvgl/src/widgets/lv_switch.c;
  111.   common = lvgl/src/widgets/lv_table.c;
  112.   common = lvgl/src/widgets/lv_textarea.c;

  113.   common = lvgl/src/extra/lv_extra.c;

  114.   common = lvgl/src/extra/layouts/flex/lv_flex.c;
  115.   common = lvgl/src/extra/layouts/grid/lv_grid.c;

  116.   common = lvgl/src/extra/libs/bmp/lv_bmp.c;
  117.   common = lvgl/src/extra/libs/gif/gifdec.c;
  118.   common = lvgl/src/extra/libs/gif/lv_gif.c;
  119.   common = lvgl/src/extra/libs/png/lodepng.c;
  120.   common = lvgl/src/extra/libs/png/lv_png.c;
  121.   common = lvgl/src/extra/libs/sjpg/lv_sjpg.c;
  122.   common = lvgl/src/extra/libs/sjpg/tjpgd.c;

  123.   common = lvgl/src/extra/others/fragment/lv_fragment_manager.c;
  124.   common = lvgl/src/extra/others/fragment/lv_fragment.c;
  125.   common = lvgl/src/extra/others/gridnav/lv_gridnav.c;
  126.   common = lvgl/src/extra/others/ime/lv_ime_pinyin.c;
  127.   common = lvgl/src/extra/others/imgfont/lv_imgfont.c;
  128.   common = lvgl/src/extra/others/monkey/lv_monkey.c;
  129.   common = lvgl/src/extra/others/msg/lv_msg.c;
  130.   common = lvgl/src/extra/others/snapshot/lv_snapshot.c;

  131.   common = lvgl/src/extra/themes/basic/lv_theme_basic.c;
  132.   common = lvgl/src/extra/themes/default/lv_theme_default.c;
  133.   common = lvgl/src/extra/themes/mono/lv_theme_mono.c;

  134.   common = lvgl/src/extra/widgets/animimg/lv_animimg.c;
  135.   common = lvgl/src/extra/widgets/calendar/lv_calendar_header_arrow.c;
  136.   common = lvgl/src/extra/widgets/calendar/lv_calendar_header_dropdown.c;
  137.   common = lvgl/src/extra/widgets/calendar/lv_calendar.c;
  138.   common = lvgl/src/extra/widgets/chart/lv_chart.c;
  139.   common = lvgl/src/extra/widgets/colorwheel/lv_colorwheel.c;
  140.   common = lvgl/src/extra/widgets/imgbtn/lv_imgbtn.c;
  141.   common = lvgl/src/extra/widgets/keyboard/lv_keyboard.c;
  142.   common = lvgl/src/extra/widgets/led/lv_led.c;
  143.   common = lvgl/src/extra/widgets/list/lv_list.c;
  144.   common = lvgl/src/extra/widgets/menu/lv_menu.c;
  145.   common = lvgl/src/extra/widgets/meter/lv_meter.c;
  146.   common = lvgl/src/extra/widgets/msgbox/lv_msgbox.c;
  147.   common = lvgl/src/extra/widgets/span/lv_span.c;
  148.   common = lvgl/src/extra/widgets/spinbox/lv_spinbox.c;
  149.   common = lvgl/src/extra/widgets/spinner/lv_spinner.c;
  150.   common = lvgl/src/extra/widgets/tabview/lv_tabview.c;
  151.   common = lvgl/src/extra/widgets/tileview/lv_tileview.c;
  152.   common = lvgl/src/extra/widgets/win/lv_win.c;

  153.   cflags = '$(CFLAGS_LVGL)';
  154.   cppflags = '$(CPPFLAGS_LVGL)';
  155. };
复制代码

编辑 grub-core/lvgl/port/lv_conf.h,参考编译配置:
  1. /**
  2. * @file lv_conf.h
  3. * Configuration file for v8.3.1
  4. */

  5. /*
  6. * Copy this file as `lv_conf.h`
  7. * 1. simply next to the `lvgl` folder
  8. * 2. or any other places and
  9. *    - define `LV_CONF_INCLUDE_SIMPLE`
  10. *    - add the path as include path
  11. */

  12. /* clang-format off */
  13. #if 1 /*Set it to "1" to enable content*/

  14. #ifndef LV_CONF_H
  15. #define LV_CONF_H

  16. #include <stdint.h>

  17. /*====================
  18.    COLOR SETTINGS
  19. *====================*/

  20. /*Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888)*/
  21. #define LV_COLOR_DEPTH 32

  22. /*Swap the 2 bytes of RGB565 color. Useful if the display has an 8-bit interface (e.g. SPI)*/
  23. #define LV_COLOR_16_SWAP 0

  24. /*Enable features to draw on transparent background.
  25. *It's required if opa, and transform_* style properties are used.
  26. *Can be also used if the UI is above another layer, e.g. an OSD menu or video player.*/
  27. #define LV_COLOR_SCREEN_TRANSP 1

  28. /* Adjust color mix functions rounding. GPUs might calculate color mix (blending) differently.
  29. * 0: round down, 64: round up from x.75, 128: round up from half, 192: round up from x.25, 254: round up */
  30. #define LV_COLOR_MIX_ROUND_OFS 0

  31. /*Images pixels with this color will not be drawn if they are chroma keyed)*/
  32. #define LV_COLOR_CHROMA_KEY lv_color_hex(0x00ff00)         /*pure green*/

  33. /*=========================
  34.    MEMORY SETTINGS
  35. *=========================*/

  36. /*1: use custom malloc/free, 0: use the built-in `lv_mem_alloc()` and `lv_mem_free()`*/
  37. #define LV_MEM_CUSTOM 1
  38. #if LV_MEM_CUSTOM == 0
  39.     /*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/
  40.     #define LV_MEM_SIZE (48U * 1024U)          /*[bytes]*/

  41.     /*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/
  42.     #define LV_MEM_ADR 0     /*0: unused*/
  43.     /*Instead of an address give a memory allocator that will be called to get a memory pool for LVGL. E.g. my_malloc*/
  44.     #if LV_MEM_ADR == 0
  45.         #undef LV_MEM_POOL_INCLUDE
  46.         #undef LV_MEM_POOL_ALLOC
  47.     #endif

  48. #else       /*LV_MEM_CUSTOM*/
  49.     #define LV_MEM_CUSTOM_INCLUDE <stdlib.h>   /*Header for the dynamic memory function*/
  50.     #define LV_MEM_CUSTOM_ALLOC   malloc
  51.     #define LV_MEM_CUSTOM_FREE    free
  52.     #define LV_MEM_CUSTOM_REALLOC realloc
  53. #endif     /*LV_MEM_CUSTOM*/

  54. /*Number of the intermediate memory buffer used during rendering and other internal processing mechanisms.
  55. *You will see an error log message if there wasn't enough buffers. */
  56. #define LV_MEM_BUF_MAX_NUM 16

  57. /*Use the standard `memcpy` and `memset` instead of LVGL's own functions. (Might or might not be faster).*/
  58. #define LV_MEMCPY_MEMSET_STD 1

  59. /*====================
  60.    HAL SETTINGS
  61. *====================*/

  62. /*Default display refresh period. LVG will redraw changed areas with this period time*/
  63. #define LV_DISP_DEF_REFR_PERIOD 30      /*[ms]*/

  64. /*Input device read period in milliseconds*/
  65. #define LV_INDEV_DEF_READ_PERIOD 30     /*[ms]*/

  66. /*Use a custom tick source that tells the elapsed time in milliseconds.
  67. *It removes the need to manually update the tick with `lv_tick_inc()`)*/
  68. #define LV_TICK_CUSTOM 0
  69. #if LV_TICK_CUSTOM
  70.     #define LV_TICK_CUSTOM_INCLUDE "Arduino.h"         /*Header for the system time function*/
  71.     #define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis())    /*Expression evaluating to current system time in ms*/
  72. #endif   /*LV_TICK_CUSTOM*/

  73. /*Default Dot Per Inch. Used to initialize default sizes such as widgets sized, style paddings.
  74. *(Not so important, you can adjust it to modify default sizes and spaces)*/
  75. #define LV_DPI_DEF 130     /*[px/inch]*/

  76. /*=======================
  77. * FEATURE CONFIGURATION
  78. *=======================*/

  79. /*-------------
  80. * Drawing
  81. *-----------*/

  82. /*Enable complex draw engine.
  83. *Required to draw shadow, gradient, rounded corners, circles, arc, skew lines, image transformations or any masks*/
  84. #define LV_DRAW_COMPLEX 1
  85. #if LV_DRAW_COMPLEX != 0

  86.     /*Allow buffering some shadow calculation.
  87.     *LV_SHADOW_CACHE_SIZE is the max. shadow size to buffer, where shadow size is `shadow_width + radius`
  88.     *Caching has LV_SHADOW_CACHE_SIZE^2 RAM cost*/
  89.     #define LV_SHADOW_CACHE_SIZE 0

  90.     /* Set number of maximally cached circle data.
  91.     * The circumference of 1/4 circle are saved for anti-aliasing
  92.     * radius * 4 bytes are used per circle (the most often used radiuses are saved)
  93.     * 0: to disable caching */
  94.     #define LV_CIRCLE_CACHE_SIZE 4
  95. #endif /*LV_DRAW_COMPLEX*/

  96. /**
  97. * "Simple layers" are used when a widget has `style_opa < 255` to buffer the widget into a layer
  98. * and blend it as an image with the given opacity.
  99. * Note that `bg_opa`, `text_opa` etc don't require buffering into layer)
  100. * The widget can be buffered in smaller chunks to avoid using large buffers.
  101. *
  102. * - LV_LAYER_SIMPLE_BUF_SIZE: [bytes] the optimal target buffer size. LVGL will try to allocate it
  103. * - LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE: [bytes]  used if `LV_LAYER_SIMPLE_BUF_SIZE` couldn't be allocated.
  104. *
  105. * Both buffer sizes are in bytes.
  106. * "Transformed layers" (where transform_angle/zoom properties are used) use larger buffers
  107. * and can't be drawn in chunks. So these settings affects only widgets with opacity.
  108. */
  109. #define LV_LAYER_SIMPLE_BUF_SIZE          (24 * 1024)
  110. #define LV_LAYER_SIMPLE_FALLBACK_BUF_SIZE (3 * 1024)

  111. /*Default image cache size. Image caching keeps the images opened.
  112. *If only the built-in image formats are used there is no real advantage of caching. (I.e. if no new image decoder is added)
  113. *With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images.
  114. *However the opened images might consume additional RAM.
  115. *0: to disable caching*/
  116. #define LV_IMG_CACHE_DEF_SIZE 1

  117. /*Number of stops allowed per gradient. Increase this to allow more stops.
  118. *This adds (sizeof(lv_color_t) + 1) bytes per additional stop*/
  119. #define LV_GRADIENT_MAX_STOPS 2

  120. /*Default gradient buffer size.
  121. *When LVGL calculates the gradient "maps" it can save them into a cache to avoid calculating them again.
  122. *LV_GRAD_CACHE_DEF_SIZE sets the size of this cache in bytes.
  123. *If the cache is too small the map will be allocated only while it's required for the drawing.
  124. *0 mean no caching.*/
  125. #define LV_GRAD_CACHE_DEF_SIZE 4096

  126. /*Allow dithering the gradients (to achieve visual smooth color gradients on limited color depth display)
  127. *LV_DITHER_GRADIENT implies allocating one or two more lines of the object's rendering surface
  128. *The increase in memory consumption is (32 bits * object width) plus 24 bits * object width if using error diffusion */
  129. #define LV_DITHER_GRADIENT 1
  130. #if LV_DITHER_GRADIENT
  131.     /*Add support for error diffusion dithering.
  132.      *Error diffusion dithering gets a much better visual result, but implies more CPU consumption and memory when drawing.
  133.      *The increase in memory consumption is (24 bits * object's width)*/
  134.     #define LV_DITHER_ERROR_DIFFUSION 1
  135. #endif

  136. /*Maximum buffer size to allocate for rotation.
  137. *Only used if software rotation is enabled in the display driver.*/
  138. #define LV_DISP_ROT_MAX_BUF (10*1024)

  139. /*-------------
  140. * GPU
  141. *-----------*/

  142. /*Use Arm's 2D acceleration library Arm-2D */
  143. #define LV_USE_GPU_ARM2D 0

  144. /*Use STM32's DMA2D (aka Chrom Art) GPU*/
  145. #define LV_USE_GPU_STM32_DMA2D 0
  146. #if LV_USE_GPU_STM32_DMA2D
  147.     /*Must be defined to include path of CMSIS header of target processor
  148.     e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
  149.     #define LV_GPU_DMA2D_CMSIS_INCLUDE
  150. #endif

  151. /*Use SWM341's DMA2D GPU*/
  152. #define LV_USE_GPU_SWM341_DMA2D 0
  153. #if LV_USE_GPU_SWM341_DMA2D
  154.     #define LV_GPU_SWM341_DMA2D_INCLUDE "SWM341.h"
  155. #endif

  156. /*Use NXP's PXP GPU iMX RTxxx platforms*/
  157. #define LV_USE_GPU_NXP_PXP 0
  158. #if LV_USE_GPU_NXP_PXP
  159.     /*1: Add default bare metal and FreeRTOS interrupt handling routines for PXP (lv_gpu_nxp_pxp_osa.c)
  160.     *   and call lv_gpu_nxp_pxp_init() automatically during lv_init(). Note that symbol SDK_OS_FREE_RTOS
  161.     *   has to be defined in order to use FreeRTOS OSA, otherwise bare-metal implementation is selected.
  162.     *0: lv_gpu_nxp_pxp_init() has to be called manually before lv_init()
  163.     */
  164.     #define LV_USE_GPU_NXP_PXP_AUTO_INIT 0
  165. #endif

  166. /*Use NXP's VG-Lite GPU iMX RTxxx platforms*/
  167. #define LV_USE_GPU_NXP_VG_LITE 0

  168. /*Use SDL renderer API*/
  169. #define LV_USE_GPU_SDL 0
  170. #if LV_USE_GPU_SDL
  171.     #define LV_GPU_SDL_INCLUDE_PATH <SDL2/SDL.h>
  172.     /*Texture cache size, 8MB by default*/
  173.     #define LV_GPU_SDL_LRU_SIZE (1024 * 1024 * 8)
  174.     /*Custom blend mode for mask drawing, disable if you need to link with older SDL2 lib*/
  175.     #define LV_GPU_SDL_CUSTOM_BLEND_MODE (SDL_VERSION_ATLEAST(2, 0, 6))
  176. #endif

  177. /*-------------
  178. * Logging
  179. *-----------*/

  180. /*Enable the log module*/
  181. #define LV_USE_LOG 0
  182. #if LV_USE_LOG

  183.     /*How important log should be added:
  184.     *LV_LOG_LEVEL_TRACE       A lot of logs to give detailed information
  185.     *LV_LOG_LEVEL_INFO        Log important events
  186.     *LV_LOG_LEVEL_WARN        Log if something unwanted happened but didn't cause a problem
  187.     *LV_LOG_LEVEL_ERROR       Only critical issue, when the system may fail
  188.     *LV_LOG_LEVEL_USER        Only logs added by the user
  189.     *LV_LOG_LEVEL_NONE        Do not log anything*/
  190.     #define LV_LOG_LEVEL LV_LOG_LEVEL_WARN

  191.     /*1: Print the log with 'printf';
  192.     *0: User need to register a callback with `lv_log_register_print_cb()`*/
  193.     #define LV_LOG_PRINTF 0

  194.     /*Enable/disable LV_LOG_TRACE in modules that produces a huge number of logs*/
  195.     #define LV_LOG_TRACE_MEM        1
  196.     #define LV_LOG_TRACE_TIMER      1
  197.     #define LV_LOG_TRACE_INDEV      1
  198.     #define LV_LOG_TRACE_DISP_REFR  1
  199.     #define LV_LOG_TRACE_EVENT      1
  200.     #define LV_LOG_TRACE_OBJ_CREATE 1
  201.     #define LV_LOG_TRACE_LAYOUT     1
  202.     #define LV_LOG_TRACE_ANIM       1

  203. #endif  /*LV_USE_LOG*/

  204. /*-------------
  205. * Asserts
  206. *-----------*/

  207. /*Enable asserts if an operation is failed or an invalid data is found.
  208. *If LV_USE_LOG is enabled an error message will be printed on failure*/
  209. #define LV_USE_ASSERT_NULL          1   /*Check if the parameter is NULL. (Very fast, recommended)*/
  210. #define LV_USE_ASSERT_MALLOC        1   /*Checks is the memory is successfully allocated or no. (Very fast, recommended)*/
  211. #define LV_USE_ASSERT_STYLE         1   /*Check if the styles are properly initialized. (Very fast, recommended)*/
  212. #define LV_USE_ASSERT_MEM_INTEGRITY 0   /*Check the integrity of `lv_mem` after critical operations. (Slow)*/
  213. #define LV_USE_ASSERT_OBJ           0   /*Check the object's type and existence (e.g. not deleted). (Slow)*/

  214. /*Add a custom handler when assert happens e.g. to restart the MCU*/
  215. #define LV_ASSERT_HANDLER_INCLUDE <stdint.h>
  216. #define LV_ASSERT_HANDLER while(1);   /*Halt by default*/

  217. /*-------------
  218. * Others
  219. *-----------*/

  220. /*1: Show CPU usage and FPS count*/
  221. #define LV_USE_PERF_MONITOR 0
  222. #if LV_USE_PERF_MONITOR
  223.     #define LV_USE_PERF_MONITOR_POS LV_ALIGN_BOTTOM_RIGHT
  224. #endif

  225. /*1: Show the used memory and the memory fragmentation
  226. * Requires LV_MEM_CUSTOM = 0*/
  227. #define LV_USE_MEM_MONITOR 0
  228. #if LV_USE_MEM_MONITOR
  229.     #define LV_USE_MEM_MONITOR_POS LV_ALIGN_BOTTOM_LEFT
  230. #endif

  231. /*1: Draw random colored rectangles over the redrawn areas*/
  232. #define LV_USE_REFR_DEBUG 0

  233. /*Change the built in (v)snprintf functions*/
  234. #define LV_SPRINTF_CUSTOM 0
  235. #if LV_SPRINTF_CUSTOM
  236.     #define LV_SPRINTF_INCLUDE <stdio.h>
  237.     #define lv_snprintf  snprintf
  238.     #define lv_vsnprintf vsnprintf
  239. #else   /*LV_SPRINTF_CUSTOM*/
  240.     #define LV_SPRINTF_USE_FLOAT 0
  241. #endif  /*LV_SPRINTF_CUSTOM*/

  242. #define LV_USE_USER_DATA 1

  243. /*Garbage Collector settings
  244. *Used if lvgl is bound to higher level language and the memory is managed by that language*/
  245. #define LV_ENABLE_GC 0
  246. #if LV_ENABLE_GC != 0
  247.     #define LV_GC_INCLUDE "gc.h"                           /*Include Garbage Collector related things*/
  248. #endif /*LV_ENABLE_GC*/

  249. /*=====================
  250. *  COMPILER SETTINGS
  251. *====================*/

  252. /*For big endian systems set to 1*/
  253. #ifdef GRUB_CPU_WORDS_BIGENDIAN
  254. #define LV_BIG_ENDIAN_SYSTEM 1
  255. #else
  256. #define LV_BIG_ENDIAN_SYSTEM 0
  257. #endif

  258. /*Define a custom attribute to `lv_tick_inc` function*/
  259. #define LV_ATTRIBUTE_TICK_INC

  260. /*Define a custom attribute to `lv_timer_handler` function*/
  261. #define LV_ATTRIBUTE_TIMER_HANDLER

  262. /*Define a custom attribute to `lv_disp_flush_ready` function*/
  263. #define LV_ATTRIBUTE_FLUSH_READY

  264. /*Required alignment size for buffers*/
  265. #define LV_ATTRIBUTE_MEM_ALIGN_SIZE 1

  266. /*Will be added where memories needs to be aligned (with -Os data might not be aligned to boundary by default).
  267. * E.g. __attribute__((aligned(4)))*/
  268. #define LV_ATTRIBUTE_MEM_ALIGN

  269. /*Attribute to mark large constant arrays for example font's bitmaps*/
  270. #define LV_ATTRIBUTE_LARGE_CONST

  271. /*Compiler prefix for a big array declaration in RAM*/
  272. #define LV_ATTRIBUTE_LARGE_RAM_ARRAY

  273. /*Place performance critical functions into a faster memory (e.g RAM)*/
  274. #define LV_ATTRIBUTE_FAST_MEM

  275. /*Prefix variables that are used in GPU accelerated operations, often these need to be placed in RAM sections that are DMA accessible*/
  276. #define LV_ATTRIBUTE_DMA

  277. /*Export integer constant to binding. This macro is used with constants in the form of LV_<CONST> that
  278. *should also appear on LVGL binding API such as Micropython.*/
  279. #define LV_EXPORT_CONST_INT(int_value) struct _silence_gcc_warning /*The default value just prevents GCC warning*/

  280. /*Extend the default -32k..32k coordinate range to -4M..4M by using int32_t for coordinates instead of int16_t*/
  281. #define LV_USE_LARGE_COORD 0

  282. /*==================
  283. *   FONT USAGE
  284. *===================*/

  285. /*Montserrat fonts with ASCII range and some symbols using bpp = 4
  286. *https://fonts.google.com/specimen/Montserrat*/
  287. #define LV_FONT_MONTSERRAT_8  1
  288. #define LV_FONT_MONTSERRAT_10 0
  289. #define LV_FONT_MONTSERRAT_12 1
  290. #define LV_FONT_MONTSERRAT_14 1
  291. #define LV_FONT_MONTSERRAT_16 1
  292. #define LV_FONT_MONTSERRAT_18 1
  293. #define LV_FONT_MONTSERRAT_20 0
  294. #define LV_FONT_MONTSERRAT_22 0
  295. #define LV_FONT_MONTSERRAT_24 1
  296. #define LV_FONT_MONTSERRAT_26 0
  297. #define LV_FONT_MONTSERRAT_28 1
  298. #define LV_FONT_MONTSERRAT_30 0
  299. #define LV_FONT_MONTSERRAT_32 1
  300. #define LV_FONT_MONTSERRAT_34 0
  301. #define LV_FONT_MONTSERRAT_36 1
  302. #define LV_FONT_MONTSERRAT_38 0
  303. #define LV_FONT_MONTSERRAT_40 0
  304. #define LV_FONT_MONTSERRAT_42 0
  305. #define LV_FONT_MONTSERRAT_44 0
  306. #define LV_FONT_MONTSERRAT_46 0
  307. #define LV_FONT_MONTSERRAT_48 1

  308. /*Demonstrate special features*/
  309. #define LV_FONT_MONTSERRAT_12_SUBPX      1
  310. #define LV_FONT_MONTSERRAT_28_COMPRESSED 1  /*bpp = 3*/
  311. #define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 1  /*Hebrew, Arabic, Persian letters and all their forms*/
  312. #define LV_FONT_SIMSUN_16_CJK            1  /*1000 most common CJK radicals*/

  313. /*Pixel perfect monospace fonts*/
  314. #define LV_FONT_UNSCII_8  1
  315. #define LV_FONT_UNSCII_16 1

  316. /*Optionally declare custom fonts here.
  317. *You can use these fonts as default font too and they will be available globally.
  318. *E.g. #define LV_FONT_CUSTOM_DECLARE   LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2)*/
  319. #define LV_FONT_CUSTOM_DECLARE

  320. /*Always set a default font*/
  321. #define LV_FONT_DEFAULT &lv_font_montserrat_16

  322. /*Enable handling large font and/or fonts with a lot of characters.
  323. *The limit depends on the font size, font face and bpp.
  324. *Compiler error will be triggered if a font needs it.*/
  325. #define LV_FONT_FMT_TXT_LARGE 1

  326. /*Enables/disables support for compressed fonts.*/
  327. #define LV_USE_FONT_COMPRESSED 1

  328. /*Enable subpixel rendering*/
  329. #define LV_USE_FONT_SUBPX 0
  330. #if LV_USE_FONT_SUBPX
  331.     /*Set the pixel order of the display. Physical order of RGB channels. Doesn't matter with "normal" fonts.*/
  332.     #define LV_FONT_SUBPX_BGR 0  /*0: RGB; 1:BGR order*/
  333. #endif

  334. /*Enable drawing placeholders when glyph dsc is not found*/
  335. #define LV_USE_FONT_PLACEHOLDER 1

  336. /*=================
  337. *  TEXT SETTINGS
  338. *=================*/

  339. /**
  340. * Select a character encoding for strings.
  341. * Your IDE or editor should have the same character encoding
  342. * - LV_TXT_ENC_UTF8
  343. * - LV_TXT_ENC_ASCII
  344. */
  345. #define LV_TXT_ENC LV_TXT_ENC_UTF8

  346. /*Can break (wrap) texts on these chars*/
  347. #define LV_TXT_BREAK_CHARS " ,.;:-_"

  348. /*If a word is at least this long, will break wherever "prettiest"
  349. *To disable, set to a value <= 0*/
  350. #define LV_TXT_LINE_BREAK_LONG_LEN 0

  351. /*Minimum number of characters in a long word to put on a line before a break.
  352. *Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/
  353. #define LV_TXT_LINE_BREAK_LONG_PRE_MIN_LEN 3

  354. /*Minimum number of characters in a long word to put on a line after a break.
  355. *Depends on LV_TXT_LINE_BREAK_LONG_LEN.*/
  356. #define LV_TXT_LINE_BREAK_LONG_POST_MIN_LEN 3

  357. /*The control character to use for signalling text recoloring.*/
  358. #define LV_TXT_COLOR_CMD "#"

  359. /*Support bidirectional texts. Allows mixing Left-to-Right and Right-to-Left texts.
  360. *The direction will be processed according to the Unicode Bidirectional Algorithm:
  361. *https://www.w3.org/International/articles/inline-bidi-markup/uba-basics*/
  362. #define LV_USE_BIDI 1
  363. #if LV_USE_BIDI
  364.     /*Set the default direction. Supported values:
  365.     *`LV_BASE_DIR_LTR` Left-to-Right
  366.     *`LV_BASE_DIR_RTL` Right-to-Left
  367.     *`LV_BASE_DIR_AUTO` detect texts base direction*/
  368.     #define LV_BIDI_BASE_DIR_DEF LV_BASE_DIR_AUTO
  369. #endif

  370. /*Enable Arabic/Persian processing
  371. *In these languages characters should be replaced with an other form based on their position in the text*/
  372. #define LV_USE_ARABIC_PERSIAN_CHARS 1

  373. /*==================
  374. *  WIDGET USAGE
  375. *================*/

  376. /*Documentation of the widgets: https://docs.lvgl.io/latest/en/html/widgets/index.html*/

  377. #define LV_USE_ARC        1

  378. #define LV_USE_BAR        1

  379. #define LV_USE_BTN        1

  380. #define LV_USE_BTNMATRIX  1

  381. #define LV_USE_CANVAS     1

  382. #define LV_USE_CHECKBOX   1

  383. #define LV_USE_DROPDOWN   1   /*Requires: lv_label*/

  384. #define LV_USE_IMG        1   /*Requires: lv_label*/

  385. #define LV_USE_LABEL      1
  386. #if LV_USE_LABEL
  387.     #define LV_LABEL_TEXT_SELECTION 1 /*Enable selecting text of the label*/
  388.     #define LV_LABEL_LONG_TXT_HINT 1  /*Store some extra info in labels to speed up drawing of very long texts*/
  389. #endif

  390. #define LV_USE_LINE       1

  391. #define LV_USE_ROLLER     1   /*Requires: lv_label*/
  392. #if LV_USE_ROLLER
  393.     #define LV_ROLLER_INF_PAGES 7 /*Number of extra "pages" when the roller is infinite*/
  394. #endif

  395. #define LV_USE_SLIDER     1   /*Requires: lv_bar*/

  396. #define LV_USE_SWITCH     1

  397. #define LV_USE_TEXTAREA   1   /*Requires: lv_label*/
  398. #if LV_USE_TEXTAREA != 0
  399.     #define LV_TEXTAREA_DEF_PWD_SHOW_TIME 1500    /*ms*/
  400. #endif

  401. #define LV_USE_TABLE      1

  402. /*==================
  403. * EXTRA COMPONENTS
  404. *==================*/

  405. /*-----------
  406. * Widgets
  407. *----------*/
  408. #define LV_USE_ANIMIMG    1

  409. #define LV_USE_CALENDAR   1
  410. #if LV_USE_CALENDAR
  411.     #define LV_CALENDAR_WEEK_STARTS_MONDAY 0
  412.     #if LV_CALENDAR_WEEK_STARTS_MONDAY
  413.         #define LV_CALENDAR_DEFAULT_DAY_NAMES {"Mo", "Tu", "We", "Th", "Fr", "Sa", "Su"}
  414.     #else
  415.         #define LV_CALENDAR_DEFAULT_DAY_NAMES {"Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"}
  416.     #endif

  417.     #define LV_CALENDAR_DEFAULT_MONTH_NAMES {"January", "February", "March",  "April", "May",  "June", "July", "August", "September", "October", "November", "December"}
  418.     #define LV_USE_CALENDAR_HEADER_ARROW 1
  419.     #define LV_USE_CALENDAR_HEADER_DROPDOWN 1
  420. #endif  /*LV_USE_CALENDAR*/

  421. #define LV_USE_CHART      1

  422. #define LV_USE_COLORWHEEL 1

  423. #define LV_USE_IMGBTN     1

  424. #define LV_USE_KEYBOARD   1

  425. #define LV_USE_LED        1

  426. #define LV_USE_LIST       1

  427. #define LV_USE_MENU       1

  428. #define LV_USE_METER      1

  429. #define LV_USE_MSGBOX     1

  430. #define LV_USE_SPAN       1
  431. #if LV_USE_SPAN
  432.     /*A line text can contain maximum num of span descriptor */
  433.     #define LV_SPAN_SNIPPET_STACK_SIZE 64
  434. #endif

  435. #define LV_USE_SPINBOX    1

  436. #define LV_USE_SPINNER    1

  437. #define LV_USE_TABVIEW    1

  438. #define LV_USE_TILEVIEW   1

  439. #define LV_USE_WIN        1

  440. /*-----------
  441. * Themes
  442. *----------*/

  443. /*A simple, impressive and very complete theme*/
  444. #define LV_USE_THEME_DEFAULT 1
  445. #if LV_USE_THEME_DEFAULT

  446.     /*0: Light mode; 1: Dark mode*/
  447.     #define LV_THEME_DEFAULT_DARK 0

  448.     /*1: Enable grow on press*/
  449.     #define LV_THEME_DEFAULT_GROW 1

  450.     /*Default transition time in [ms]*/
  451.     #define LV_THEME_DEFAULT_TRANSITION_TIME 80
  452. #endif /*LV_USE_THEME_DEFAULT*/

  453. /*A very simple theme that is a good starting point for a custom theme*/
  454. #define LV_USE_THEME_BASIC 1

  455. /*A theme designed for monochrome displays*/
  456. #define LV_USE_THEME_MONO 1

  457. /*-----------
  458. * Layouts
  459. *----------*/

  460. /*A layout similar to Flexbox in CSS.*/
  461. #define LV_USE_FLEX 1

  462. /*A layout similar to Grid in CSS.*/
  463. #define LV_USE_GRID 1

  464. /*---------------------
  465. * 3rd party libraries
  466. *--------------------*/

  467. /*File system interfaces for common APIs */

  468. /*API for fopen, fread, etc*/
  469. #define LV_USE_FS_STDIO 0
  470. #if LV_USE_FS_STDIO
  471.     #define LV_FS_STDIO_LETTER '\0'     /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
  472.     #define LV_FS_STDIO_PATH ""         /*Set the working directory. File/directory paths will be appended to it.*/
  473.     #define LV_FS_STDIO_CACHE_SIZE 0    /*>0 to cache this number of bytes in lv_fs_read()*/
  474. #endif

  475. /*API for open, read, etc*/
  476. #define LV_USE_FS_POSIX 0
  477. #if LV_USE_FS_POSIX
  478.     #define LV_FS_POSIX_LETTER '\0'     /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
  479.     #define LV_FS_POSIX_PATH ""         /*Set the working directory. File/directory paths will be appended to it.*/
  480.     #define LV_FS_POSIX_CACHE_SIZE 0    /*>0 to cache this number of bytes in lv_fs_read()*/
  481. #endif

  482. /*API for CreateFile, ReadFile, etc*/
  483. #define LV_USE_FS_WIN32 0
  484. #if LV_USE_FS_WIN32
  485.     #define LV_FS_WIN32_LETTER '\0'     /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
  486.     #define LV_FS_WIN32_PATH ""         /*Set the working directory. File/directory paths will be appended to it.*/
  487.     #define LV_FS_WIN32_CACHE_SIZE 0    /*>0 to cache this number of bytes in lv_fs_read()*/
  488. #endif

  489. /*API for FATFS (needs to be added separately). Uses f_open, f_read, etc*/
  490. #define LV_USE_FS_FATFS 0
  491. #if LV_USE_FS_FATFS
  492.     #define LV_FS_FATFS_LETTER '\0'     /*Set an upper cased letter on which the drive will accessible (e.g. 'A')*/
  493.     #define LV_FS_FATFS_CACHE_SIZE 0    /*>0 to cache this number of bytes in lv_fs_read()*/
  494. #endif

  495. /*PNG decoder library*/
  496. #define LV_USE_PNG 1

  497. /*BMP decoder library*/
  498. #define LV_USE_BMP 1

  499. /* JPG + split JPG decoder library.
  500. * Split JPG is a custom format optimized for embedded systems. */
  501. #define LV_USE_SJPG 1

  502. /*GIF decoder library*/
  503. #define LV_USE_GIF 1

  504. /*QR code library*/
  505. #define LV_USE_QRCODE 0

  506. /*FreeType library*/
  507. #define LV_USE_FREETYPE 0
  508. #if LV_USE_FREETYPE
  509.     /*Memory used by FreeType to cache characters [bytes] (-1: no caching)*/
  510.     #define LV_FREETYPE_CACHE_SIZE (16 * 1024)
  511.     #if LV_FREETYPE_CACHE_SIZE >= 0
  512.         /* 1: bitmap cache use the sbit cache, 0:bitmap cache use the image cache. */
  513.         /* sbit cache:it is much more memory efficient for small bitmaps(font size < 256) */
  514.         /* if font size >= 256, must be configured as image cache */
  515.         #define LV_FREETYPE_SBIT_CACHE 0
  516.         /* Maximum number of opened FT_Face/FT_Size objects managed by this cache instance. */
  517.         /* (0:use system defaults) */
  518.         #define LV_FREETYPE_CACHE_FT_FACES 0
  519.         #define LV_FREETYPE_CACHE_FT_SIZES 0
  520.     #endif
  521. #endif

  522. /*Rlottie library*/
  523. #define LV_USE_RLOTTIE 0

  524. /*FFmpeg library for image decoding and playing videos
  525. *Supports all major image formats so do not enable other image decoder with it*/
  526. #define LV_USE_FFMPEG 0
  527. #if LV_USE_FFMPEG
  528.     /*Dump input information to stderr*/
  529.     #define LV_FFMPEG_DUMP_FORMAT 0
  530. #endif

  531. /*-----------
  532. * Others
  533. *----------*/

  534. /*1: Enable API to take snapshot for object*/
  535. #define LV_USE_SNAPSHOT 1

  536. /*1: Enable Monkey test*/
  537. #define LV_USE_MONKEY 0

  538. /*1: Enable grid navigation*/
  539. #define LV_USE_GRIDNAV 1

  540. /*1: Enable lv_obj fragment*/
  541. #define LV_USE_FRAGMENT 1

  542. /*1: Support using images as font in label or span widgets */
  543. #define LV_USE_IMGFONT 1

  544. /*1: Enable a published subscriber based messaging system */
  545. #define LV_USE_MSG 1

  546. /*1: Enable Pinyin input method*/
  547. /*Requires: lv_keyboard*/
  548. #define LV_USE_IME_PINYIN 1
  549. #if LV_USE_IME_PINYIN
  550.     /*1: Use default thesaurus*/
  551.     /*If you do not use the default thesaurus, be sure to use `lv_ime_pinyin` after setting the thesauruss*/
  552.     #define LV_IME_PINYIN_USE_DEFAULT_DICT 1
  553.     /*Set the maximum number of candidate panels that can be displayed*/
  554.     /*This needs to be adjusted according to the size of the screen*/
  555.     #define LV_IME_PINYIN_CAND_TEXT_NUM 6

  556.     /*Use 9 key input(k9)*/
  557.     #define LV_IME_PINYIN_USE_K9_MODE      0
  558.     #if LV_IME_PINYIN_USE_K9_MODE == 1
  559.         #define LV_IME_PINYIN_K9_CAND_TEXT_NUM 3
  560.     #endif // LV_IME_PINYIN_USE_K9_MODE
  561. #endif

  562. /*==================
  563. * EXAMPLES
  564. *==================*/

  565. /*Enable the examples to be built with the library*/
  566. #define LV_BUILD_EXAMPLES 0

  567. /*===================
  568. * DEMO USAGE
  569. ====================*/

  570. /*Show some widget. It might be required to increase `LV_MEM_SIZE` */
  571. #define LV_USE_DEMO_WIDGETS 0
  572. #if LV_USE_DEMO_WIDGETS
  573. #define LV_DEMO_WIDGETS_SLIDESHOW 0
  574. #endif

  575. /*Demonstrate the usage of encoder and keyboard*/
  576. #define LV_USE_DEMO_KEYPAD_AND_ENCODER 0

  577. /*Benchmark your system*/
  578. #define LV_USE_DEMO_BENCHMARK 0
  579. #if LV_USE_DEMO_BENCHMARK
  580. /*Use RGB565A8 images with 16 bit color depth instead of ARGB8565*/
  581. #define LV_DEMO_BENCHMARK_RGB565A8 0
  582. #endif

  583. /*Stress test for LVGL*/
  584. #define LV_USE_DEMO_STRESS 0

  585. /*Music player demo*/
  586. #define LV_USE_DEMO_MUSIC 0
  587. #if LV_USE_DEMO_MUSIC
  588.     #define LV_DEMO_MUSIC_SQUARE    0
  589.     #define LV_DEMO_MUSIC_LANDSCAPE 0
  590.     #define LV_DEMO_MUSIC_ROUND     0
  591.     #define LV_DEMO_MUSIC_LARGE     0
  592.     #define LV_DEMO_MUSIC_AUTO_PLAY 0
  593. #endif

  594. /*--END OF LV_CONF_H--*/

  595. #endif /*LV_CONF_H*/

  596. #endif /*End of "Content enable"*/
复制代码

5. 创建测试模块
grub-core/Makefile.core.def
  1. module = {
  2.   name = lvgltest;
  3.   common = commands/lvgltest.c;
  4.   cflags = '$(CFLAGS_LVGLAPP)';
  5.   cppflags = '$(CPPFLAGS_LVGLAPP)';
  6. };
复制代码

grub-core/commands/lvgltest.c
  1. /*
  2. *  GRUB  --  GRand Unified Bootloader
  3. *  Copyright (C) 2022  A1ive
  4. *
  5. *  GRUB is free software: you can redistribute it and/or modify
  6. *  it under the terms of the GNU General Public License as published by
  7. *  the Free Software Foundation, either version 3 of the License, or
  8. *  (at your option) any later version.
  9. *
  10. *  GRUB is distributed in the hope that it will be useful,
  11. *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. *  GNU General Public License for more details.
  14. *
  15. *  You should have received a copy of the GNU General Public License
  16. *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
  17. */

  18. #include <grub/types.h>
  19. #include <grub/misc.h>
  20. #include <grub/mm.h>
  21. #include <grub/err.h>
  22. #include <grub/dl.h>
  23. #include <grub/extcmd.h>
  24. #include <grub/i18n.h>

  25. #include <lvgl.h>

  26. GRUB_MOD_LICENSE ("GPLv3+");

  27. static grub_err_t
  28. grub_cmd_lvgl (grub_extcmd_context_t ctxt __attribute__ ((unused)),
  29.                int argc __attribute__ ((unused)),
  30.                char **args __attribute__ ((unused)))
  31. {
  32.   lv_init ();
  33.   grub_printf ("lv_init OK.\n");
  34.   return 0;
  35. }

  36. static grub_extcmd_t cmd;

  37. GRUB_MOD_INIT(lvgltest)
  38. {
  39.   cmd = grub_register_extcmd ("lvgltest", grub_cmd_lvgl, 0, 0,
  40.                               N_("LVGL test."), 0);
  41. }

  42. GRUB_MOD_FINI(lvgltest)
  43. {
  44.   grub_unregister_extcmd (cmd);
  45. }
复制代码
回复

使用道具 举报

4#
 楼主| 发表于 2022-9-21 14:03:10 | 只看该作者
本帖最后由 wintoflash 于 2022-9-22 12:01 编辑

6. 添加显示界面
文档:https://docs.lvgl.io/master/porting/display.html
目前仅用于测试 LVGL 是否正常工作,暂不考虑效率,因此使用 Full refresh (One buffer) 模式。
测试中文显示和拼音输入法:

创建 grub-core/lvgl/port/lv_port_disp.c:
  1. /*
  2. *  GRUB  --  GRand Unified Bootloader
  3. *  Copyright (C) 2022  A1ive
  4. *
  5. *  GRUB is free software: you can redistribute it and/or modify
  6. *  it under the terms of the GNU General Public License as published by
  7. *  the Free Software Foundation, either version 3 of the License, or
  8. *  (at your option) any later version.
  9. *
  10. *  GRUB is distributed in the hope that it will be useful,
  11. *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. *  GNU General Public License for more details.
  14. *
  15. *  You should have received a copy of the GNU General Public License
  16. *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
  17. */

  18. #include <grub/misc.h>
  19. #include <grub/mm.h>
  20. #include <grub/term.h>
  21. #include <grub/video.h>
  22. #include <grub/bitmap.h>

  23. #include "../lvgl.h"
  24. #include "lv_port_disp.h"

  25. static lv_disp_drv_t grub_lvgl_disp_drv;
  26. static lv_disp_draw_buf_t grub_lvgl_draw_buf;
  27. static lv_color_t *grub_lvgl_fb;
  28. static uint32_t grub_lvgl_fb_size;
  29. static struct grub_video_bitmap grub_lvgl_bmp =
  30. {
  31.   .mode_info =
  32.   {
  33.     .mode_type = GRUB_VIDEO_MODE_TYPE_RGB | GRUB_VIDEO_MODE_TYPE_ALPHA,
  34.     .blit_format = GRUB_VIDEO_BLIT_FORMAT_BGRA_8888,
  35.     .bpp = 32,
  36.     .bytes_per_pixel = 4,
  37.     .number_of_colors = 256,
  38.     .blue_mask_size = 8,
  39.     .blue_field_pos = 0,
  40.     .green_mask_size = 8,
  41.     .green_field_pos = 8,
  42.     .red_mask_size = 8,
  43.     .red_field_pos = 16,
  44.     .reserved_mask_size = 8,
  45.     .reserved_field_pos = 24,
  46.   },
  47. };

  48. static void
  49. grub_lvgl_flush_cb (lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
  50. {
  51.   unsigned int width, height;
  52.   width = area->x2 - area->x1 + 1;
  53.   height = area->y2 - area->y1 + 1;

  54.   grub_lvgl_bmp.mode_info.width = width;
  55.   grub_lvgl_bmp.mode_info.height = height;
  56.   grub_lvgl_bmp.mode_info.pitch = width * 4;
  57.   grub_lvgl_bmp.data = &color_p->ch;

  58.   grub_video_blit_bitmap(&grub_lvgl_bmp, GRUB_VIDEO_BLIT_BLEND,
  59.                          area->x1, area->y1, 0, 0, width, height);

  60.   grub_refresh();
  61.   lv_disp_flush_ready(disp_drv);
  62. }


  63. grub_err_t
  64. lv_port_disp_init(void)
  65. {
  66.   struct grub_video_mode_info info;
  67.   if (grub_video_get_info(&info) != GRUB_ERR_NONE)
  68.     return grub_errno;
  69.   grub_printf("%ux%ux%u, format=%d\n",
  70.               info.width, info.height, info.bpp, info.blit_format);
  71.   grub_lvgl_fb_size = info.height * info.width;
  72.   grub_lvgl_fb = grub_calloc(sizeof(lv_color_t), grub_lvgl_fb_size);
  73.   if (!grub_lvgl_fb)
  74.     return grub_error(GRUB_ERR_OUT_OF_MEMORY, "out of memory");
  75.   lv_disp_draw_buf_init(&grub_lvgl_draw_buf, grub_lvgl_fb, NULL, grub_lvgl_fb_size);

  76.   lv_disp_drv_init(&grub_lvgl_disp_drv);
  77.   grub_lvgl_disp_drv.hor_res = info.width;
  78.   grub_lvgl_disp_drv.ver_res = info.height;
  79.   grub_lvgl_disp_drv.draw_buf = &grub_lvgl_draw_buf;
  80.   grub_lvgl_disp_drv.full_refresh = 1;
  81.   grub_lvgl_disp_drv.flush_cb = grub_lvgl_flush_cb;
  82.   lv_disp_drv_register(&grub_lvgl_disp_drv);

  83.   return GRUB_ERR_NONE;
  84. }
复制代码

创建 grub-core/lvgl/port/lv_port_disp.h:
  1. #ifndef LV_PORT_DISP_H
  2. #define LV_PORT_DISP_H
  3. #include <grub/err.h>
  4. grub_err_t lv_port_disp_init(void);
  5. #endif /*LV_PORT_DISP_H*/
复制代码

在 lv_conf.h 中,我们已经将 LV_COLOR_DEPTH 设置为 32,那么 lv_color_t 就是 BGRA8888 格式的 (和 BMP 一样)。
由于 grub_video_bitmap_create 不支持创建 BGRA8888 格式图片,因此只能自己写一个 grub_video_bitmap 的结构体,手动指定各颜色的位置。
在 grub-core/Makefile.core.def 的 lvgl 一节中加入
  1. common = lvgl/port/lv_port_disp.c;
复制代码

编辑 grub-core/commands/lvgltest.c,添加如下测试内容:
  1. #include <grub/types.h>
  2. #include <grub/misc.h>
  3. #include <grub/mm.h>
  4. #include <grub/err.h>
  5. #include <grub/dl.h>
  6. #include <grub/extcmd.h>
  7. #include <grub/i18n.h>
  8. #include <grub/term.h>

  9. #include <lvgl.h>
  10. #include <port/lv_port_disp.h>

  11. GRUB_MOD_LICENSE ("GPLv3+");

  12. static void ta_event_cb(lv_event_t * e)
  13. {
  14.   lv_event_code_t code = lv_event_get_code(e);
  15.   lv_obj_t * ta = lv_event_get_target(e);
  16.   lv_obj_t * kb = lv_event_get_user_data(e);

  17.   if(code == LV_EVENT_FOCUSED)
  18.   {
  19.     if(lv_indev_get_type(lv_indev_get_act()) != LV_INDEV_TYPE_KEYPAD)
  20.     {
  21.       lv_keyboard_set_textarea(kb, ta);
  22.       lv_obj_clear_flag(kb, LV_OBJ_FLAG_HIDDEN);
  23.     }
  24.   }
  25.   else if(code == LV_EVENT_CANCEL)
  26.   {
  27.     lv_obj_add_flag(kb, LV_OBJ_FLAG_HIDDEN);
  28.     lv_obj_clear_state(ta, LV_STATE_FOCUSED);
  29.     lv_indev_reset(NULL, ta);   /*To forget the last clicked object to make it focusable again*/
  30.   }
  31. }

  32. static grub_err_t
  33. grub_cmd_lvgl (grub_extcmd_context_t ctxt __attribute__ ((unused)),
  34.                int argc __attribute__ ((unused)),
  35.                char **args __attribute__ ((unused)))
  36. {
  37.   lv_init ();
  38.   grub_printf ("lv_init OK.\n");
  39.   grub_refresh();
  40.   if (lv_port_disp_init() != GRUB_ERR_NONE)
  41.   {
  42.     grub_printf("lv_port_disp_init error %d\n", grub_errno);
  43.     return grub_errno;
  44.   }
  45.   grub_printf("lv_port_disp_init OK.\n");
  46.   grub_refresh();

  47.   lv_obj_t * pinyin_ime = lv_ime_pinyin_create(lv_scr_act());
  48.   lv_obj_set_style_text_font(pinyin_ime, &lv_font_simsun_16_cjk, 0);

  49.   /* ta1 */
  50.   lv_obj_t * ta1 = lv_textarea_create(lv_scr_act());
  51.   lv_textarea_set_one_line(ta1, true);
  52.   lv_obj_set_style_text_font(ta1, &lv_font_simsun_16_cjk, 0);
  53.   lv_obj_align(ta1, LV_ALIGN_TOP_LEFT, 0, 0);

  54.   /*Create a keyboard and add it to ime_pinyin*/
  55.   lv_obj_t * kb = lv_keyboard_create(lv_scr_act());
  56.   lv_ime_pinyin_set_keyboard(pinyin_ime, kb);
  57.   lv_keyboard_set_textarea(kb, ta1);

  58.   lv_obj_add_event_cb(ta1, ta_event_cb, LV_EVENT_ALL, kb);

  59.   /*Get the cand_panel, and adjust its size and position*/
  60.   lv_obj_t * cand_panel = lv_ime_pinyin_get_cand_panel(pinyin_ime);
  61.   lv_obj_set_size(cand_panel, LV_PCT(100), LV_PCT(10));
  62.   lv_obj_align_to(cand_panel, kb, LV_ALIGN_OUT_TOP_MID, 0, 0);

  63.   /*Try using ime_pinyin to output the Chinese below in the ta1 above*/
  64.   lv_obj_t * cz_label = lv_label_create(lv_scr_act());
  65.   lv_label_set_text(cz_label,
  66.                     "嵌入式系统(Embedded System),\n"
  67.                     "是一种嵌入机械或电气系统内部、具有专一功能和实时计算性能的计算机系统。");
  68.   lv_obj_set_style_text_font(cz_label, &lv_font_simsun_16_cjk, 0);
  69.   lv_obj_set_width(cz_label, 310);
  70.   lv_obj_align_to(cz_label, ta1, LV_ALIGN_OUT_BOTTOM_LEFT, 0, 0);

  71.   while (1)
  72.   {
  73.     lv_tick_inc(5);
  74.     lv_task_handler();
  75.   }

  76.   return 0;
  77. }
复制代码

编译并在虚拟机中运行测试,即可看到图片所示内容。
回复

使用道具 举报

5#
 楼主| 发表于 2022-9-22 11:52:32 | 只看该作者
本帖最后由 wintoflash 于 2022-9-22 21:53 编辑

7. 添加输入设备支持 (键盘)
文档:https://docs.lvgl.io/master/porting/indev.html

暂时仅添加键盘驱动。使用 grub_getkey_no_block() 从 GRUB2 终端获取按键。
根据 lvgl/src/core/lv_group.h,下列按键需要特殊处理:
  1. enum {
  2.     LV_KEY_UP        = 17,  /*0x11*/
  3.     LV_KEY_DOWN      = 18,  /*0x12*/
  4.     LV_KEY_RIGHT     = 19,  /*0x13*/
  5.     LV_KEY_LEFT      = 20,  /*0x14*/
  6.     LV_KEY_ESC       = 27,  /*0x1B*/
  7.     LV_KEY_DEL       = 127, /*0x7F*/
  8.     LV_KEY_BACKSPACE = 8,   /*0x08*/
  9.     LV_KEY_ENTER     = 10,  /*0x0A, '\n'*/
  10.     LV_KEY_NEXT      = 9,   /*0x09, '\t'*/
  11.     LV_KEY_PREV      = 11,  /*0x0B, '*/
  12.     LV_KEY_HOME      = 2,   /*0x02, STX*/
  13.     LV_KEY_END       = 3,   /*0x03, ETX*/
  14. };
复制代码

添加 grub-core/lvgl/port/lv_port_indev.c:
  1. /*
  2. *  GRUB  --  GRand Unified Bootloader
  3. *  Copyright (C) 2022  A1ive
  4. *
  5. *  GRUB is free software: you can redistribute it and/or modify
  6. *  it under the terms of the GNU General Public License as published by
  7. *  the Free Software Foundation, either version 3 of the License, or
  8. *  (at your option) any later version.
  9. *
  10. *  GRUB is distributed in the hope that it will be useful,
  11. *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. *  GNU General Public License for more details.
  14. *
  15. *  You should have received a copy of the GNU General Public License
  16. *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
  17. */

  18. #include <grub/misc.h>
  19. #include <grub/mm.h>
  20. #include <grub/term.h>

  21. #include "../lvgl.h"
  22. #include "lv_port_indev.h"

  23. static lv_indev_drv_t grub_lvgl_indev_drv;
  24. lv_indev_t *grub_lvgl_indev_kbd;

  25. static void
  26. grub_lvgl_kbd_read_cb (lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
  27. {
  28.   (void) indev_drv;
  29.   static uint32_t last_key = 0, act_key = 0;
  30.   /*Get whether the a key is pressed and save the pressed key*/
  31.   int key = grub_getkey_noblock();
  32.   if(key != GRUB_TERM_NO_KEY)
  33.   {
  34.     data->state = LV_INDEV_STATE_PR;
  35.     switch(key)
  36.     {
  37.       case GRUB_TERM_KEY_UP:
  38.       case GRUB_TERM_CTRL | 'p':
  39.         act_key = LV_KEY_UP;
  40.         break;
  41.       case GRUB_TERM_KEY_DOWN:
  42.       case GRUB_TERM_CTRL | 'n':
  43.         act_key = LV_KEY_DOWN;
  44.         break;
  45.       case GRUB_TERM_KEY_RIGHT:
  46.       case GRUB_TERM_CTRL | 'f':
  47.         act_key = LV_KEY_RIGHT;
  48.         break;
  49.       case GRUB_TERM_KEY_LEFT:
  50.       case GRUB_TERM_CTRL | 'b':
  51.         act_key = LV_KEY_LEFT;
  52.         break;
  53.       case GRUB_TERM_ESC:
  54.         act_key = LV_KEY_ESC;
  55.         break;
  56.       case GRUB_TERM_KEY_DC:
  57.       case GRUB_TERM_CTRL | 'd':
  58.         act_key = LV_KEY_DEL;
  59.         break;
  60.       case GRUB_TERM_BACKSPACE:
  61.       case GRUB_TERM_CTRL | 'h':
  62.         act_key = LV_KEY_BACKSPACE;
  63.         break;
  64.       case '\n':
  65.       case '\r':
  66.         act_key = LV_KEY_ENTER;
  67.         break;
  68.       case '\t':
  69.       case GRUB_TERM_KEY_NPAGE:
  70.       case GRUB_TERM_CTRL | 'i':
  71.         act_key = LV_KEY_NEXT;
  72.         break;
  73.       case '\v':
  74.       case GRUB_TERM_KEY_PPAGE:
  75.       case GRUB_TERM_CTRL | 'k':
  76.         act_key = LV_KEY_PREV;
  77.         break;
  78.       case GRUB_TERM_KEY_HOME:
  79.       case GRUB_TERM_CTRL | 'a':
  80.         act_key = LV_KEY_HOME;
  81.         break;
  82.       case GRUB_TERM_KEY_END:
  83.       case GRUB_TERM_CTRL | 'e':
  84.         act_key = LV_KEY_END;
  85.         break;
  86.       default:
  87.         act_key = (uint32_t) key;
  88.     }
  89.     last_key = act_key;
  90.   }
  91.   else
  92.   {
  93.     data->state = LV_INDEV_STATE_REL;
  94.   }

  95.   data->key = last_key;
  96. }

  97. void lv_port_indev_init(void)
  98. {
  99.     /*Register a keypad input device*/
  100.     lv_indev_drv_init(&grub_lvgl_indev_drv);
  101.     grub_lvgl_indev_drv.type = LV_INDEV_TYPE_KEYPAD;
  102.     grub_lvgl_indev_drv.read_cb = grub_lvgl_kbd_read_cb;
  103.     grub_lvgl_indev_kbd = lv_indev_drv_register(&grub_lvgl_indev_drv);
  104. }
复制代码

grub-core/lvgl/port/lv_port_indev.h
  1. #ifndef LV_PORT_INDEV_H
  2. #define LV_PORT_INDEV_H
  3. #include "../lvgl.h"
  4. extern lv_indev_t *grub_lvgl_indev_kbd;
  5. void lv_port_indev_init(void);
  6. #endif /*LV_PORT_INDEV_H*/
复制代码

在 grub-core/Makefile.core.def 的 lvgl 一节中加入
  1. common = lvgl/port/lv_port_indev.c;
复制代码

编辑 grub-core/commands/lvgltest.c,加入输入设备相关代码:
  1. ...
  2. #include <grub/time.h>
  3. #include <port/lv_port_indev.h>
  4. ...
  5.   grub_printf("lv_port_disp_init OK.\n");
  6.   grub_refresh();
  7.   lv_port_indev_init();
  8.   grub_printf("lv_port_indev_init OK.\n");
  9.   grub_refresh();

  10.   lv_group_t *g = lv_group_create();
  11.   lv_group_set_default(g);
  12.   lv_indev_set_group(grub_lvgl_indev_kbd, g);
  13. ...
  14.   while (1)
  15.   {
  16.     lv_tick_inc(5);
  17.     lv_task_handler();
  18.     grub_millisleep(5);
  19.   }
复制代码
回复

使用道具 举报

6#
 楼主| 发表于 2022-9-22 21:44:29 | 只看该作者
本帖最后由 wintoflash 于 2022-10-1 09:57 编辑

9. 接入 GRUB2 pf2 字体支持
GRUB2 采用的是自定义的 PFF2 点阵字体格式 (https://www.gnu.org/software/gru ... F2-Font-File-Format)
它提供了 grub-mkfont 工具,调用 freetype 以实现 ttf->pf2 字体格式的转换。
在 GRUB2 加载字体后,每个字形 (glyph) 都会被转化成以下格式的结构体:

  1. struct grub_font_glyph
  2. {
  3.   grub_font_t font;
  4.   /* 字形宽度 (不包含 Horizonal leading,也就是两个字符之间的空隙) */
  5.   grub_uint16_t width;

  6.   /* 字形高度  */
  7.   grub_uint16_t height;

  8.   /* 位图 x 偏移  */
  9.   grub_int16_t offset_x;

  10.   /* 位图 y 偏移  */
  11.   grub_int16_t offset_y;

  12.   /* Horizonal leading 的有效值  */
  13.   grub_uint16_t device_width;

  14.   /* 字形的位图,每个比特对应一个像素 (bpp=1)  */
  15.   grub_uint8_t bitmap[0];
  16. };
复制代码

所有的字形,组成了字体 (font)。
  1. struct grub_font
  2. {
  3.   char *name;
  4.   grub_file_t file;
  5.   char *family;
  6.   short point_size;
  7.   short weight;
  8.   /* 最大宽度 */
  9.   short max_char_width;
  10.   /* 最大高度 */
  11.   short max_char_height;
  12.   /* 基线 (base line) 之上的空间 */
  13.   short ascent;
  14. /* 基线 (base line) 之下的空间 */
  15.   short descent;
  16.   short leading;
  17.   grub_uint32_t num_chars;
  18.   struct char_index_entry *char_index;
  19.   grub_uint16_t *bmp_idx;
  20. };
复制代码


在 lvgl 中,定义字形的结构体为
  1. typedef struct {
  2.     const struct _lv_font_t *resolved_font; /* 回退 (fallback) 字体 */
  3.     uint16_t adv_w; /* 对应 grub2 中的 device_width */
  4.     uint16_t box_w; /* 对应 grub2 中的 width */
  5.     uint16_t box_h; /* 对应 grub2 中的 height */
  6.     int16_t ofs_x;  /* 对应 grub2 中的 offset_x */
  7.     int16_t ofs_y;  /* 对应 grub2 中的 offset_y */
  8.     uint8_t bpp: 4;  /* 每像素占据的位宽,对于 grub2,bpp=1 */
  9.     uint8_t is_placeholder: 1; /* 是否为占位符 (字体缺少对应字形时显示的占位符) */
  10. } lv_font_glyph_dsc_t;
复制代码

lvgl 字体的定义为
  1. typedef struct _lv_font_t {
  2.     /* 回调函数,用来获取字形的信息 (宽/高等) */
  3.     bool (*get_glyph_dsc)(const struct _lv_font_t *, lv_font_glyph_dsc_t *, uint32_t letter, uint32_t letter_next);
  4.     /* 回调函数,用来获取字形的位图 */
  5.     const uint8_t * (*get_glyph_bitmap)(const struct _lv_font_t *, uint32_t);
  6.     /* 任意文本能满足的实际行高度 */
  7.     /* 应该对应 grub2 的 max_char_height */
  8.     lv_coord_t line_height;
  9.     /* 基线,似乎 lvgl 是依据字体高度减去这个值来计算的 */
  10.     /* 应该对应 grub2 的 descent ? */
  11.     lv_coord_t base_line;
  12.     /* 值为 LV_FONT_SUBPX_NONE */
  13.     uint8_t subpx  : 2;
  14.     /* Distance between the top of the underline and base line (< 0 means below the base line) */
  15.     /* 应该为 descent 的负值 ?*/
  16.     int8_t underline_position;
  17.     /* Thickness of the underline */
  18.     /* 不知道 */
  19.     int8_t underline_thickness;
  20.     /* 存储对应的 grub_font_t */
  21.     const void * dsc;
  22.     const struct _lv_font_t * fallback;
  23. } lv_font_t;
复制代码

创建 grub-core/lvgl/port/lv_port_font.c 和 grub-core/lvgl/port/lv_port_font.h。
用来从 grub2 pf2 字体取得字形信息的回调函数:
  1. static bool
  2. grub_lvgl_get_glyph_dsc(const lv_font_t *font,
  3.                         lv_font_glyph_dsc_t *dsc_out,
  4.                         uint32_t letter, uint32_t letter_next)
  5. {
  6.   (void) letter_next;
  7.   grub_font_t pf2_font = font->dsc;
  8.   struct grub_font_glyph *glyph;

  9.   glyph = grub_font_get_glyph_with_fallback(pf2_font, letter);

  10.   dsc_out->adv_w = glyph->device_width;
  11.   dsc_out->box_h = glyph->height;
  12.   dsc_out->box_w = glyph->width;
  13.   dsc_out->ofs_x = glyph->offset_x;
  14.   dsc_out->ofs_y = glyph->offset_y;
  15.   dsc_out->bpp = 1;

  16.   return true;
  17. }
复制代码

如果字体为斜体 (Italic),且为字符串最后一个字符,adv_w 应该特殊处理。但是正常人在 grub2 下不会用斜体,因此暂不考虑。
grub2 也不支持阿拉伯文等的连字,因此暂时不用考虑下一个字符的不同导致本字符字形的变化。
如果考虑连字和从右向左书写的文字 (如希伯来文/阿拉伯文),似乎应该使用 grub_font_construct_glyph 函数。
从 grub2 获取字形位图的回调函数:
  1. static const uint8_t *
  2. grub_lvgl_get_glyph_bitmap(const lv_font_t *font, uint32_t unicode_letter)
  3. {
  4.   grub_font_t pf2_font = font->dsc;
  5.   struct grub_font_glyph *glyph;

  6.   glyph = grub_font_get_glyph_with_fallback(pf2_font, unicode_letter);
  7.   return glyph->bitmap;
  8. }
复制代码

将 grub2 字体转成 lvgl 字体的函数:
  1. void lv_port_font_get(lv_font_t *font, const char *name)
  2. {
  3.   grub_font_t pf2_font = grub_font_get(name);
  4.   font->get_glyph_dsc = grub_lvgl_get_glyph_dsc;
  5.   font->get_glyph_bitmap = grub_lvgl_get_glyph_bitmap;
  6.   font->line_height = grub_font_get_max_char_height(pf2_font);
  7.   font->base_line = grub_font_get_descent(pf2_font);
  8.   font->subpx = LV_FONT_SUBPX_NONE;
  9.   font->underline_position = -grub_font_get_descent(pf2_font); // 似乎有问题,将来再改
  10.   font->dsc = pf2_font;
  11. }
复制代码

在 lvgltest 中进行测试:
  1. static lv_font_t lv_font_unifont;
  2. lv_port_font_get(&lv_font_unifont, "Unifont");
复制代码

将 lv_font_simsun_16_cjk 替换为 lv_font_unifont。

可以正常显示 grub2 的字体了。但是字符高度好像有问题 (调整 underline_position ?)。
另外要处理不可打印字符 (CR, LF等)。
回复

使用道具 举报

7#
 楼主| 发表于 2022-10-1 09:07:32 | 只看该作者
---未完成---
10. 用lvgl实现grub2 boot_menu 和 terminal_box 组件
回复

使用道具 举报

8#
 楼主| 发表于 2022-10-1 09:08:47 | 只看该作者
---未完成---
11. lvgl 接管 grub2 gfxmenu
12. 实现鼠标支持
回复

使用道具 举报

9#
 楼主| 发表于 2022-10-1 09:50:20 | 只看该作者
---占楼结束---
回复

使用道具 举报

10#
发表于 2022-10-1 17:58:48 | 只看该作者
不明觉厉
回复

使用道具 举报

11#
发表于 2024-5-22 23:49:49 | 只看该作者
确实厉害,到哪一步了?
回复

使用道具 举报

12#
发表于 2024-6-23 13:24:33 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

13#
发表于 2024-6-23 13:24:50 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

14#
发表于 2024-6-23 15:02:42 | 只看该作者
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|Archiver|捐助支持|无忧启动 ( 闽ICP备05002490号-1 )

闽公网安备 35020302032614号

GMT+8, 2024-11-25 15:03

Powered by Discuz! X3.3

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表